diff --git a/crates/spar-sysml2/tests/conformance_tests.rs b/crates/spar-sysml2/tests/conformance_tests.rs index f7de784b..1e07b3f4 100644 --- a/crates/spar-sysml2/tests/conformance_tests.rs +++ b/crates/spar-sysml2/tests/conformance_tests.rs @@ -1,84 +1,152 @@ -//! SysML v2 parser conformance tests using official examples. +//! Named official SysML v2 files, each with the verdict it actually gets. //! -//! Files from Systems-Modeling/SysML-v2-Release repository. +//! ## What this file used to be +//! +//! Eight tests that could not fail. Seven asserted on the CST's *text* — +//! `!result.syntax_node().text().is_empty()`, `text().contains("port")`, +//! `text().len() > 50000` — and the CST is lossless, so it echoes the input +//! back whether or not a single token parsed. Not one of the eight called +//! `errors()` or `ok()`. `parse_annex_a_simple_vehicle` reported `ok` while the +//! SysML v2 specification's own Annex A model failed on line 3. +//! +//! `REQ-GUARD-GATE-EVIDENCE-002` names that shape exactly: an operation that +//! can produce "nothing happened" must render differently from "it worked". +//! Four releases applied it to the CI guardrails; none of it had been pointed +//! here. +//! +//! ## Verdicts are DECLARED, not discovered +//! +//! The obvious repair — assert whatever the parser currently does — would have +//! been just as inert: it would have recorded "these seven files fail" as the +//! desired state and stayed green forever. So each file carries an EXPECTED +//! verdict and the reason for it, the same discipline +//! `first_party_legality.rs` uses on the AADL side. Today every expectation is +//! `Fails`, and each names the construct responsible. When +//! `REQ-SYSML2-VISIBILITY-001` closes those gaps, these tests go red and say +//! which file changed — a fix cannot land silently. +//! +//! The bulk gate lives in `official_corpus.rs`, over 310 vendored files. This +//! file is the *named* companion: the corpus gate moves a number, this one +//! moves an identifiable model. use spar_sysml2::parse; -fn parse_file(name: &str) -> spar_sysml2::Parse { - let manifest = env!("CARGO_MANIFEST_DIR"); - let root = manifest - .replace("crates/spar-sysml2", "") - .replace("/crates/spar-sysml2", ""); - let path = format!("{}/test-data/sysml2/{}", root.trim_end_matches('/'), name); - let source = - std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read {}: {}", path, e)); - parse(&source) -} - -#[test] -fn parse_package_example() { - let result = parse_file("Package_Example.sysml"); - assert!(!result.syntax_node().text().is_empty()); +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Expect { + /// Parses clean today. + /// + /// Currently unconstructed, and `-D warnings` would otherwise reject the + /// crate for it — allowed rather than deleted because this is the variant + /// every entry below is headed for. Removing it would mean the first person + /// to fix a grammar gap has to re-invent the vocabulary before they can + /// record the win. + #[allow(dead_code)] + Parses, + /// Fails today, for the stated reason. Not an aspiration — a record. + Fails(&'static str), } +use Expect::*; -#[test] -fn parse_part_definition_example() { - let result = parse_file("Part_Definition_Example.sysml"); - let text = result.syntax_node().text().to_string(); - assert!(text.contains("part def Vehicle")); -} +/// The named files, their expected verdict, and why. +/// +/// Measured 2026-08-26 against `f395518`. Five of the seven fail on the very +/// first construct in the file — a quoted package name at 1:9 — which is why +/// the corpus-wide count is 1 of 310 rather than something gentler. +const CASES: &[(&str, Expect)] = &[ + ( + "Package_Example.sysml", + Fails("1:9 quoted name — `package 'Package Example' {`"), + ), + ("Part_Definition_Example.sysml", Fails("1:9 quoted name")), + ("Parts_Example.sysml", Fails("1:9 quoted name")), + ("Connections_Example.sysml", Fails("1:9 quoted name")), + ("Port_Example.sysml", Fails("1:9 quoted name")), + ( + "VehicleUsages.sysml", + Fails("7:2 visibility modifier on a member"), + ), + ( + "SysML_v2_Spec_Annex_A_SimpleVehicleModel.sysml", + Fails("3:5 `public import Definitions::*;` — visibility on import"), + ), +]; -#[test] -fn parse_parts_example() { - let result = parse_file("Parts_Example.sysml"); - assert!(!result.syntax_node().text().is_empty()); +fn repo_root() -> String { + let manifest = env!("CARGO_MANIFEST_DIR"); + manifest + .replace("crates/spar-sysml2", "") + .replace("/crates/spar-sysml2", "") + .trim_end_matches('/') + .to_string() } -#[test] -fn parse_connections_example() { - let result = parse_file("Connections_Example.sysml"); - assert!(!result.syntax_node().text().is_empty()); +fn read(name: &str) -> String { + let path = format!("{}/test-data/sysml2/{}", repo_root(), name); + std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("cannot read {path}: {e}")) } #[test] -fn parse_port_example() { - let result = parse_file("Port_Example.sysml"); - let text = result.syntax_node().text().to_string(); - assert!(text.contains("port")); +fn every_named_file_gets_the_verdict_it_claims() { + let mut wrong = Vec::new(); + for (name, expect) in CASES { + let parsed = parse(&read(name)); + let got_ok = parsed.ok(); + let want_ok = matches!(expect, Parses); + if got_ok != want_ok { + let detail = match expect { + Parses => "expected it to PARSE, and it does not".to_string(), + Fails(why) => format!( + "expected it to FAIL ({why}) — it now PARSES. That is a fix: \ + change this entry to Parses and raise OFFICIAL_PARSING in \ + official_corpus.rs, which will also have moved." + ), + }; + wrong.push(format!(" {name}: {detail}")); + } + } + assert!( + wrong.is_empty(), + "{} named file(s) changed verdict:\n{}", + wrong.len(), + wrong.join("\n") + ); } +/// Discrimination guard. If `parse().ok()` were stuck on one answer the test +/// above would still pass whenever the declared set happened to agree with it. +/// Both verdicts must be reachable for the declarations to carry information. #[test] -fn parse_vehicle_usages() { - let result = parse_file("VehicleUsages.sysml"); - let text = result.syntax_node().text().to_string(); - assert!(text.contains("Vehicle")); +fn the_verdict_function_can_return_both_answers() { + assert!(parse("package P { part def A; }").ok()); + assert!(!parse("package P { part def").ok()); } +/// A file that fails to parse must still say WHY. A parser that rejects input +/// while emitting an empty diagnostic list is unusable as an oracle — the CLI +/// would exit non-zero with nothing printed, and a user could not act on it. #[test] -fn parse_annex_a_simple_vehicle() { - let result = parse_file("SysML_v2_Spec_Annex_A_SimpleVehicleModel.sysml"); - assert!(u32::from(result.syntax_node().text().len()) > 50000); +fn a_rejected_file_carries_at_least_one_diagnostic() { + for (name, expect) in CASES { + let Fails(_) = expect else { continue }; + let parsed = parse(&read(name)); + assert!( + !parsed.errors().is_empty(), + "{name} is rejected but produced no diagnostic — a refusal a user \ + cannot act on is no better than a silent acceptance" + ); + } } +/// The one assertion in the original suite that was real, kept verbatim in +/// intent: a lossless CST must reproduce its input byte for byte. This holds +/// whether or not the parse succeeded, which is exactly the property a lossless +/// syntax tree is for — and it is why the *other* seven tests could pass on +/// files that never parsed. #[test] -fn lossless_roundtrip_all_files() { - for file in &[ - "Package_Example.sysml", - "Part_Definition_Example.sysml", - "Parts_Example.sysml", - "Connections_Example.sysml", - "Port_Example.sysml", - "VehicleUsages.sysml", - "SysML_v2_Spec_Annex_A_SimpleVehicleModel.sysml", - ] { - let manifest = env!("CARGO_MANIFEST_DIR"); - let root = manifest - .replace("crates/spar-sysml2", "") - .replace("/crates/spar-sysml2", ""); - let path = format!("{}/test-data/sysml2/{}", root.trim_end_matches('/'), file); - let source = std::fs::read_to_string(&path).unwrap(); - let result = parse(&source); - let roundtrip = result.syntax_node().text().to_string(); - assert_eq!(source, roundtrip, "Lossless roundtrip failed for {}", file); +fn the_cst_is_lossless_even_when_the_parse_fails() { + for (name, _) in CASES { + let source = read(name); + let roundtrip = parse(&source).syntax_node().text().to_string(); + assert_eq!(source, roundtrip, "lossless roundtrip failed for {name}"); } } diff --git a/crates/spar-sysml2/tests/official_corpus.rs b/crates/spar-sysml2/tests/official_corpus.rs new file mode 100644 index 00000000..b6bd69fa --- /dev/null +++ b/crates/spar-sysml2/tests/official_corpus.rs @@ -0,0 +1,187 @@ +//! The SysML v2 parser, graded by somebody else's models. +//! +//! ## Why this file exists +//! +//! Until it did, every SysML v2 number this project quoted was measured against +//! 43 fixtures we wrote ourselves, and `conformance_tests.rs` — the suite whose +//! name promised otherwise — could not fail. Its assertion was +//! `assert!(!result.syntax_node().text().is_empty())`, which checks that the +//! *input source text* is non-empty. That is true by construction. Zero of its +//! eight tests called `errors()`, so `parse_annex_a_simple_vehicle` reported +//! `ok` while the specification's own Annex A model failed to parse. +//! +//! That is the defect class `REQ-GUARD-GATE-EVIDENCE-002` names — an operation +//! that can produce "nothing happened" rendering identically to "it worked". +//! Four releases of that discipline went into the CI guardrails and none of it +//! had ever been pointed at the tool's own interop claim. +//! +//! ## What this gate does and does not claim +//! +//! It claims exactly one thing: **the number of official model files this +//! parser accepts is what the constant says, and it may only rise.** It does +//! not claim the parser is correct — a file that parses may still be lowered +//! wrongly, and `Parse::ok()` is a syntax predicate, not a semantic one. +//! +//! Nor is a parse *rate* a property of the parser alone. It is equally a +//! property of the corpus, which is why `test-data/sysml2/PROVENANCE.md` +//! classifies the failures rather than only counting them: 309 failures across +//! five distinct first-error kinds is a handful of grammar gaps, and reporting +//! it as "0.3%" without that classification would be alarmism. + +use std::path::{Path, PathBuf}; + +const REPO: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../.."); +const CORPUS: &str = "test-data/sysml2/official"; + +/// How many official model files the parser accepts today. +/// +/// EXACT, not a floor — below fails as a regression, above fails until the +/// constant is raised. Same two-sided discipline as `MAX_TOO_PERMISSIVE` in the +/// OSATE agreement gate: a win that is not locked in is slack that quietly +/// leaks back out. +/// +/// Measured 2026-08-26 against the corpus pinned at `29a3d2ac`. The path to +/// moving it is `REQ-SYSML2-VISIBILITY-001` — quoted names and visibility +/// modifiers alone account for 258 of the 309 failures. +const OFFICIAL_PARSING: usize = 1; + +/// Guards against the corpus vanishing. An empty walk parses nothing and +/// nothing fails; the count would read as a catastrophic regression rather than +/// as "the directory is gone", and a `git clean` or a bad merge would look like +/// a parser bug. Checked separately so the two are never confused. +const OFFICIAL_TOTAL: usize = 310; + +/// Walks with `std::fs` rather than a shell glob on purpose: paths in this +/// corpus contain spaces (`kerml/examples/Address Book Example/…`), which +/// word-split under `for f in $(find …)` and silently turn one file into +/// several non-existent ones. That inflated the failure count twice while this +/// baseline was being measured. See PROVENANCE.md. +fn collect(dir: &Path, out: &mut Vec) { + let Ok(entries) = std::fs::read_dir(dir) else { + return; + }; + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + collect(&path, out); + } else if matches!( + path.extension().and_then(|s| s.to_str()), + Some("sysml") | Some("kerml") + ) { + out.push(path); + } + } +} + +fn corpus() -> Vec { + let mut files = Vec::new(); + collect(&PathBuf::from(REPO).join(CORPUS), &mut files); + files.sort(); + files +} + +/// The same predicate the CLI exits non-zero on, so the gate and +/// `spar sysml2 parse` can never disagree about whether a file parsed. +fn parses(path: &Path) -> bool { + // NOT `unwrap_or_default()`. An unreadable file would become an empty + // string, an empty string parses clean, and the file would score as + // PASSING — inflating the ratchet with files nobody read. + let Ok(src) = std::fs::read_to_string(path) else { + panic!("cannot read {}", path.display()); + }; + spar_sysml2::parse(&src).ok() +} + +#[test] +fn the_corpus_is_present() { + let files = corpus(); + assert_eq!( + files.len(), + OFFICIAL_TOTAL, + "expected {OFFICIAL_TOTAL} vendored official model files under {CORPUS}, \ + found {}. A sweep that reads nothing agrees with every expectation, so \ + this is checked before the parse count rather than being allowed to \ + masquerade as a parser regression. If the pin moved, re-vendor with \ + tools/vendor-sysml2-corpus.sh and update both constants together.", + files.len() + ); +} + +#[test] +fn the_official_parse_count_is_exactly_what_we_claim() { + let files = corpus(); + assert_eq!( + files.len(), + OFFICIAL_TOTAL, + "corpus size changed; see the_corpus_is_present" + ); + + let passing: Vec<&PathBuf> = files.iter().filter(|f| parses(f)).collect(); + let n = passing.len(); + + if n > OFFICIAL_PARSING { + panic!( + "{n} official files now parse, above the declared {OFFICIAL_PARSING}. \ + This is a WIN — raise OFFICIAL_PARSING to {n} so it is locked in \ + rather than left as slack that can leak back out." + ); + } + assert_eq!( + n, OFFICIAL_PARSING, + "{n} official files parse, below the declared {OFFICIAL_PARSING}. A file \ + that parsed has stopped parsing — that is a regression in the grammar, \ + not a corpus change (the corpus size is asserted separately)." + ); +} + +/// Non-vacuity. The gate above compares a count to a constant; if `parses()` +/// were stuck on one answer the comparison would still pass whenever the +/// constant happened to match. Both verdicts must be reachable on real input +/// for the count to carry information. +#[test] +fn the_parse_predicate_discriminates() { + assert!( + spar_sysml2::parse("package P { part def A; }").ok(), + "a known-good model must parse — otherwise a count of zero would mean \ + nothing about the corpus" + ); + assert!( + !spar_sysml2::parse("package P { part def").ok(), + "a truncated model must NOT parse — otherwise every file would score as \ + passing and the ratchet would be decorative" + ); +} + +/// The corpus is the point of this file, but a gate over 310 files says nothing +/// about *which* constructs are missing. These pin the four grammar gaps that +/// account for the failures, so closing one shows up as a named test flipping +/// rather than only as a number moving. Each is currently expected to FAIL — +/// when `REQ-SYSML2-VISIBILITY-001` lands, these invert and say so loudly. +#[test] +fn the_known_grammar_gaps_are_the_ones_we_think_they_are() { + let gaps: &[(&str, &str)] = &[ + ("quoted name", "package 'Application Layer' { }"), + ( + "visibility on import", + "package P { private import Objects::*; }", + ), + ("KerML class", "package P { class ShoppingCart; }"), + ( + "abstract type", + "package P { abstract type A specializes Base::Anything; }", + ), + ]; + let unexpectedly_ok: Vec<&str> = gaps + .iter() + .filter(|(_, src)| spar_sysml2::parse(src).ok()) + .map(|(name, _)| *name) + .collect(); + + assert!( + unexpectedly_ok.is_empty(), + "these grammar gaps now PARSE: {unexpectedly_ok:?}. That is progress — \ + remove them from this list and raise OFFICIAL_PARSING, which will have \ + moved. The list exists so a fix is visible as a named construct rather \ + than only as a count." + ); +} diff --git a/test-data/sysml2/PROVENANCE.md b/test-data/sysml2/PROVENANCE.md new file mode 100644 index 00000000..4dfbb255 --- /dev/null +++ b/test-data/sysml2/PROVENANCE.md @@ -0,0 +1,105 @@ +# SysML v2 corpus provenance + +## Source + +- Upstream: [`Systems-Modeling/SysML-v2-Release`](https://github.com/Systems-Modeling/SysML-v2-Release) + — the OMG SysML v2 pilot implementation's release repository. +- Pinned commit: `29a3d2acdd49600cff872e7a55962a40400f3335`. +- Vendored: 2026-08-26, under `official/`. + +## Why it is vendored and not fetched + +`download-official-suite.sh` used to fetch this corpus from `master` at run +time, through the GitHub contents API, with `|| true` on every download and a +hardcoded fallback list when the API call failed. It had never been run: the +three `official/` directories it targets were empty, so **every SysML v2 number +this project has ever quoted was measured against 43 fixtures we wrote +ourselves**. + +Fetching also makes the number unreproducible in two directions at once — the +upstream tip moves (the grammar still ships monthly incremental tags), and a +network failure degrades to a smaller corpus that reads as a better parse rate. +Vendoring at a pin fixes both, and matches what `test-data/interop/` already +does for the 548 OSATE models and the 1347 third-party AADL models. + +## What was taken, and what was not + +Vendored **verbatim, without modification** — 310 model files: + +| path | files | +|---|---| +| `official/sysml/validation/` | 56 | +| `official/sysml/training/` | 100 | +| `official/sysml/examples/` | 96 | +| `official/kerml/examples/` | 58 | + +**Not** vendored: the rest of the 366 MB upstream tree — the Xtext pilot +implementation itself, its Eclipse plugins, jars, Jupyter kernel, `.project` +and IDE state, and the API service sources. None of those are model source, and +none is needed to grade a parser. + +## Licensing + +Upstream is **EPL-2.0**; `official/LICENSE` is the upstream file, copied +unaltered. EPL-2.0 permits redistribution provided the licence travels with the +material and copyright notices are not removed or altered — both hold here, and +the models themselves are byte-identical to upstream. + +This is the same arrangement as the vendored OSATE corpus, which is also +EPL-2.0. It is **not** the same as `Systems-Modeling/SysML-v2-AADL-Release`, +the AADL domain library, which is **CC-BY-ND 4.0** — that one may be vendored +verbatim but never forked or modified, and is not part of this corpus. + +## A trap that has already cost two measurements + +**Paths in this corpus contain spaces.** `kerml/examples/Address Book +Example/AddressBookModel.kerml` is typical. Any shell iteration of the form + +```sh +for f in $(find test-data/sysml2/official -name '*.sysml'); do ... # WRONG +``` + +word-splits those paths and feeds fragments to the tool, which then fails to +open them. Done while measuring the parse rate, this inflates the failure count +with paths that were never files — it produced a wrong headline number twice +before being caught. Use `find -print0` with `read -d ''`, or iterate in a +language with a real list type. `crates/spar-sysml2/tests/official_corpus.rs` +walks the tree with `std::fs` and does not have the problem. + +## The baseline this corpus establishes + +Measured 2026-08-26 against `f395518`, oracle = the parser's own +`Parse::ok()` (the same predicate the CLI exits non-zero on): + +``` +.sysml 0 / 252 +.kerml 1 / 58 +TOTAL 1 / 310 (0.3%) +``` + +A rate is a property of the corpus as much as the parser, so the failures were +classified rather than counted. There are **five distinct first-error kinds +across 309 failing files**, not 309 problems: + +| first error | files | construct | +|---|---|---| +| `expected name` | 161 | quoted names — `package 'Application Layer';` | +| `expected member declaration` | 97 | visibility modifiers — `private import Objects::*;` | +| `expected SEMICOLON` | 41 | KerML `class` definitions | +| `expected package, import, or definition` | 9 | a visibility-modified import at file scope | +| `expected definition after abstract` | 1 | `abstract type A specializes …` | + +So the parser is a small number of grammar gaps away from a large jump, which +is what `REQ-SYSML2-VISIBILITY-001` is scoped to close. The two KerML kinds +(`class`, `abstract type`) were **not** in that requirement's original scope and +are a finding of this vendoring — recheck it before planning v0.44.0. + +## Refreshing the pin + +```sh +./tools/vendor-sysml2-corpus.sh # re-vendors at the recorded pin +./tools/vendor-sysml2-corpus.sh # moves the pin, deliberately +``` + +Moving the pin is a reviewable change: it will move the ratchet in +`official_corpus.rs`, and the test says so when it fails. diff --git a/test-data/sysml2/download-official-suite.sh b/test-data/sysml2/download-official-suite.sh deleted file mode 100644 index 03752a02..00000000 --- a/test-data/sysml2/download-official-suite.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env bash -# Download official SysML v2 validation and training files from the -# Systems-Modeling/SysML-v2-Release repository. -# -# Usage: ./download-official-suite.sh -# -# This downloads files into: -# validation/official/ -- official validation .sysml files -# training/official/ -- one file per training category -# examples/official/ -- official example files - -set -euo pipefail - -REPO="Systems-Modeling/SysML-v2-Release" -BASE_URL="https://raw.githubusercontent.com/${REPO}/master" -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" - -echo "=== Downloading SysML v2 official test files ===" -echo "Repository: ${REPO}" -echo "Target: ${SCRIPT_DIR}" - -# --- Validation files --- -VALIDATION_DIR="${SCRIPT_DIR}/validation/official" -mkdir -p "${VALIDATION_DIR}" -echo "" -echo "--- Validation files ---" - -# List files from the validation directory using the GitHub API -VALIDATION_FILES=$(curl -sL "https://api.github.com/repos/${REPO}/contents/sysml/src/validation" | \ - python3 -c "import json,sys; [print(x['name']) for x in json.load(sys.stdin) if x['name'].endswith('.sysml')]" 2>/dev/null || true) - -if [ -z "${VALIDATION_FILES}" ]; then - echo "Could not list validation files via API. Trying known files..." - VALIDATION_FILES=" -01-Packages-1.sysml -02-Parts-1.sysml -03-Ports-1.sysml -04-Connections-1.sysml -05-Actions-1.sysml -06-States-1.sysml -07-Requirements-1.sysml -08-Constraints-1.sysml -" -fi - -for FILE in ${VALIDATION_FILES}; do - echo " Downloading ${FILE}..." - curl -sL "${BASE_URL}/sysml/src/validation/${FILE}" -o "${VALIDATION_DIR}/${FILE}" 2>/dev/null || \ - echo " SKIP: ${FILE} not found" -done - -# --- Training files (one per category) --- -TRAINING_DIR="${SCRIPT_DIR}/training/official" -mkdir -p "${TRAINING_DIR}" -echo "" -echo "--- Training files ---" - -TRAINING_DIRS=$(curl -sL "https://api.github.com/repos/${REPO}/contents/sysml/src/training" | \ - python3 -c "import json,sys; [print(x['name']) for x in json.load(sys.stdin) if x['type'] == 'dir']" 2>/dev/null || true) - -for DIR in ${TRAINING_DIRS}; do - # Get first .sysml file from each training directory - FIRST_FILE=$(curl -sL "https://api.github.com/repos/${REPO}/contents/sysml/src/training/${DIR}" | \ - python3 -c "import json,sys; files=[x['name'] for x in json.load(sys.stdin) if x['name'].endswith('.sysml')]; print(files[0] if files else '')" 2>/dev/null || true) - if [ -n "${FIRST_FILE}" ]; then - echo " Downloading ${DIR}/${FIRST_FILE}..." - curl -sL "${BASE_URL}/sysml/src/training/${DIR}/${FIRST_FILE}" \ - -o "${TRAINING_DIR}/${DIR}-${FIRST_FILE}" 2>/dev/null || \ - echo " SKIP: ${FIRST_FILE} not found" - fi -done - -# --- Example files --- -EXAMPLES_DIR="${SCRIPT_DIR}/examples/official" -mkdir -p "${EXAMPLES_DIR}" -echo "" -echo "--- Example files ---" - -EXAMPLE_FILES=$(curl -sL "https://api.github.com/repos/${REPO}/contents/sysml/src/examples" | \ - python3 -c " -import json, sys -data = json.load(sys.stdin) -for item in data: - if item['name'].endswith('.sysml'): - print(item['name']) - elif item['type'] == 'dir': - print('DIR:' + item['name']) -" 2>/dev/null || true) - -for ITEM in ${EXAMPLE_FILES}; do - if [[ "${ITEM}" == DIR:* ]]; then - SUBDIR="${ITEM#DIR:}" - SUBFILES=$(curl -sL "https://api.github.com/repos/${REPO}/contents/sysml/src/examples/${SUBDIR}" | \ - python3 -c "import json,sys; [print(x['name']) for x in json.load(sys.stdin) if x['name'].endswith('.sysml')]" 2>/dev/null || true) - for SF in ${SUBFILES}; do - echo " Downloading ${SUBDIR}/${SF}..." - curl -sL "${BASE_URL}/sysml/src/examples/${SUBDIR}/${SF}" \ - -o "${EXAMPLES_DIR}/${SUBDIR}-${SF}" 2>/dev/null || \ - echo " SKIP: ${SF} not found" - done - else - echo " Downloading ${ITEM}..." - curl -sL "${BASE_URL}/sysml/src/examples/${ITEM}" \ - -o "${EXAMPLES_DIR}/${ITEM}" 2>/dev/null || \ - echo " SKIP: ${ITEM} not found" - fi -done - -# --- GfSE models --- -GFSE_DIR="${SCRIPT_DIR}/examples/gfse" -mkdir -p "${GFSE_DIR}" -echo "" -echo "--- GfSE SysML v2 Models ---" - -GFSE_REPO="GfSE/SysML-v2-Models" -GFSE_FILES=$(curl -sL "https://api.github.com/repos/${GFSE_REPO}/contents" | \ - python3 -c "import json,sys; [print(x['name']) for x in json.load(sys.stdin) if x['name'].endswith('.sysml')]" 2>/dev/null || true) - -for FILE in ${GFSE_FILES}; do - echo " Downloading ${FILE}..." - curl -sL "https://raw.githubusercontent.com/${GFSE_REPO}/main/${FILE}" \ - -o "${GFSE_DIR}/${FILE}" 2>/dev/null || \ - echo " SKIP: ${FILE} not found" -done - -echo "" -echo "=== Download complete ===" -TOTAL=$(find "${SCRIPT_DIR}" -name "*.sysml" | wc -l | tr -d ' ') -echo "Total .sysml files: ${TOTAL}" diff --git a/test-data/sysml2/official/LICENSE b/test-data/sysml2/official/LICENSE new file mode 100644 index 00000000..e23ece2c --- /dev/null +++ b/test-data/sysml2/official/LICENSE @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Address Book Example/AddressBookModel.kerml b/test-data/sysml2/official/kerml/examples/Address Book Example/AddressBookModel.kerml new file mode 100644 index 00000000..cb620b94 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Address Book Example/AddressBookModel.kerml @@ -0,0 +1,13 @@ +private import ScalarValues::*; +package AddressBookModel { + + class Entry { + name: String; + address: String; + } + + class AddressBook { + entries: Entry[*]; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_N_ary.kerml b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_N_ary.kerml new file mode 100644 index 00000000..7ca7b83d --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_N_ary.kerml @@ -0,0 +1,127 @@ +package ProductSelection_N_ary { + + class ShoppingCart; + class Product; + class Account; + + // User-specified association definition + assoc ProductSelection { + end [0..1] feature cart: ShoppingCart[1]; + end [0..*] feature selectedProduct: Product[1]; + end [1..1] feature account : Account[1]; + } + + // Equivalent association definition with named end features. + assoc ProductSelection1 { + end inCart[0..1] feature cart: ShoppingCart[1]; + end selectedProducts[0..*] feature selectedProduct: Product[1]; + end withAccount[1..1] feature account : Account[1]; + } + + // Equivalent association definition with nested cross features. + assoc ProductSelection2 { + end feature cart: ShoppingCart[1] { + member feature inCart[0..1]; // owned cross feature + } + end feature selectedProduct: Product[1] { + member feature selectedProducts[0..*]; // owned cross feature + } + end feature account : Account[1] { + member feature withAccount[1..1]; // owned cross feature + } + } + + // Equivalent association definition showing library model specialization + // implied cross subsetting, and "Cartesian product" features. + assoc ProductSelection3 specializes Links::Link { + end cart: ShoppingCart[1] crosses cart::product_account.inCart { + member feature inCart: ShoppingCart[0..1] featured by Product_Account { + // Represents the "Cartesian product" of Product X Account. + member feature Product_Account : Account featured by Product; + } + member feature product_account : inCart::Product_Account featured by ProductSelection3 { + public import inCart; + } + } + end selectedProduct: Product[1] crosses selectedProduct::cart_account.selectedProducts { + member feature selectedProducts: Product[0..*] featured by Cart_Account { + // Represents the "Cartesian product" of ShoppingCart X Account. + member feature Cart_Account : Account featured by ShoppingCart; + } + member feature cart_account : selectedProducts::Cart_Account featured by ProductSelection3 { + public import selectedProducts; + } + } + end feature account : Account[1] crosses account::cart_product.withAccount { + member feature withAccount[1..1] : Account featured by Cart_Product { + // Represents the "Cartesian product" of ShoppingCart X Product. + member feature Cart_Product : Product featured by ShoppingCart; + } + member feature cart_product : withAccount::Cart_Product featured by ProductSelection3 { + public import withAccount; + } + } + } + + assoc SingleProductSelection specializes ProductSelection { + end [0..1] feature cart: ShoppingCart[1]; + end [0..1] feature selectedProduct: Product[1]; + end [1..1] feature account : Account[1]; + } + + assoc SingleProductSelection1 specializes ProductSelection1 { + end inCart1 [0..1] feature cart: ShoppingCart[1]; + end selectedProduct1 [0..1] feature selectedProduct: Product[1]; + end withAccount1 [1..1] feature account : Account[1]; + } + + assoc SingleProductSelection2 specializes ProductSelection2 { + end feature cart: ShoppingCart[1] { + member feature inCart1[0..1]; // owned crossing feature + } + end feature selectedProduct: Product[1] { + member feature selectedProducts1[0..*]; // owned crossing feature + } + end feature account : Account[1] { + member feature withAccount1[0..*]; // owned crossing feature + } + } + + assoc SingleProductSelection3 specializes ProductSelection3 { + end cart: ShoppingCart[1] redefines cart crosses cart::product_account1.inCart1 { + member feature inCart1: ShoppingCart[0..1] featured by Product_Account1 { + member feature Product_Account1 subsets Product_Account : Account featured by Product; + } + member feature product_account1 : inCart1::Product_Account1 featured by ProductSelection3 { + public import inCart1; + } + } + end selectedProduct: Product[1] redefines selectedProduct crosses selectedProduct::cart_account1.selectedProduct1 { + member feature selectedProduct1: Product[1..1] featured by Cart_Account1 { + member feature Cart_Account1 subsets Cart_Account : Account featured by ShoppingCart; + } + member feature cart_account1 : selectedProduct1::Cart_Account1 featured by ProductSelection3 { + public import selectedProduct1; + } + } + end feature account : Account[1] crosses account::cart_product1.withAccount1 { + member feature withAccount1[1..1] : Account featured by cart_product1 { + member feature Cart_Product1 subsets Cart_Product : Product featured by ShoppingCart; + } + member feature cart_product1 : withAccount1::Cart_Product1 featured by ProductSelection3 { + public import withAccount1; + } + } + } + + class OnlineCustomer { + feature myCart: ShoppingCart[1]; + feature products: Product[0..*]; + feature myAccount : Account[1]; + + connector ps1 : ProductSelection (myCart, products, myAccount); + + connector ps2 : ProductSelection ([1] myCart, [0..1] products, [1] myAccount); + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_OwnedEnds.kerml b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_OwnedEnds.kerml new file mode 100644 index 00000000..747b0525 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_OwnedEnds.kerml @@ -0,0 +1,94 @@ +package ProductSelection_OwnedEnds { + + class SelectionInfo; + class ShoppingCart; + class Product; + + // User-specified association definition + assoc ProductSelection { + feature info: SelectionInfo; + + end [0..1] feature cart: ShoppingCart[1]; + end [0..*] nonunique feature selectedProduct: Product[1]; + } + + // Equivalent association definition with named end features. + assoc ProductSelection1 { + feature info: SelectionInfo; + + end inCart[0..1] feature cart: ShoppingCart[1]; + end selectedProducts[0..*] feature selectedProduct: Product[1]; + } + + // Equivalent association definition with nested cross features. + assoc ProductSelection2 { + feature info: SelectionInfo; + + end feature cart: ShoppingCart[1] { + member feature inCart[0..1]; // owned cross feature + } + end feature selectedProduct: Product[1] { + member feature selectedProducts[0..*]; // owned cross feature + } + } + + // Equivalent association definition showing library model specialization + // and implied cross subsetting. + assoc ProductSelection3 specializes Links::BinaryLink { + feature info: SelectionInfo; + + end cart: ShoppingCart[1] redefines source crosses selectedProduct.inCart { + member feature inCart: ShoppingCart[0..1] featured by Product; + public import selectedProduct::selectedProducts; + } + end selectedProduct: Product[1] redefines target crosses cart.selectedProducts { + member feature selectedProducts: Product[0..*] featured by ShoppingCart; + public import cart::inCart; + } + } + + assoc SingleProductSelection specializes ProductSelection { + end [0..1] feature cart: ShoppingCart[1]; + end [0..1] feature selectedProduct: Product[1]; + } + + assoc SingleProductSelection1 specializes ProductSelection1 { + end inCart1 [0..1] feature cart: ShoppingCart[1]; + end selectedProduct1 [0..1] feature selectedProduct: Product[1]; + } + + assoc SingleProductSelection2 specializes ProductSelection2 { + end feature cart: ShoppingCart[1] { + member feature inCart1[0..1]; // owned crossing feature + } + end feature selectedProduct: Product[1] { + member feature selectedProduct1[0..1]; // owned crossing feature + } + } + + assoc SingleProductSelection3 specializes ProductSelection3 { + end cart: ShoppingCart[1] redefines cart crosses selectedProduct.inCart1 { + member feature inCart1[0..1] subsets inCart featured by Product; + public import selectedProduct::selectedProduct1; + } + end selectedProduct: Product[1] redefines selectedProduct crosses cart.selectedProduct1 { + member feature selectedProduct1[0..1] subsets selectedProducts featured by ShoppingCart; + public import cart::inCart1; + } + } + + class OnlineCustomer { + feature info1: SelectionInfo; + feature myCart: ShoppingCart[1]; + feature products: Product[0..*]; + + connector ps1 : ProductSelection from myCart to products { + :>> info = info1; + } + + connector ps2 : ProductSelection from [1] myCart to [1] products { + :>> info = info1; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_UnownedEnds.kerml b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_UnownedEnds.kerml new file mode 100644 index 00000000..ef44c14e --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Association Examples/ProductSelection_UnownedEnds.kerml @@ -0,0 +1,47 @@ +package ProductSelection_UnownedEnds { + + class SelectionInfo; + class ShoppingCart { + feature selectedProducts : Product[0..*]; + } + class Product { + feature inCart: ShoppingCart[0..1]; + } + + assoc ProductSelection { + feature info: SelectionInfo[1]; + + end feature cart: ShoppingCart[1] crosses selectedProduct.inCart; + end feature selectedProduct: Product[1] crosses cart.selectedProducts; + } + + assoc SingleProductSelection :> ProductSelection { + end feature cart: ShoppingCart[1]; + end [0..1] feature selectedProduct: Product[1]; + } + + // Equivalent association showing implied relationships explicitly. + assoc SingleProductSelection1 :> ProductSelection { + end feature cart: ShoppingCart[1] redefines cart { + public import selectedProduct::selectedProduct1; + } + end feature selectedProduct: Product[1] redefines selectedProduct crosses cart.selectedProduct1 { + member feature selectedProduct1[0..1] subsets ShoppingCart::selectedProducts featured by ShoppingCart; + } + } + + class OnlineCustomer { + feature info1: SelectionInfo; + feature myCart: ShoppingCart[1]; + feature products: Product[0..*]; + + connector ps1 : ProductSelection from myCart to products { + :>> info = info1; + } + + connector ps2 : ProductSelection from [1] myCart to [1] products { + :>> info = info1; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Behavior Examples/Camera.kerml b/test-data/sysml2/official/kerml/examples/Behavior Examples/Camera.kerml new file mode 100644 index 00000000..5bf3a55e --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Behavior Examples/Camera.kerml @@ -0,0 +1,8 @@ +class Camera { + private import ScalarValues::*; + + portion focusedState: Camera subsets timeSlices; + portion shotState: Camera subsets timeSlices; + + succession focusedState then shotState; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Behavior Examples/TakePicture.kerml b/test-data/sysml2/official/kerml/examples/Behavior Examples/TakePicture.kerml new file mode 100644 index 00000000..c89499b2 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Behavior Examples/TakePicture.kerml @@ -0,0 +1,18 @@ +behavior TakePicture { + private import Camera; + + feature camera: Camera[1] subsets involvedObjects; + + class Exposure; + + behavior Focus { out xrsl: Exposure; } + behavior Shoot { in xsf: Exposure; } + + step step1: Focus[1]; + step step2: Shoot[1]; + + succession flow exposure[1] of Exposure from step1.xrsl to step2.xsf; + + succession step1 then camera.focusedState; + succession step2 then camera.shotState; +} diff --git a/test-data/sysml2/official/kerml/examples/Individuals Examples/JohnIndividualExample.kerml b/test-data/sysml2/official/kerml/examples/Individuals Examples/JohnIndividualExample.kerml new file mode 100644 index 00000000..e9518911 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Individuals Examples/JohnIndividualExample.kerml @@ -0,0 +1,103 @@ +package JohnIndividualExample { + private import Objects::*; + + class Person specializes Object { + doc + /* + This is the class of persons, each of whom has an age. + It is NOT restricted to maximal portions. + (The specialization of Object would normally be left implicit.) + */ + + class Life specializes Person, Occurrences::Life; + + feature age : ScalarValues::Natural; + + feature redefines portions : Person { + doc + /* + These redefinitions enforce the "rigidity" constraint for Person. + They ensure that all portions of a person are also persons and + that a person can only be a portion of another person. This implies + that the class Person must also include all the portions of any one + of its instances. The redefinitions for the portion features + also implicitly constraint the typing of the time slice and snapshot + features, since they are subsets of portioning. + (It is currently awkward to have to declare these redefinitions + explicitly.) + */ + } + feature redefines portionOf : Person; + + } + + class President specializes Person { + doc + /* + This is the class of presidents, each of which must be a time slice + of the life of some individual person. + (Note that this class is NOT "rigid".) + */ + + feature redefines timeSliceOf : Person::Life [1]; + } + + class John specializes Person { + doc + /* + This is the class of the specific (individual) person who is John. + There is at most one such person. + */ + + class all JohnLife[0..1] specializes John, Occurrences::Life; + } + + class JohnAsPresident specializes John, President { + doc + /* + This is the class of time slices of John's life in which he is + a president. + */ + } + + class Country specializes Object { + doc + /* + This is the class of countries, each of which may have at most one + president. + */ + + class all Life specializes Country, Occurrences::Life; + + feature presidentOfCountry : President[0..1]; + + // Rigidity constraint. + feature redefines portions : Country; + feature redefines portionOf : Country; + } + + class UnitedStates specializes Country { + doc + /* + This is the class of the specific country that is the + United States. It contains a single instance. The United States + always has a president who must be at least 35 years old. + */ + + class all USLife[1] specializes UnitedStates, Occurrences::Life ; + feature presidentOfUS[1] redefines presidentOfCountry { + inv { age >= 35 } + } + } + + class UnitedStatesWithJohnAsPresident specializes UnitedStates { + doc + /* + This is the class of time slices of the United States during + which John is president of the United States. + */ + + feature redefines timeSliceOf : UnitedStates::Life; + feature redefines presidentOfUS : JohnAsPresident; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-Atoms.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-Atoms.kerml new file mode 100644 index 00000000..173273f9 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-Atoms.kerml @@ -0,0 +1,14 @@ +package Atoms { + doc + /* This package defines a keyword (atom) for classifiers with + * exactly one instance and are disjoint from any others + * marked with this keyword. + */ + + private import Metaobjects::Metaobject; + + classifier Atom; + metaclass AtomMetadata specializes Metaobject { + baseType = Atom meta KerML::Classifier; + } +} diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-ModelingInstances.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-ModelingInstances.kerml new file mode 100644 index 00000000..be68c540 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-2-ModelingInstances.kerml @@ -0,0 +1,38 @@ +package ModelingInstances { + doc + /* + */ + + classifier Vehicle; + classifier Bicycle specializes Vehicle; + classifier MyBike [1] specializes Bicycle; + classifier YourBike [1] specializes Bicycle disjoint from MyBike; +} + +package ModelingInstancesWithAtoms { + doc + /* + */ + + private import Atoms::atom; + + classifier Vehicle; + classifier Bicycle specializes Vehicle; + + #atom + classifier MyBike specializes Bicycle; + #atom + classifier YourBike specializes Bicycle; + + /* Assigning feature values. */ + + classifier Garage { + feature stores : Bicycle [*]; + } + classifier OurBicycle unions MyBike, YourBike; + + #atom + classifier OurGarage specializes Garage { + feature redefines stores : OurBicycle [2]; + } +} diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-2-WithoutConnectors.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-2-WithoutConnectors.kerml new file mode 100644 index 00000000..0e8c3959 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-2-WithoutConnectors.kerml @@ -0,0 +1,37 @@ + +package WithoutConnectorsModelToBeExecuted { + doc + /* + */ + + classifier Bicycle { + feature rollsOn : Wheel [2]; + feature holdsWheel : BikeFork [*]; + } + classifier Wheel; + classifier BikeFork; +} + +package WithoutConnectorsExecution { + doc + /* + */ + + private import Atoms::*; + private import WithoutConnectorsModelToBeExecuted::*; + + #atom + classifier MyWheel1 specializes Wheel; + #atom + classifier MyWheel2 specializes Wheel; + + classifier MyWheel unions MyWheel1, MyWheel2; + + #atom + classifier MyBike specializes Bicycle { + feature redefines rollsOn : MyWheel; + } +} + + + diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-3-OneToOneConnectors.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-3-OneToOneConnectors.kerml new file mode 100644 index 00000000..f427df91 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-3-OneToOneConnectors.kerml @@ -0,0 +1,58 @@ + +package OneToOneConnectorsModelToBeExecuted { + doc + /* + */ + + public import WithoutConnectorsModelToBeExecuted::Wheel; + public import WithoutConnectorsModelToBeExecuted::BikeFork; + + classifier Bicycle { + feature rollsOn : Wheel [2]; + feature holdsWheel : BikeFork [*]; + connector fixWheel : BikeWheelFixed from [1] rollsOn to [1] holdsWheel; + } + assoc BikeWheelFixed { + end feature wheel : Wheel; + end feature fixedTo : BikeFork; + } +} + +package OneToOneConnectorsExecution { + doc + /* + */ + + private import Atoms::*; + public import OneToOneConnectorsModelToBeExecuted::*; + public import WithoutConnectorsExecution::MyWheel1; + public import WithoutConnectorsExecution::MyWheel2; + public import WithoutConnectorsExecution::MyWheel; + + #atom + classifier MyBikeFork1 specializes BikeFork; + #atom + classifier MyBikeFork2 specializes BikeFork; + + classifier MyBikeFork unions MyBikeFork1, MyBikeFork2; + + #atom + assoc MyBikeWheel1_Fork1_BWF_Link specializes BikeWheelFixed { + end feature redefines wheel : MyWheel1; + end feature redefines fixedTo : MyBikeFork1; + } + #atom + assoc MyBikeWheel2_Fork2_BWF_Link specializes BikeWheelFixed { + end feature redefines wheel : MyWheel2; + end feature redefines fixedTo : MyBikeFork2; + } + + classifier MyBikeWheel_Fork_BWF_Link unions MyBikeWheel1_Fork1_BWF_Link, MyBikeWheel2_Fork2_BWF_Link; + + #atom + classifier MyBike specializes Bicycle { + feature redefines rollsOn : MyWheel; + feature redefines holdsWheel : MyBikeFork; + connector redefines fixWheel : MyBikeWheel_Fork_BWF_Link [2] from [1] rollsOn to [1] holdsWheel; + } +} diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-4-OneToUnrestrictedConnectors.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-4-OneToUnrestrictedConnectors.kerml new file mode 100644 index 00000000..a4572d66 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-4-OneToUnrestrictedConnectors.kerml @@ -0,0 +1,59 @@ + +package OneToUnrestrictedConnectorsModelToBeExecuted { + doc + /* + */ + + private import WithoutConnectorsModelToBeExecuted::BikeFork; + + classifier Bicycle { + feature carrier : BikeBasket [*]; + feature holdsWheel : BikeFork [*]; + connector carrierFixed : BikeBasketFixed from [*] carrier to [1] holdsWheel; + } + classifier BikeBasket; + + assoc BikeBasketFixed { + end feature basket : BikeBasket; + end feature fixedTo : BikeFork; + } +} + +package OneToUnrestrictedConnectorsExecution { + doc + /* + */ + + private import Atoms::*; + private import OneToUnrestrictedConnectorsModelToBeExecuted::*; + private import OneToOneConnectorsExecution::MyBikeFork1; + private import OneToOneConnectorsExecution::MyBikeFork2; + private import OneToOneConnectorsExecution::MyBikeFork; + + #atom + classifier MyBikeBasket1 specializes BikeBasket; + #atom + classifier MyBikeBasket2 specializes BikeBasket; + + classifier MyBikeBasket unions MyBikeBasket1, MyBikeBasket2; + + #atom + assoc MyBikeBasket1_Fork1_BBF_Link specializes BikeBasketFixed { + end feature redefines basket : MyBikeBasket1; + end feature redefines fixedTo : MyBikeFork1; + } + #atom + assoc MyBikeBasket2_Fork1_BBF_Link specializes BikeBasketFixed { + end feature redefines basket : MyBikeBasket2; + end feature redefines fixedTo : MyBikeFork1; + } + + classifier MyBikeBasket_Fork_BBF_Link unions MyBikeBasket1_Fork1_BBF_Link, MyBikeBasket2_Fork1_BBF_Link; + + #atom + classifier MyBike specializes Bicycle { + feature redefines carrier : MyBikeBasket [2]; + feature redefines holdsWheel : MyBikeFork [2]; + connector redefines carrierFixed : MyBikeBasket_Fork_BBF_Link [2] from [*] carrier to [1] holdsWheel; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-5-TimingForStructures.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-5-TimingForStructures.kerml new file mode 100644 index 00000000..ae120e54 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-5-TimingForStructures.kerml @@ -0,0 +1,201 @@ + +package TimingForStructuresModelToBeExecuted1 { + doc + /* + */ + + private import WithoutConnectorsModelToBeExecuted::Wheel; + private import WithoutConnectorsModelToBeExecuted::BikeFork; + private import Occurrences::Occurrence; + + struct Bicycle { + feature rollsOn : Wheel [2] subsets timeCoincidentOccurrences; + feature holdsWheel : BikeFork [2] subsets timeCoincidentOccurrences; + } +} + +package TimingForStructuresExecution1 { + doc + /* + */ + + private import Atoms::*; + private import TimingForStructuresModelToBeExecuted1::*; + private import OneToOneConnectorsExecution::MyWheel; + private import OneToOneConnectorsExecution::MyBikeFork; + + struct MyBikeTimeCoincident unions MyWheel, MyBikeFork, MyBike; + + #atom + struct MyBike specializes Bicycle { + feature redefines self : MyBike; + feature redefines timeCoincidentOccurrences : MyBikeTimeCoincident [5]; + feature redefines rollsOn : MyWheel; + feature redefines holdsWheel : MyBikeFork; + } +} + + +package TimingForStructuresModelToBeExecuted2 { + doc + /* + */ + + private import WithoutConnectorsModelToBeExecuted::Wheel; + private import WithoutConnectorsModelToBeExecuted::BikeFork; + private import Occurrences::Occurrence; + private import Occurrences::HappensDuring; + + struct Bicycle { + feature rollsOn : Wheel [2]; + feature holdsWheel : BikeFork [2]; + feature allParts : Occurrence unions rollsOn, holdsWheel; + connector b_during_ap : HappensDuring from [1] self to [*] allParts; + } +} + +package TimingForStructuresExecution2 { + doc + /* + */ + + private import Atoms::*; + private import TimingForStructuresModelToBeExecuted2::*; + private import Occurrences::HappensDuring; + private import OneToOneConnectorsExecution::MyWheel; + private import OneToOneConnectorsExecution::MyBikeFork; + + struct MyWheel1 specializes OneToOneConnectorsExecution::MyWheel1; + struct MyWheel2 specializes OneToOneConnectorsExecution::MyWheel2; + struct MyBikeFork1 specializes OneToOneConnectorsExecution::MyBikeFork1; + struct MyBikeFork2 specializes OneToOneConnectorsExecution::MyBikeFork2; + + #atom + assoc MyBike_During_Wheel1_Link specializes HappensDuring { + end feature redefines shorterOccurrence : MyBike; + end feature redefines longerOccurrence : MyWheel1; + } + #atom + assoc MyBike_During_Wheel2_Link specializes HappensDuring { + end feature redefines shorterOccurrence : MyBike; + end feature redefines longerOccurrence : MyWheel2; + } + #atom + assoc MyBike_During_Fork1_Link specializes HappensDuring { + end feature redefines shorterOccurrence : MyBike; + end feature redefines longerOccurrence : MyBikeFork1; + } + #atom + assoc MyBike_During_Fork2_Link specializes HappensDuring { + end feature redefines shorterOccurrence : MyBike; + end feature redefines longerOccurrence : MyBikeFork2; + } + + assoc MyBike_During_Parts_Link specializes HappensDuring + unions MyBike_During_Wheel1_Link, MyBike_During_Fork1_Link, + MyBike_During_Wheel2_Link, MyBike_During_Fork2_Link; + + struct MyBikeParts unions MyWheel, MyBikeFork; + + #atom + struct MyBike specializes Bicycle { + feature redefines rollsOn : MyWheel; + feature redefines holdsWheel : MyBikeFork; + feature redefines allParts : MyBikeParts [4]; + + feature redefines self : MyBike; + connector redefines b_during_ap : MyBike_During_Parts_Link [4] + from [1] self to [*] allParts; + } +} + +package TimingForStructuresModelToBeExecuted3 { + doc + /* + */ + + private import WithoutConnectorsModelToBeExecuted::Wheel; + private import WithoutConnectorsModelToBeExecuted::BikeFork; + private import Occurrences::Occurrence; + private import Occurrences::HappensWhile; + + struct Bicycle { + feature rollsOn : Wheel [2]; + feature holdsWheel : BikeFork [2]; + feature allParts : Occurrence unions rollsOn, holdsWheel; + feature redefines endShot : Bicycle; + connector be_while_pe : HappensWhile from [1] endShot to [*] endShot.allParts.endShot; + } +} + +package TimingForStructuresExecution3 { + doc + /* + */ + + private import Atoms::*; + private import TimingForStructuresModelToBeExecuted3::*; + private import Occurrences::Occurrence; + private import Occurrences::HappensWhile; + private import WithoutConnectorsModelToBeExecuted::Wheel; + private import WithoutConnectorsModelToBeExecuted::BikeFork; + + /* End atoms */ + #atom + struct MyWheel1End specializes Wheel; + #atom + struct MyWheel1 specializes Wheel { + feature redefines endShot : MyWheel1End; + } + #atom + struct MyWheel2End specializes Wheel; + #atom + struct MyWheel2 specializes Wheel { + feature redefines endShot : MyWheel2End; + } + struct MyBikeFork1End specializes BikeFork; + #atom + struct MyBikeFork1 specializes BikeFork { + feature redefines endShot : MyBikeFork1End; + } + struct MyBikeFork2End specializes BikeFork; + #atom + struct MyBikeFork2 specializes BikeFork { + feature redefines endShot : MyBikeFork2End; + } + #atom + struct MyBikeEnd specializes Bicycle; + + /* HappensWhile atoms */ + #atom + assoc MyBikeEnd_While_Wheel1End_Link specializes HappensWhile { + end feature redefines thisOccurrence : MyBikeEnd; + end feature redefines thatOccurrence : MyWheel1End; + } + #atom + assoc MyBikeEnd_While_Wheel2End_Link specializes HappensWhile { + end feature redefines thisOccurrence : MyBikeEnd; + end feature redefines thatOccurrence : MyWheel2End; + } + #atom + assoc MyBikeEnd_While_Fork1End_Link specializes HappensWhile { + end feature redefines thisOccurrence : MyBikeEnd; + end feature redefines thatOccurrence : MyBikeFork1End; + } + #atom + assoc MyBikeEnd_While_Fork2End_Link specializes HappensWhile { + end feature redefines thisOccurrence : MyBikeEnd; + end feature redefines thatOccurrence : MyBikeFork2End; + } + + assoc MyBikeEnd_While_PartsEnd_Link specializes HappensWhile + unions MyBikeEnd_While_Wheel1End_Link, MyBikeEnd_While_Fork1End_Link, + MyBikeEnd_While_Wheel2End_Link, MyBikeEnd_While_Fork2End_Link; + + #atom + struct MyBike specializes Bicycle { + feature redefines endShot : MyBikeEnd; + connector redefines be_while_pe : MyBikeEnd_While_PartsEnd_Link [4] + from [1] endShot to [*] endShot.allParts.endShot; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-6-Sequences.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-6-Sequences.kerml new file mode 100644 index 00000000..311f5ee2 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-6-Sequences.kerml @@ -0,0 +1,62 @@ + +package SequencesModelToBeExecuted { + doc + /* + */ + + behavior Manufacture { + step paint : Paint [1]; + step dry : Dry [*]; + succession p_before_d first [1] paint then [1] dry; + step ship : Ship [*]; + succession d_before_s first [1] dry then [1] ship; + } + behavior Paint; + behavior Dry; + behavior Ship; +} + +package SequencesExecution { + doc + /* + */ + + private import Atoms::*; + private import SequencesModelToBeExecuted::*; + private import Occurrences::Occurrence; + private import Occurrences::HappensBefore; + + #atom + behavior MyPaint specializes Paint; + #atom + behavior MyDry specializes Dry; + + #atom + assoc MyPaint_Before_Dry_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyPaint; + end feature redefines laterOccurrence : MyDry; + } + + behavior MyManufactureStepsPD unions MyPaint, MyDry; + + #atom + behavior MyShip specializes Ship; + + #atom + assoc MyDry_Before_Ship_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyDry; + end feature redefines laterOccurrence : MyShip; + } + + behavior MyManufactureStepsPDS unions MyManufactureStepsPD, MyShip; + + #atom + behavior MyManufacture specializes Manufacture { + feature redefines timeEnclosedOccurrences : MyManufactureStepsPDS [3]; + step redefines paint : MyPaint; + step redefines dry : MyDry [1]; + succession redefines p_before_d : MyPaint_Before_Dry_Link [1] first paint then dry; + step redefines ship : MyShip [1]; + succession redefines d_before_s : MyDry_Before_Ship_Link [1] first dry then ship; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-7-DecisionsAndMerges.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-7-DecisionsAndMerges.kerml new file mode 100644 index 00000000..50a699d4 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-7-DecisionsAndMerges.kerml @@ -0,0 +1,132 @@ + +package DecisionsAndMergesModelToBeExecuted { + doc + /* + */ + + private import ControlPerformances::DecisionPerformance; + private import ControlPerformances::MergePerformance; + private import Occurrences::HappensBefore; + private import Links::SelfLink; + + behavior Manufacture { + /* Before decision. */ + step admit : Admit [1]; + succession a_before_i first [1] admit then [1] inspect; + + /* Decision. */ + step inspect : DecisionPerformance [*]; + + /* Two decision branches. */ + succession i_before_f first [1] inspect then [0..1] finish; + step finish : Touchup [*]; + succession i_before_r first [1] inspect then [0..1] recycle; + step recycle : MarkForRecycling [*]; + + /* Two merge branches. */ + succession f_before_ms first [0..1] finish then [1] mShip; + succession r_before_ms first [0..1] recycle then [1] mShip; + + /* Merge */ + step mShip : MergePerformance [*]; + + /* After merge */ + succession ms_before_s first [1] mShip then [1] ship; + step ship : Ship [*]; + + /* Decision and merge timing constraints. */ + feature inspectOutgoingHBLinks : HappensBefore [*] unions i_before_f, i_before_r; + connector bindIOHBL : SelfLink from [1] inspectOutgoingHBLinks to [1] inspect.outgoingHBLink; + feature mShipIncomingHBLinks : HappensBefore [*] unions f_before_ms, r_before_ms; + connector bindmSIHBL : SelfLink from [1] mShipIncomingHBLinks to [1] mShip.incomingHBLink; + } + behavior Admit; + behavior Touchup; + behavior MarkForRecycling; + behavior Ship; +} + +package DecisionsAndMergesExecution { + doc + /* + */ + + private import Atoms::*; + private import DecisionsAndMergesModelToBeExecuted::*; + private import Occurrences::Occurrence; + private import Occurrences::HappensBefore; + private import ControlPerformances::DecisionPerformance; + private import ControlPerformances::MergePerformance; + + /* Before decision. */ + #atom + behavior MyAdmit specializes Admit; + + /* Decision. */ + #atom + behavior MyInspect specializes DecisionPerformance; + #atom + assoc MyAdmit_Before_Inspect_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyAdmit; + end feature redefines laterOccurrence : MyInspect; + } + + /* One decision branch taken. */ + #atom + behavior MyTouchup specializes Touchup; + #atom + assoc MyInspect_Before_Touchup_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyInspect; + end feature redefines laterOccurrence : MyTouchup; + } + + /* One merge branch taken. Merge. */ + #atom + behavior MyMergeToShip specializes MergePerformance; + #atom + assoc MyTouchup_Before_Merge_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyTouchup; + end feature redefines laterOccurrence : MyMergeToShip; + } + + /* After merge. */ + #atom + behavior MyShip specializes Ship; + #atom + assoc MyMerge_Before_Ship_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyMergeToShip; + end feature redefines laterOccurrence : Ship; + } + + behavior MyManufactureSteps unions MyAdmit, MyInspect, MyTouchup, MyMergeToShip, MyShip; + + #atom + behavior MyManufacture specializes Manufacture { + feature redefines timeEnclosedOccurrences : MyManufactureSteps [5]; + + /* Before decision. */ + step redefines admit : MyAdmit [1]; + + /* Decision. */ + step redefines inspect : MyInspect [1]; + succession redefines a_before_i : MyAdmit_Before_Inspect_Link [1] first admit then inspect; + + /* One decision branch taken. */ + step redefines finish : MyTouchup [1]; + succession redefines i_before_f : MyInspect_Before_Touchup_Link [1] first inspect then finish; + + /* One merge branch taken. */ + succession redefines f_before_ms : MyTouchup_Before_Merge_Link [1] first finish then mShip; + + /* Merge. */ + step redefines mShip: MyMergeToShip [1]; + + /* After merge */ + step redefines ship : MyShip [1]; + succession redefines ms_before_s : MyMerge_Before_Ship_Link [1] first mShip then ship; + + /* Decision and merge timing constraints. */ + feature redefines inspectOutgoingHBLinks : MyInspect_Before_Touchup_Link; + feature redefines mShipIncomingHBLinks : MyTouchup_Before_Merge_Link; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-8-ChangingFeatureValues.kerml b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-8-ChangingFeatureValues.kerml new file mode 100644 index 00000000..c0b7914e --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/KerML Spec Annex A Examples/A-3-8-ChangingFeatureValues.kerml @@ -0,0 +1,198 @@ + +package ChangingFeatureValuesModelToBeExecuted { + doc + /* + */ + + private import ScalarValues::Boolean; + private import FeatureReferencingPerformances::FeatureWritePerformance; + + behavior Manufacture { + feature objectToFinish : Product [1]; + step paint : Paint [1] { + redefines objectToPaint = objectToFinish; + } + step dry : Dry [*] { + redefines objectToDry = objectToFinish; + } + succession p_before_d first [1] paint then [1] dry; + step ship : Ship [*] { + redefines objectToShip = objectToFinish; + } + succession d_before_s first [1] dry then [1] ship; + } + + struct Product { + var feature isPainted : Boolean [1] := false; + var feature isDry : Boolean [1] := true; + var feature isShipped : Boolean [1] := false; + } + + behavior Paint { + feature objectToPaint : Product [1]; + + step painting : FeatureWritePerformance [1] { + in redefines onOccurrence : Product = objectToPaint { + redefines startingAt : Product { + redefines accessedFeature : Boolean [1] subsets isDry; } } + in redefines replacementValues = false; + } + + succession p_before_p first [1] painting then [1] painted; + step painted : FeatureWritePerformance [*] { + in redefines onOccurrence : Product = objectToPaint { + redefines startingAt : Product { + redefines accessedFeature : Boolean [1] subsets isPainted; } } + in redefines replacementValues = true; + } + } + + behavior Dry { + feature objectToDry : Product [1]; + step dried : FeatureWritePerformance [1] { + in redefines onOccurrence : Product = objectToDry { + redefines startingAt : Product { + redefines accessedFeature : Boolean [1] subsets isDry; } } + in redefines replacementValues = true; + } + } + + behavior Ship { + feature objectToShip : Product [1]; + step shipped : FeatureWritePerformance [1] { + in redefines onOccurrence : Product = objectToShip { + redefines startingAt : Product { + redefines accessedFeature : Boolean [1] subsets isShipped; } } + in redefines replacementValues = true; + } + } +} + +package ChangingFeatureValuesExecution { + doc + /* + */ + + private import Atoms::*; + private import ChangingFeatureValuesModelToBeExecuted::*; + private import Occurrences::Occurrence; + private import Occurrences::HappensBefore; + private import FeatureReferencingPerformances::FeatureWritePerformance; + + struct ProductTimeSlice specializes Product { + feature redefines isPainted; + feature redefines isDry; + feature redefines isShipped; + } + + #atom + struct MyProduct specializes Product { + feature beforePaint : ProductTimeSlice [1] subsets timeSlices; + feature whilePainting : ProductTimeSlice [1] subsets timeSlices; + feature afterPaint : ProductTimeSlice [1] subsets timeSlices; + feature afterDry : ProductTimeSlice [1] subsets timeSlices; + feature afterShip : ProductTimeSlice [1] subsets timeSlices; + } + + behavior MyProductFeatureWrite specializes FeatureWritePerformance { + in redefines onOccurrence : MyProduct; + } + + #atom + behavior PaintingMyProductFeatureWrite specializes MyProductFeatureWrite; + #atom + behavior PaintedMyProductFeatureWrite specializes MyProductFeatureWrite; + #atom + assoc MyPaintingFW_Before_PaintFW_Link specializes HappensBefore { + end feature redefines earlierOccurrence : PaintingMyProductFeatureWrite; + end feature redefines laterOccurrence : PaintedMyProductFeatureWrite; + } + #atom + behavior MyPaint specializes Paint { + feature redefines objectToPaint : MyProduct; + step redefines painting : PaintingMyProductFeatureWrite { + in onOccurrence; + } + step redefines painted : PaintedMyProductFeatureWrite { + in onOccurrence; + } + succession redefines p_before_p : MyPaintingFW_Before_PaintFW_Link first painting then painted; + } + + #atom + behavior MyDry specializes Dry { + feature redefines objectToDry : MyProduct; + step redefines dried : MyProductFeatureWrite { + in onOccurrence; + } + } + #atom + assoc MyPaint_Before_Dry_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyPaint; + end feature redefines laterOccurrence : MyDry; + } + #atom + behavior MyShip specializes Ship { + feature redefines objectToShip : MyProduct; + step redefines shipped : MyProductFeatureWrite { + in onOccurrence; + } + } + #atom + assoc MyDry_Before_Ship_Link specializes HappensBefore { + end feature redefines earlierOccurrence : MyDry; + end feature redefines laterOccurrence : MyShip; + } + #atom + behavior MyManufacture specializes Manufacture { + feature redefines objectToFinish : MyProduct; + feature redefines startShot subsets objectToFinish.beforePaint.startShot.timeCoincidentOccurrences; + feature obPiP chains objectToFinish.beforePaint.isPainted = false; + feature obPiD chains objectToFinish.beforePaint.isDry = true; + feature obPiS chains objectToFinish.beforePaint.isShipped = false; + + + step redefines paint : MyPaint { + feature redefines paint::objectToPaint, MyPaint::objectToPaint; + } + feature subsets objectToFinish.beforePaint.immediateSuccessors, + objectToFinish.whilePainting.startShot.timeCoincidentOccurrences + chains paint.painting.endShot; + feature owPiP chains objectToFinish.whilePainting.isPainted = false; + feature owPiD chains objectToFinish.whilePainting.isDry = false; + feature owPiS chains objectToFinish.whilePainting.isShipped = false; + + + feature subsets objectToFinish.whilePainting.immediateSuccessors, + objectToFinish.afterPaint.startShot.timeCoincidentOccurrences + chains paint.painted.endShot; + feature oaPiP chains objectToFinish.afterPaint.isPainted = true; + feature oaPiD chains objectToFinish.afterPaint.isDry = false; + feature oaPiS chains objectToFinish.afterPaint.isShipped = false; + + + step redefines dry : MyDry { + feature redefines dry::objectToDry, MyDry::objectToDry; + } + succession redefines p_before_d : MyPaint_Before_Dry_Link [1] first paint then dry; + feature subsets objectToFinish.afterPaint.immediateSuccessors, + objectToFinish.afterDry.startShot.timeCoincidentOccurrences + chains dry.dried.endShot; + feature oaDiP chains objectToFinish.afterDry.isPainted = true; + feature oaDiD chains objectToFinish.afterDry.isDry = true; + feature oaDiS chains objectToFinish.afterDry.isShipped = false; + + + step redefines ship : MyShip { + feature redefines ship::objectToShip, MyShip::objectToShip; + } + succession redefines d_before_s : MyDry_Before_Ship_Link [1] first dry then ship; + feature subsets objectToFinish.afterDry.immediateSuccessors, + objectToFinish.afterShip.startShot.timeCoincidentOccurrences + chains ship.shipped.endShot; + feature redefines endShot subsets objectToFinish.afterShip.timeCoincidentOccurrences; + feature oaSiP chains objectToFinish.afterShip.isPainted = true; + feature oaSiD chains objectToFinish.afterShip.isDry = true; + feature oaSiS chains objectToFinish.afterShip.isShipped = true; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_1.kerml b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_1.kerml new file mode 100644 index 00000000..c9d81631 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_1.kerml @@ -0,0 +1,11 @@ +package MassRollup_1 { + private import NumericalFunctions::*; + + class MassedThing { + feature mass : ScalarValues::Real; + composite subcomponents: MassedThing[0..*]; + + feature totalMass : ScalarValues::Real = + mass + sum(subcomponents.totalMass); + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_2.kerml b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_2.kerml new file mode 100644 index 00000000..71304f6a --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/MassRollup_2.kerml @@ -0,0 +1,15 @@ +package MassRollup_2 { + private import NumericalFunctions::*; + private import ISQ::*; + + class MassedThing { + feature mass : ScalarValues::Real; + feature totalMass : ScalarValues::Real = + mass + sum(subcomponents.totalMass); + + feature subcomponents redefines massedThings; + } + + feature massedThings: MassedThing[0..*]; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_1.kerml b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_1.kerml new file mode 100644 index 00000000..d0be8164 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_1.kerml @@ -0,0 +1,41 @@ +package Vehicles_1 { + private import ScalarValues::String; + private import MassRollup_1::*; + + class Vehicle specializes MassedThing { + feature vin: String; + feature m redefines mass; + + composite engine: Engine subsets subcomponents; + composite transmission: Transmission subsets subcomponents; + } + + class Engine specializes MassedThing { + feature serialNumber: String; + feature m redefines mass; + + // ... + } + + class Transmission specializes MassedThing { + feature serialNumber: String; + feature m redefines mass; + + // ... + } + + // Example usage + + private import SI::*; + feature v: Vehicle { + feature m redefines Vehicle::m = 1000; + composite engine redefines Vehicle::engine { + feature m redefines Engine::m = 100; + } + composite transmission redefines Vehicle::transmission { + feature m redefines Transmission::m = 50; + } + } + + // v.totalMass evaluates to 1150.0 +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_2.kerml b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_2.kerml new file mode 100644 index 00000000..d7bb81a2 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_2.kerml @@ -0,0 +1,38 @@ +package Vehicles_2 { + private import ScalarValues::String; + private import MassRollup_1::*; + + class CarPart specializes MassedThing { + feature serialNumber: String; + feature m redefines mass; + + composite subparts: CarPart[0..*] redefines subcomponents; + } + + feature vehicle: CarPart { + feature vin redefines serialNumber; + + composite engine: CarPart subsets subparts { + //... + } + + composite transmission: CarPart subsets subparts { + //... + } + } + + // Example usage + + private import SI::*; + feature v: vehicle { + feature m redefines CarPart::m = 1000; + composite engine redefines vehicle::engine { + feature m redefines CarPart::m = 100; + } + composite transmission redefines vehicle::transmission { + feature m redefines CarPart::m = 50; + } + } + + // v.totalMass evaluates to 1150.0 +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_3.kerml b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_3.kerml new file mode 100644 index 00000000..dcf00216 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Mass Roll-up Example/Vehicles_3.kerml @@ -0,0 +1,47 @@ +package Vehicles_3 { + private import ScalarValues::*; + private import MassRollup_2::*; + + class CarPart specializes MassedThing { + feature serialNumber: String; + feature m redefines MassedThing::mass; + + feature subparts redefines carParts; + } + + composite feature carParts: CarPart[0..*] subsets massedThings; + + feature vehicle subsets carParts { + feature vin redefines serialNumber; + + feature redefines engine; + feature redefines transmission; + } + + composite feature engine subsets carParts { + //... + } + + composite feature transmission subsets carParts { + //... + } + + // Example usage + + private import SI::*; + feature v: vehicle { + feature m redefines CarPart::m = 1000; + composite :>> engine = e; + composite :>> transmission = t; + } + + feature e :> engine { + feature m redefines CarPart::m = 100; + } + + feature t :> transmission { + feature m redefines CarPart::m = 50; + } + + // v.totalMass evaluates to 1150.0 +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Massed Thing Example/MassedThings.kerml b/test-data/sysml2/official/kerml/examples/Massed Thing Example/MassedThings.kerml new file mode 100644 index 00000000..556b6083 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Massed Thing Example/MassedThings.kerml @@ -0,0 +1,13 @@ +private import ScalarValues::*; +package MassedThings { + + public class MassedThing { + public name: String; + public mass: Real = 0; + } + + public assoc MassedThingAssembly { + public end [0..1] feature assembly: MassedThing; + public end [0..*] feature parts: MassedThing; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Named Collection Members Example/VehicleTanks.kerml b/test-data/sysml2/official/kerml/examples/Named Collection Members Example/VehicleTanks.kerml new file mode 100644 index 00000000..1323adee --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Named Collection Members Example/VehicleTanks.kerml @@ -0,0 +1,33 @@ +package VehicleTanks { + private import ScalarValues::*; + private import RealFunctions::*; + + class V6Engine; + + class Tank { + feature capacity: Real; + } + + class Vehicle { + composite tanks: Tank[1..*] ordered; + + feature fuelCapacity: Real = sum(tanks.capacity); + } + + class Vehicle1 specializes Vehicle { + composite tanks: Tank[4] ordered redefines Vehicle::tanks { + feature main1[1] subsets tanks = tanks#(1); + feature main2[1] subsets tanks = tanks#(2); + feature aux1[1] subsets tanks = tanks#(3); + feature aux2[1] subsets tanks = tanks#(4); + } + + composite eng: V6Engine; + + connector eng to tanks.main1; + connector tanks.main1 to tanks.aux1; + + connector eng to tanks.main2; + connector tanks.main2 to tanks.aux2; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Packet Example/PacketUsage.kerml b/test-data/sysml2/official/kerml/examples/Packet Example/PacketUsage.kerml new file mode 100644 index 00000000..1c5e2325 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Packet Example/PacketUsage.kerml @@ -0,0 +1,16 @@ +private import Packets::*; +private import ScalarValues::Real; +package 'Packet Usage' { + + feature packet1: 'Thermal Data Packet'; + feature packet2: 'Thermal Data Packet'; + feature packet3: 'Thermal Data Packet' { + feature 'special data field' redefines 'packet data field'{ + feature :>> 'user data field' { + feature 'special data': Real; + } + } + } + +} + diff --git a/test-data/sysml2/official/kerml/examples/Packet Example/Packets.kerml b/test-data/sysml2/official/kerml/examples/Packet Example/Packets.kerml new file mode 100644 index 00000000..7eb7df7a --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Packet Example/Packets.kerml @@ -0,0 +1,35 @@ +private import ScalarValues::*; +private import Time::DateTime; +package Packets { + + feature 'packet header' { } + + feature 'packet data field' { + feature 'packet secondary header' redefines 'packet header'; + feature 'user data field'; + } + + class 'Data Packet' { + feature 'packet primary header' redefines 'packet header' { + feature 'packet version number': Integer; + feature 'packet identification': String; + feature 'packet data length': Integer; + } + feature redefines 'packet data field'; + } + + class 'Thermal Data Packet' specializes 'Data Packet' { + feature 'packet data field' redefines Packets::'packet data field'{ + feature 'packet secondary header' redefines 'packet header' { + feature 'packet timestamp': DateTime; + feature 'telemetry packet type': String; + } + + feature 'user data field' redefines Packets::'packet data field'::'user data field' { + feature timestamp: DateTime; + feature temperature: Real; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/ArgumentResolution.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/ArgumentResolution.kerml new file mode 100644 index 00000000..8d6ca648 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/ArgumentResolution.kerml @@ -0,0 +1,17 @@ +package ArgumentResolutionBug { + class A { + feature x; + } + + behavior B { + in feature x; + out feature : A = new A(x); + } + + class C { + feature a : A; + feature b : B; + + connector a ::> a.x to b; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Associations.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Associations.kerml new file mode 100644 index 00000000..3bfc8e9d --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Associations.kerml @@ -0,0 +1,27 @@ +package Associations { + datatype X; + class Y; + + assoc A { + end x_cross [1..1] feature x : X; + end y_cross [1..*] feature y : Y; + } + + assoc B specializes A { + end x1; + end [0..*] feature y1 redefines y; + } + + assoc struct C { + const end [1] feature a; + const end feature b; + } + + metaclass M; + assoc XY { + end [0..1] feature x : X { + @M; + } + end feature y : Y; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Behaviors.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Behaviors.kerml new file mode 100644 index 00000000..f123f335 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Behaviors.kerml @@ -0,0 +1,21 @@ +package Behaviors { + behavior A { + in x; + out y = b.y1; + composite step b : B { + in x1 = A::x; + } + } + behavior B specializes A { + in x1; + out var y1; + } + class C { + var z = A().y; + step a : A; + step b : B; + binding z = a.y; + flow a.y to b.x1; + } + abstract flow msg of C; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Circular.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Circular.kerml new file mode 100644 index 00000000..ea56cb8c --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Circular.kerml @@ -0,0 +1,12 @@ +package Circular { + class A { } + feature a: A; + alias Circ for Circular; + package P { + public import Circular::*; + } + + feature x :> z; + feature y :> x; + feature z :> y; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Classes.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Classes.kerml new file mode 100644 index 00000000..e2b00971 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Classes.kerml @@ -0,0 +1,33 @@ +package Classes { + + feature f: A; + + public class <'1'> A { + feature b: B; + protected in c: C; + portion feature p : A; + } + + abstract class <'2'> B { + public abstract feature a: A { + composite feature aa: A; + } + public composite feature a1: A; + feature x { + composite feature a: A { + portion feature q : A; + } + portion feature q : A; + } + package P { } + } + + private struct C specializes Classes::'2' { + private y: A, '2'[0..*]; + alias z for y; + composite feature c : C { + composite feature cc : C; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Classifications.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Classifications.kerml new file mode 100644 index 00000000..0609b75c --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Classifications.kerml @@ -0,0 +1,8 @@ +package Classifications { + class T; + x; + y = x istype T or x hastype z; + z = (all T)#(3); + a = x as T; + b = x meta KerML::Feature; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Classifiers.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Classifiers.kerml new file mode 100644 index 00000000..d6af2f70 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Classifiers.kerml @@ -0,0 +1,16 @@ +package Classifiers { + classifier A; + classifier B; + + specialization Super subclassifier A specializes B; + specialization subclassifier B :> A; + + subclassifier C specializes A; + subclassifier C specializes B; + + classifier C specializes A, B; + + classifier D disjoint from C differences A, B; + classifier E specializes C intersects A, B; + classifier F unions A unions B; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Comments.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Comments.kerml new file mode 100644 index 00000000..77c9777b --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Comments.kerml @@ -0,0 +1,46 @@ +/* AAA */ +//a lexical comment ("note") is not a part of model +package Comments { + // inside package + /* +*AAA + * BBB*/ + /* + * + * + * AAA *** + *BBB + */ + + /* + * AAAA + * BBBB */ + /* AAAA + + + * BBBB + * + * CCCC + */ + locale "en_US" /* + * AAAA + * BBBB + * CCC DDD + */ + + /* comment inside a package */ + comment cmt /* Named Comment */ + comment cmt_cmt about cmt /* Other Comment about Comment */ + + class C { + doc locale "en_US"/* Documentation on Class C */ + comment /* Comment in Class C */ + comment about Comments /* Comment about Package */ + + } + /* abc */ + class A { + doc /* Documentation comment on A*/ + comment about a locale "en_US" /* Comment about documenation with ID 'a' */ + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Conjugation.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Conjugation.kerml new file mode 100644 index 00000000..87b7c6b4 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Conjugation.kerml @@ -0,0 +1,9 @@ +package Conjugation { + class A { + in feature f; + } + + class B conjugates A; + + feature g ~ B::f; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Connectors.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Connectors.kerml new file mode 100644 index 00000000..38841415 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Connectors.kerml @@ -0,0 +1,43 @@ +package Connectors { + + class A { + feature a : A; + feature b : A; + + connector c1 from a to b; + abstract connector c2 = c1; + connector = c2 { + end feature references a; + end feature references b; + } + + binding a = b; + binding ab of a = b; + binding { + end feature references a; + end feature references b; + } + binding ab1 : AS of a = b; + + succession a then b; + succession s first a then b; + succession { + end feature references a; + end feature references b; + } + succession s1 : AS first a then b; + + } + + class B { + feature a : A; + connector :> a.c1 from a.a to a.b; + } + + assoc struct AS { + end a; + end b; + } + + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Dependencies.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Dependencies.kerml new file mode 100644 index 00000000..3a833977 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Dependencies.kerml @@ -0,0 +1,22 @@ +package Dependencies { + + package System { + package 'Application Layer'; + package 'Service Layer'; + package 'Data Layer'; + } + + public import System::*; + + dependency Use from 'Application Layer' to 'Service Layer'; + dependency from 'Service Layer' to 'Data Layer'; + + feature x; + feature y; + feature z; + + dependency z to x, y { + feature e; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Expansion.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Expansion.kerml new file mode 100644 index 00000000..bcb94b8f --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Expansion.kerml @@ -0,0 +1,4 @@ +package Expansion { + private import ControlFunctions::select; + feature x = x->select {in y; in w; in z; w+1}; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Expressions.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Expressions.kerml new file mode 100644 index 00000000..271932c6 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Expressions.kerml @@ -0,0 +1,75 @@ +package Expressions { + private import ScalarFunctions::*; + private import BaseFunctions::ToString; + private import ControlFunctions::*; + + a: Integer; + aa : Boolean; + x = ToString(a * a + 3 == 4); + y = NumericalFunctions::'+'(1,2); + z : Boolean = aa & true xor zz | false implies z; + zz : Boolean = aa and true xor aa or false implies z; + grp = -x + x * y * y + a ** 3 ^ 4; + + b = if x > y? x-y else y-x; + c = x->collect {in xx; xx + 1}; + c1 = x.{in xx; xx + 1}; + d = x->select {in xx; xx != null}; + d1 = x.?{in xx; xx != null}; + e = x->reduce {in s; in t; s + t}->reduce '+'; + + behavior w { inout v : Integer; + step : ControlPerformances::LoopPerformance { + in expr whileTest {v > 3} + in step body { + step decrement { + out v_decr : Integer = v - 1; + } + succession decrement then update; + step update : FeatureReferencingPerformances::FeatureWritePerformance { + in onOccurrence = w::self { + feature redefines startingAt : w { + inout feature redefines accessedFeature redefines v; + } + } + inout replacementValues = decrement.v_decr; + } + } + } + } + + xx = if x == 1 and y == 2? a + else if x == 2? b + else if x == 3? c + else 0; + + function TotalMass { in partMass; in subparts; + partMass + (subparts->collect {in p; totalMass(partMass, subparts)}->reduce '+' ?? 0.0) + } + + expr totalMass: TotalMass { in mass; in sub; } + + feature f { + expr s { in x; return : Boolean; } + } + + bb : Boolean = f.s(1); + + class C { + var count : ScalarValues::Integer := 0; + } + + feature obj1 : C; + feature obj2 : C; + + test1 = obj1 === obj2; + test2 = x !== obj2; + + class L { + feature c : C[*]; + feature count : ScalarValues::Integer = c#(1).count; + } + + feature l = new L(); + feature w1 = w(xx); +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureChains.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureChains.kerml new file mode 100644 index 00000000..1507e1b2 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureChains.kerml @@ -0,0 +1,36 @@ +package FeatureChains { + classifier F { + feature a : A; + } + + feature f : F; + + classifier A { + feature g = f.a; + } + + classifier B { + feature f : F; + feature a : A; + } + + feature b : B { + connector f.a to a.g; + binding f.a = a.g; + } + + feature g subsets f.a; + subset g.g subsets b.f.a; + redefinition b.f redefines b.a; + + subtype g.g specializes b.f.a; + + disjoint b.f.a from b.a; + + feature h1 unions f, b.f, b.a; + feature h2 differences b.f, b.a intersects f.a, g disjoint from h1; + + feature b_f_a chains b chains f.a; + + feature x conjugates f.a; +} diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureInheritance.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureInheritance.kerml new file mode 100644 index 00000000..a420d938 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/FeatureInheritance.kerml @@ -0,0 +1,7 @@ +package FeatureInheritance { + feature s { + feature t : ISQ::TorqueValue; + } + + feature u subsets s; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Features.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Features.kerml new file mode 100644 index 00000000..1eccb81e --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Features.kerml @@ -0,0 +1,72 @@ +package Features { + classifier A; + classifier B; + + feature f; + feature g; + + feature x typed by A, B references f subsets g; + + // Equivalent declaration: + feature x1 subsets g typed by A subsets f typed by B; + + classifier C; + + feature y; + featuring F of y by C; + + feature y1 : A :> x featured by C; + + feature z unions f, g disjoint from y; + feature z1 intersects f,g differences y, y1, z; + + classifier Person; + + abstract feature person : Person; // Default subsets Base::things. + feature child subsets person; + + feature adult differences person, child; + + classifier Fuel; + + classifier Tanks { + feature fuelInPort { + in feature fuelFlow : Fuel; + } + feature fuelOutPort ~ fuelInPort; + } + + feature parent[1..2] : Person; + feature mother : Person[1] :> parent; + + specialization t1 typing f typed by B; + specialization t2 typing g : A; + + specialization Sub subset parent subsets person; + specialization subset mother subsets parent; + + classifier LegalRecord { + feature guardian[1]; + } + + class RegisteredAsset { + composite var feature identifier[0..1]; + } + + classifier Vehicle :> RegisteredAsset { + derived var feature vin[1] = identifier; + + var feature v : Vehicle; + binding vin = v.vin; + var feature w = v.vin; + + feature x = vin; + binding x = vin; + } + feature legalIdentification; + + specialization Redef redefinition LegalRecord::guardian redefines parent; + specialization redefinition Vehicle::vin redefines RegisteredAsset::identifier; + + redefinition Vehicle::vin redefines legalIdentification; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Filtering.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Filtering.kerml new file mode 100644 index 00000000..ad1fda6f --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Filtering.kerml @@ -0,0 +1,51 @@ +package Filtering { + private import ScalarValues::*; + + package Annotations { + metaclass ApprovalAnnotation { + approved : Boolean; + approver : String; + level : Natural; + } + } + + package DesignModel { + private import Annotations::*; + struct System { + @ApprovalAnnotation { + approved = true; + approver = "John Smith"; + level = 2; + } + } + composite feature system : System; + } + + package UpperLevelApprovals { + private import DesignModel::**; + filter (as Annotations::ApprovalAnnotation).approved and + (as Annotations::ApprovalAnnotation).level > 1; + + struct Test :> System; + } + + package UpperLevelApprovals1 { + private import Annotations::**; + private import DesignModel::**[@Structure] + [(as Annotations::ApprovalAnnotation).approved and + (as Annotations::ApprovalAnnotation).level > 1]; + + struct Test :> System; + } + + private import KerML::*; + package Meta { + private import DesignModel::*; + filter (Element::name == "System" and not Type::isAbstract) or + Feature::isComposite; + + struct Test :> System; + feature :> system; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Imports.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Imports.kerml new file mode 100644 index 00000000..5cd500d6 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Imports.kerml @@ -0,0 +1,46 @@ +package Imports { + + package P { + class A; + class B; + class C; + } + + package Q { + class A; + class D { + class E; + } + package Q1 { + class D; + class E; + private package Q1a { + class G; + } + } + package Q2 { + class F; + } + } + + package R { + public import Q::*; + } + + + package S { + public import P::*; + public import Q::**; + + class X :> A; + class Y :> D; + class Z :> F; + } + + package S1 { + public import P::*; + public import R::*; + + class X :> A; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Inheritance.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Inheritance.kerml new file mode 100644 index 00000000..2e38e8e6 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Inheritance.kerml @@ -0,0 +1,22 @@ +package Inheritance { + class A { + feature f; + } + + class B specializes A { + + } + + feature y: A { + alias x for B::f; + feature g redefines f; + } + + alias z for y::g; + + feature w subsets y; + + alias us for w::g; + + feature yy: y; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Inverses.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Inverses.kerml new file mode 100644 index 00000000..1f207348 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Inverses.kerml @@ -0,0 +1,15 @@ +package Inverses { + class A { + feature f : B inverse of B::g disjoint from h; + feature h : B; + } + + class B { + feature g : A; + } + + inverse B::g of A::f; + inverting Invert inverse B::g.f of A::h; + + feature gg : A featured by B inverse of A::f; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/MetadataTest.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/MetadataTest.kerml new file mode 100644 index 00000000..b8fb8ec4 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/MetadataTest.kerml @@ -0,0 +1,56 @@ +package MetadataTest { + private import 'User Defined Extensions'::*; + + library package 'User Defined Extensions' { + + datatype ClassificationLevel :> ScalarValues::Natural; + feature uncl[1] : ClassificationLevel = 0; + feature conf[1] : ClassificationLevel = 1; + feature secret[1] : ClassificationLevel = 2; + + metaclass Classified { + feature :>> annotatedElement : KerML::Feature; + feature classificationLevel : ClassificationLevel; + } + + metaclass Security; + } + + feature x { + metadata Classified { + classificationLevel = conf; + } + metadata : Security; + } + + feature y { + @Classified { + classificationLevel = conf; + } + @ : Security; + } + + private #Classified #Security feature z1; + abstract #Classified z2; + + feature z { + #Security #Classified metadata Classified { + classificationLevel = secret; + } + } + + class CC; + struct SS { + feature cc : CC; + } + + metaclass M :> Metaobjects::SemanticMetadata { + :>> annotatedElement : KerML::Class; + :>> baseType = if annotatedElement istype KerML::Structure ? + SS meta KerML::Type else CC meta KerML::Class; + } + + #M struct T { + feature :>> cc; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Redefinition.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Redefinition.kerml new file mode 100644 index 00000000..8da95847 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Redefinition.kerml @@ -0,0 +1,23 @@ +package Redefinition { + + classifier A { + feature f; + } + + classifier B specializes A { + feature redefines f { + feature g; + } + } + + classifier C specializes A, B { + feature subsets f { + feature redefines g; + } + } + + class X { + feature redefines startShot; + feature redefines endShot; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Scoping.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Scoping.kerml new file mode 100644 index 00000000..788548ff --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Scoping.kerml @@ -0,0 +1,40 @@ +package Scoping { + package P1 { + class A { + feature f; + } + package P2 { + class A { + feature g; + } + package P3 { + class B :> A { + feature :>> g; + } + } + } + package Objects { + class Object { + feature test1; + } + } + package '$' { + class Objects { + class Object { + feature test2; + } + } + } + package P4 { + class C :> Objects::Object { + feature :>> test1; + } + class D :> '$'::Objects::Object { + feature :>> test2; + } + class E :> $::Objects::Object { + feature :>> subobjects; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/TextualRepresentation.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/TextualRepresentation.kerml new file mode 100644 index 00000000..87b5cf31 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/TextualRepresentation.kerml @@ -0,0 +1,19 @@ +package TextualRepresentation { + private import ScalarValues::Real; + + class C { + feature x: Real; + inv x_constraint { + rep inOCL language "ocl" + /* self.x > 0.0 */ + } + } + + behavior setX { in c : C; in newX : Real; + language "alf" + /* c.x = newX; + * WriteLine("Set new x"); + */ + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Simple Tests/Types.kerml b/test-data/sysml2/official/kerml/examples/Simple Tests/Types.kerml new file mode 100644 index 00000000..49241b47 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Simple Tests/Types.kerml @@ -0,0 +1,36 @@ +package Types { + abstract type A specializes Base::Anything; + type all x specializes A, Base::things; + + // This Type has exactly one instance. + type Singleton[1] specializes Base::Anything; + + type Super specializes Base::Anything { + private package P { + type Sub specializes Super; + } + protected feature f : P::Sub; + } + + type B :> Base::Anything; + + specialization Gen subtype A specializes B; + specialization subtype x :> Base::things; + + type Original specializes Base::Anything { + in feature Input; + } + type Conjugate1 specializes Base::Anything; + type Conjugate2 specializes Base::Anything; + conjugation c1 conjugate Conjugate1 conjugates Original; + conjugation c2 conjugate Conjugate2 ~ Original; + + type Conjugate3 conjugates Original; + type Conjugate4 ~ Conjugate1; + + type C :> B disjoint from A; + + type D :> Base::Anything unions A, B; + type E :> Base::Anything intersects A, B; + type F :> Base::Anything differences A, B; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/ExtendedOccurrences.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/ExtendedOccurrences.kerml new file mode 100644 index 00000000..84cb46bb --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/ExtendedOccurrences.kerml @@ -0,0 +1,54 @@ +package ExtendedOccurrences { + class Interval; + class Moment :> Interval; + class Timeslice { + feature interval : Interval; + :>> self : Timeslice; + } + class Snapshot :> Timeslice { + feature moment :>> interval : Moment; + :>> self : Snapshot; + } + class Life :> Timeslice; + class ExtendedOccurrence :> Life { + :>> timeSlices : Timeslice [1..*]; + :>> snapshots :> timeSlices : Snapshot [1..*]; + expr at { + :>> that : Timeslice; + in interval : Interval; + return result : Timeslice; + + binding result.portionOf = that; + binding result.interval = interval; + } + + expr while { + in timeslice : Timeslice; + return result : Timeslice = at(timeslice.interval); + } + + var feature activeOccurrences :> Occurrences::occurrences { + connector : Occurrences::HappensDuring from [1] that to [1] self; + } + + var feature activeSuboccurrences :> Occurrences::occurrences { + connector : Occurrences::HappensDuring from [1] that to [1] self; + } + + // occurrences and performances are abstract package-level features. + // It would be nice to put the variable next to them, but they cannot + // be package-level, or featured by Anything. Nevertheless, since + // Occurrence is a specialization of Anything, it will have these + // features (might be worth redefining them explicitly), so the + // variables can subset them. In the case below, performances will + // contain every step in the occurrence, which is the correct domain + // for the variable. + var feature activePerformances :> Performances::performances { + connector : Occurrences::HappensDuring from [1] that to [1] self; + } + } + struct ExtendedObject :> ExtendedOccurrence { + feature self : ExtendedObject :>> Objects::Object::self, ExtendedOccurrence::self; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/Moments.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/Moments.kerml new file mode 100644 index 00000000..0838f951 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/Moments.kerml @@ -0,0 +1,39 @@ +package Moments { + private import Occurrences::Life; + private import Occurrences::Occurrence; + + class Eternity specializes Life { + // Nothing before/after or outside. + // Could be many of these, see universal below. + redefines predecessors [0]; + redefines successors [0]; + redefines outsideOfOccurrences [0]; + } + + class UniversalEternity [1] specializes Eternity { + redefines timeSlices: Period; //Includes life. + redefines snapshots : Moment; + } + + feature universalEternity : UniversalEternity [1]; + + class Period { //Includes life and snapshots. + //↓↓ With UE redef, exactly UE timeslices. + redefines timeSliceOf : UniversalEternity [1]; + } + + class all InstantOccurrence specializes Occurrence { + // Probly useful elsewhere, eg, to type snapshots. + redefines snapshots [1]; // Or startShot subsets endShot; + } // Or middleTimeslice [0]; + + class Moment specializes Period, InstantOccurrence { + //↓↓ With UE redef, exactly UE snapshots. + redefines snapshotOf : UniversalEternity [1]; } + + private import Occurrence::spaceTimeCoincidentOccurrences; + //UE portion "corresponding" to an occurrence. + feature coincidentUEPortion : Occurrence [1] subsets spaceTimeCoincidentOccurrences, + universalEternity.portions + featured by Occurrence; +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingFeaturesEnhanced.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingFeaturesEnhanced.kerml new file mode 100644 index 00000000..57c205ab --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingFeaturesEnhanced.kerml @@ -0,0 +1,145 @@ +package TimeVaryingFeaturesEnhanced { + private import ExtendedOccurrences::*; + + class CC1 :> ExtendedOccurrence { + var feature x; + //member feature x featured by CC1_snapshots { + // member feature CC1_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by CC1; + //} + + // portions are not variable + portion :>> startShot { + var feature :>> x = 0; + //member feature :>> CC1::x featured by CC1_startShot_snapshots = 0 { + // member feature CC1_startShot_snapshots :>> CC1_snapshots featured by CC1::startShot; + //} + } + + portion t :> timeSlices { + var feature y; + //member feature y featured by CC1_t_snapshots { + // member feature CC1_t_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by CC1::t; + //} + portion :>> startShot { + var feature :>> x = 0; + //member feature :>> CC1::x featured by CC1_t_startShot_snapshots = 0 { + // member feature CC1_t_startShot_snapshots :>> CC1_snapshots featured by CC1::t::startShot; + //} + var feature :>> y = 1; + //member feature :>> CC1::t::y featured by CC1_t_startShot_snapshots = 1 { + // member feature CC1_t_startShot_snapshots :>> CC1_t_snapshots featured by CC1::t::startShot; + //} + } + portion t1 :> timeSlices { + portion :>> startShot { + var feature :>> x = 2; + //member feature :>> CC1::x featured by CC1_t_t1_startShot_snapshots = 2 { + // member feature CC1_t_t1_startShot_snapshots :>> CC1_snapshots featured by CC1::t::t1::startShot; + //} + var feature :>> y = 3; + //member feature :>> CC1::t::y featured by CC1_t_t1_startShot_snapshots = 3 { + // member feature CC1_t_t1_startShot_snapshots :>> CC1_t_snapshots featured by CC1::t::t1::startShot; + //} + } + } + } + } + + private import ScalarValues::Boolean; + private import ScalarValues::Real; + + class Car :> ExtendedOccurrence { + var feature driver : Person [0..1]; + //member feature driver : Person [0..1] featured by Car_snapshots { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car; + //} + var feature speed : Real [1]; + //member feature speed : Real [1] featured by Car_snapshots { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car; + //} + + // bind the current speed to the current speed of the current driver + // var binding driver.speed = speed; + //member connector : Links::SelfLink featured by Car_snapshots { + // :>> that : Car_snapshots; + // end feature :>> thisThing references that.driver.while{interval = Car_snapshots::self}.speed; + // end feature :>> thisThing references that.driver.at{timeslices = Car_snapshots::self.moment}.speed; + // end feature :>> sameThing references that.speed; + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car; + //} + + portion operated [0..*] :> timeSlices { + var feature :>> driver [1]; + //member feature :>> Car::driver [1] featured by Car_operated_snapshots { + // member feature Car_operated_snapshots :>> Car_snapshots featured by Car::operated; + + // var feature :>> isLicensed = true; + // member feature isLicensed1 :>> Person::isLicensed featured by Car_operated_driver_snapshots = true { + // member feature Car_operated_driver_snapshots :>> Person_snapshots featured by Car::operated::driver; + // } + //} + + //portion :>> snapshots { + // public import operated; + //} + } + + var feature engine [1]; + //member feature engine [1] featured by Car_snapshots { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car; + //} + + var feature transmission [1]; + //member feature transmission [1] featured by Car_snapshots { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car; + //} + + var connector drive from engine to transmission; + //member connector drive featured by Car_snapshots from engine to transmission { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots :> engine::Car_snapshots, transmission::Car_snapshots featured by Car; + //} + + portion inOperable [0..1] :> timeSlices; + + // successions are not variable + succession first operated then inOperable; + } + + class Person :> ExtendedOccurrence { + var feature isLicensed : Boolean[0..1]; + //member feature isLicensed : Boolean[0..1] featured by Person_snapshots { + // member feature Person_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Person; + //} + var feature speed : Real[1]; + //member feature speed : Real[1] featured by Person_snapshots { + // member feature Person_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Person; + //} + } + + struct Car1 :> ExtendedObject { // May or may not be a life + var feature driver : Person [0..1]; + //member feature driver : Person [0..1] featured by Car_snapshots { + // member feature Car_snapshots :>> ExtendedOccurrences::ExtendedOccurrence::snapshots featured by Car1; + //} + + // :>> timeSlices : Car; <-- Don't do this! + + portion :>> startShot { // Not a kind of Car! + var feature :>> driver [0]; + //member feature :>> driver : Person [0] featured by Car_startShot_snapshots { + // member feature Car_startShot_snapshots :>> Car_snapshots featured by Car1::startShot; + //} + } + + succession first startShot then driven; + + portion driven :> timeSlices { + var feature :>> driver [1]; + // No conflict with multiplicity! (driven just can't be startshot) + //member feature :>> driver : Person [1] featured by Car_driven_snapshots { + // member feature Car_driven_snapshots :>> Car_snapshots featured by Car1::driven; + //} + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingSteps.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingSteps.kerml new file mode 100644 index 00000000..7e11d3fa --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/Enhancements/TimeVaryingSteps.kerml @@ -0,0 +1,55 @@ +package TimeVaryingSteps { + behavior TakePicture { + // var step merge : MergePerformance [0..1]; + member step merge : ControlPerformances::MergePerformance [0..1] featured by TakePicture_snapshots { + member feature TakePicture_snapshots :>> Occurrences::Occurrence::snapshots featured by TakePicture { + public import merge; + } + } + + // var step focus [0..1]; + member step focus [0..1] featured by TakePicture_snapshots { + member feature TakePicture_snapshots :>> Occurrences::Occurrence::snapshots featured by TakePicture { + public import focus; + } + } + + // var step shoot [0..1]; + member step shoot [0..1] featured by TakePicture_snapshots { + member feature TakePicture_snapshots :>> Occurrences::Occurrence::snapshots featured by TakePicture { + public import shoot; + } + } + + // var step decide : DecisionPerformance [0..1]; + member step decide : ControlPerformances::DecisionPerformance [0..1] featured by TakePicture_snapshots { + member feature TakePicture_snapshots :>> Occurrences::Occurrence::snapshots featured by TakePicture { + public import decide; + } + } + + succession first [0..1] startShot then [1] merge::TakePicture_snapshots.merge; + succession first [1] merge::TakePicture_snapshots.merge then [1] focus::TakePicture_snapshots.focus; + succession first [1] focus::TakePicture_snapshots.focus then shoot::TakePicture_snapshots.shoot; + succession first [1] shoot::TakePicture_snapshots.shoot then [1] decide::TakePicture_snapshots.decide; + succession first [0..1] decide::TakePicture_snapshots.decide then [0..1] merge::TakePicture_snapshots.merge; + succession first [1] decide::TakePicture_snapshots.decide then[0..1] endShot; + } + + struct Camera { + // Is always taking a picture, one at a time. + // var step takePic : TakePicture [1]; + member step takePic : TakePicture [1] featured by Camera_snapshots { + member feature Camera_snapshots :>> Occurrences::Occurrence::snapshots featured by Camera; + } + } + + struct MultiCamera { + // Can take many pictures at one time. + // var step takePics : TakePicture [0..*]; + member step takePics : TakePicture [0..*] featured by Camera_snapshots { + member feature Camera_snapshots :>> Occurrences::Occurrence::snapshots featured by Camera; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingCarDriver.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingCarDriver.kerml new file mode 100644 index 00000000..18902686 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingCarDriver.kerml @@ -0,0 +1,120 @@ +package TimeVaryingCarDriver { + private import ScalarValues::*; + + // Example model without variable features. + + struct Person0 { + feature isLicensed : Boolean [0..1]; + } + + struct Car0 { + feature driver : Person0 [0..1]; + + portion :>> startShot { + feature :>> driver [0]; + } + + succession first startShot then operated; + + portion operated [0..*] :> timeSlices { + feature :>> driver [1] { + feature :>> isLicensed = true; + } + } + + abstract feature carParts [0..*]; + feature engine [1] :> carParts; + feature transmission [1] :> carParts; + + connector drive from engine to transmission; + } + + // Example model with "variable features" identified + + struct Person1 { + var feature isLicensed : Boolean [1]; + } + + struct Car1 { + var feature driver : Person1 [0..1]; + + portion :>> startShot { + var feature :>> driver [0]; + } + + succession first startShot then operated; + + portion operated [0..*] :> timeSlices { + var feature :>> driver [1] { + var feature :>> isLicensed = true; + } + } + + abstract var feature carParts [0..*]; + var feature engine [1] :> carParts; + var feature transmission [1] :> carParts; + + var connector drive from engine to transmission; + } + + // Semantic equivalent of implied relationships for variable features in + // the previous model + + struct Person1_ { + // var feature isLicensed : Boolean [1]; + member feature isLicensed : Boolean [1] featured by Person_snapshots { + member feature Person_snapshots :>> Occurrences::Occurrence::snapshots featured by Person1_; + } + member feature name : String [1] featured by Person_snapshots { + member feature Person_snapshots :>> Occurrences::Occurrence::snapshots featured by Person1_; + } + } + + struct Car1_ { + // var feature driver : Person [0..1]; + member feature driver : Person1_ [0..1] featured by Car_snapshots { + member feature Car_snapshots :>> Occurrences::Occurrence::snapshots featured by Car1_; + } + + portion :>> startShot { + // var feature :>> driver [0]; + member feature :>> Car1_::driver [0] featured by Car_startShot_snapshots { + member feature Car_startShot_snapshots :>> Car_snapshots featured by Car1_::startShot; + } + } + + succession first startShot then operated; + + portion operated [0..*] :> timeSlices { + // var feature :>> driver [1] + member feature :>> Car1_::driver [1] featured by Car_operated_snapshots { + member feature Car_operated_snapshots :>> Car_snapshots featured by Car1_::operated; + // var feature :>> isLicensed = true; + member feature isLicensed1 :>> Person1_::isLicensed featured by Car_operated_driver_snapshots = true { + member feature Car_operated_driver_snapshots :>> Occurrences::Occurrence::snapshots featured by Car1_::operated::driver; + } + } + } + + // var abstract feature carParts [0..*]; + member abstract feature carParts [0..*] featured by Car_snapshots { + member feature Car_snapshots :>> Occurrences::Occurrence::snapshots featured by Car1_; + } + + // var feature engine [1]; + member feature engine [1] :> carParts featured by Car_snapshots1 { + member feature Car_snapshots1 :>> Occurrences::Occurrence::snapshots featured by Car1_; + } + + // var feature transmission [1]; + member feature transmission [1] :> carParts featured by Car_snapshots1 { + member feature Car_snapshots1 :>> Occurrences::Occurrence::snapshots featured by Car1_; + } + + // var connector drive from engine to transmission; + member connector drive featured by Car_snapshots from engine to transmission { + member feature Car_snapshots :>> Occurrences::Occurrence::snapshots featured by Car1_; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingFeatures.kerml b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingFeatures.kerml new file mode 100644 index 00000000..73b60aa9 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Variable Feature Examples/TimeVaryingFeatures.kerml @@ -0,0 +1,69 @@ +package TimeVaryingFeatures { + class CC0 { + var feature x; + + portion :>> startShot { + var feature :>> x = 0; + } + + portion t :> timeSlices { + var feature y; + + portion :>> startShot { + var feature :>> x = 0; + var feature :>> y = 1; + } + + portion t1 :> timeSlices { + portion :>> startShot { + var feature :>> x = 2; + var feature :>> y = 3; + } + } + } + } + + class CC1 { + // var feature x; + member feature x featured by CC1_snapshots { + member feature CC1_snapshots :>> Occurrences::Occurrence::snapshots featured by CC1; + } + + // portions are not variable + portion :>> startShot { + // var feature :>> x = 0; + member feature :>> CC1::x featured by CC1_startShot_snapshots = 0 { + member feature CC1_startShot_snapshots :>> CC1_snapshots featured by CC1::startShot; + } + } + + portion t :> timeSlices { + // var feature y; + member feature y featured by CC1_t_snapshots { + member feature CC1_t_snapshots :>> Occurrences::Occurrence::snapshots featured by CC1::t; + } + portion :>> startShot { + // var feature :>> x = 0; + member feature :>> CC1::x featured by CC1_t_startShot_snapshots = 0 { + member feature CC1_t_startShot_snapshots :>> CC1_snapshots featured by CC1::t::startShot; + } + // var feature :>> y = 1; + member feature :>> CC1::t::y featured by CC1_t_startShot_snapshots = 1 { + member feature CC1_t_startShot_snapshots :>> CC1_t_snapshots featured by CC1::t::startShot; + } + } + portion t1 :> timeSlices { + portion :>> startShot { + // var feature :>> x = 2; + member feature :>> CC1::x featured by CC1_t_t1_startShot_snapshots = 2 { + member feature CC1_t_t1_startShot_snapshots :>> CC1_snapshots featured by CC1::t::t1::startShot; + } + // var feature :>> y = 3; + member feature :>> CC1::t::y featured by CC1_t_t1_startShot_snapshots = 3 { + member feature CC1_t_t1_startShot_snapshots :>> CC1_t_snapshots featured by CC1::t::t1::startShot; + } + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleDefinitions.kerml b/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleDefinitions.kerml new file mode 100644 index 00000000..f1c84d0a --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleDefinitions.kerml @@ -0,0 +1,44 @@ +package VehicleDefinitions { + doc + /* + * Example vehicle definitions model. + */ + + + /* BLOCKS */ + + class Vehicle; + class Transmission; + class AxleAssembly; + class Axle; + class Wheel; + class Lugbolt { + tighteningTorque[1] : ScalarValues::Real; + } + + /* INTERFACE BLOCKS */ + + class DriveIF { + in driveTorque: ScalarValues::Real; + } + + class AxleMountIF { + out transferredTorque : ScalarValues::Real; + } + + class WheelHubIF { + in appliedTorque : ScalarValues::Real; + } + + /* ASSOCIATION BLOCKS */ + + assoc Mounting { + doc + /* + * mounting a Wheel to an Axle. + */ + + end axleMount: AxleMountIF; + end hub: WheelHubIF; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleUsages.kerml b/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleUsages.kerml new file mode 100644 index 00000000..1d79f474 --- /dev/null +++ b/test-data/sysml2/official/kerml/examples/Vehicle Example/VehicleUsages.kerml @@ -0,0 +1,104 @@ +package VehicleUsages { + doc + /* + * Example usages of elements from the vehicle definitions model. + */ + + private import VehicleDefinitions::*; + + /* VALUES */ + + feature T1 = 10.0; + feature T2 = 20.0; + + /* PARTS */ + + feature narrowRimWheel: Wheel { + doc /* Narrow-rim wheel configuration with 4 to 5 lugbolts. */ + composite lugbolt: Lugbolt[4..5]; + } + + feature wideRimWheel: Wheel { + doc /* Wide-rim wheel configuration with 4 to 6 lugbolts. */ + composite lugbolt: Lugbolt[4..6]; + } + + feature vehicle_C1: Vehicle { + doc /* Basic Vehicle configuration showing a part hierarchy. */ + composite frontAxleAssembly: AxleAssembly { + composite frontWheel[2] redefines narrowRimWheel { + composite lugbolt[4] redefines narrowRimWheel::lugbolt { + feature tighteningTorque redefines Lugbolt::tighteningTorque = T1; + } + } + composite frontAxle: Axle; + } + composite rearAxleAssembly: VehicleDefinitions::AxleAssembly { + composite rearWheel[2] redefines wideRimWheel { + composite lugbolt[6] redefines wideRimWheel::lugbolt { + feature tighteningTorque redefines Lugbolt::tighteningTorque = T2; + } + } + composite rearAxle: Axle; + } + } + + feature vehicle_C2 subsets vehicle_C1 { + doc /* Specialized configuration with part-specific ports. */ + composite frontAxleAssembly redefines vehicle_C1::frontAxleAssembly { + composite leftFrontWheel subsets vehicle_C1::frontAxleAssembly::frontWheel = vehicle_C1::frontAxleAssembly::frontWheel#(1) { + composite hub: VehicleDefinitions::WheelHubIF; + } + composite rightFrontWheel subsets vehicle_C1::frontAxleAssembly::frontWheel = vehicle_C1::frontAxleAssembly::frontWheel#(2) { + feature hub: VehicleDefinitions::WheelHubIF; + } + + composite frontAxle redefines vehicle_C1::frontAxleAssembly::frontAxle { + composite leftMountingPoint: AxleMountIF; + composite rightMountingPoint: AxleMountIF; + } + + connector leftFrontMount: Mounting from + frontAxle.leftMountingPoint to leftFrontWheel.hub; + + connector rightFrontMount: Mounting from + frontAxle.rightMountingPoint to rightFrontWheel.hub; + } + + composite rearAxleAssembly redefines vehicle_C1::rearAxleAssembly { + composite leftRearWheel subsets vehicle_C1::rearAxleAssembly::rearWheel = vehicle_C1::rearAxleAssembly::rearWheel#(1) { + feature hub: WheelHubIF; + } + composite rightRearWheel subsets vehicle_C1::rearAxleAssembly::rearWheel = vehicle_C1::rearAxleAssembly::rearWheel#(2) { + feature hub: WheelHubIF; + } + + composite rearAxle redefines vehicle_C1::rearAxleAssembly::rearAxle { + feature leftMountingPoint: AxleMountIF; + feature rightMountingPoint: AxleMountIF; + } + + connector leftRearMount: Mounting from + rearAxle.leftMountingPoint to leftRearWheel.hub; + + connector rightRearMount: Mounting from + rearAxle.rightMountingPoint to rightRearWheel.hub; + } + } + + feature vehicle_C3 subsets vehicle_C2 { + doc /* Further specialized configuration with a connector to a deeply-nested feature. */ + composite transmission: Transmission { + out feature drive: DriveIF; + } + + composite rearAxleAssembly redefines vehicle_C2::rearAxleAssembly { + composite rearAxle redefines vehicle_C2::rearAxleAssembly::rearAxle { + in feature drive: DriveIF; + } + } + + connector driveShaft from + transmission.drive to rearAxleAssembly.rearAxle.drive; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Analysis Examples/AnalysisAnnotation.sysml b/test-data/sysml2/official/sysml/examples/Analysis Examples/AnalysisAnnotation.sysml new file mode 100644 index 00000000..5d974866 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Analysis Examples/AnalysisAnnotation.sysml @@ -0,0 +1,26 @@ +package AnalysisAnnotation { + private import ScalarValues::Real; + private import AnalysisTooling::*; + private import ISQ::*; + + action def ComputeDynamics { + metadata ToolExecution { + toolName = "ModelCenter"; + uri = "aserv://localhost/Vehicle/Equation1"; + } + + in dt : TimeValue { @ToolVariable { name = "deltaT"; } } + in whlpwr : PowerValue { @ToolVariable { name = "power"; } } + in Cd : Real { @ToolVariable { name = "C_D"; } } + in Cf: Real { @ToolVariable { name = "C_F"; } } + in tm : MassValue { @ToolVariable { name = "mass"; } } + in v_in : SpeedValue { @ToolVariable { name = "v0"; } } + in x_in : LengthValue { @ToolVariable { name = "x0"; } } + + out a_out : AccelerationValue { @ToolVariable { name = "a"; } } + out v_out : SpeedValue { @ToolVariable { name = "v"; } } + out x_out : LengthValue { @ToolVariable { name = "x"; } } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Analysis Examples/Dynamics.sysml b/test-data/sysml2/official/sysml/examples/Analysis Examples/Dynamics.sysml new file mode 100644 index 00000000..26746dd7 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Analysis Examples/Dynamics.sysml @@ -0,0 +1,91 @@ +package Dynamics { + private import ScalarValues::Real; + private import ISQ::*; + + // Function definitions + + calc def Power { + in whlpwr : PowerValue; in Cd : Real; in Cf : Real; in tm : MassValue; in v : SpeedValue; + return tp : PowerValue = whlpwr - Cd * v - Cf * tm * v; + } + + calc def Acceleration { in dt : TimeValue; in tm : MassValue; in tp: PowerValue; + return a : AccelerationValue = tp * dt * tp; + } + + calc def Velocity { in dt : TimeValue; in v0 : SpeedValue; in a : AccelerationValue; + return v : SpeedValue = v0 + a * dt; + } + + calc def Position { in dt : TimeValue; in x0 : LengthValue; in v : SpeedValue; + return x : LengthValue = x0 + v * dt; + } + + // Analysis action def + + action def StraightLineVehicleDynamics { + + in attribute dt : TimeValue; + in attribute whlpwr : PowerValue; + in attribute Cd : Real; + in attribute Cf: Real; + in attribute tm : MassValue; + in attribute v_in : SpeedValue; + in attribute x_in : LengthValue; + + out attribute a_out : AccelerationValue; + out attribute v_out : SpeedValue; + out attribute x_out : LengthValue; + + assert constraint { + attribute tp : PowerValue; + + tp == Power(whlpwr, Cd, Cf, tm, v_in) & + a_out == Acceleration(dt, tm, tp) & + v_out == Velocity(dt, v_in, a_out) & + x_out == Position(dt, x_in, v_in) + } + } + + + // Analysis actions + + action dyn1 : StraightLineVehicleDynamics { + in attribute dt : TimeValue; + in attribute whlpwr : PowerValue; + in attribute Cd : Real; + in attribute Cf: Real; + in attribute tm : MassValue; + in attribute v_in : SpeedValue; + in attribute x_in : LengthValue; + + attribute tp : PowerValue = Power(whlpwr, Cd, Cf, tm, v_in); + + out attribute :>> a_out : AccelerationValue = Acceleration(dt, tm, tp); + out attribute :>> v_out : SpeedValue = Velocity(dt, v_in, a_out); + out attribute :>> x_out : LengthValue = Position(dt, x_in, v_in); + } + + action dyn2 : StraightLineVehicleDynamics { + calc acc : Acceleration { + in dt = dyn2::dt; + in tm = dyn2::tm; + in tp = Power(whlpwr, Cd, Cf, tm, v_in); + } + bind a_out = acc.a; + + calc vel : Velocity { + in dt = dyn2::dt; + in v0 = dyn2::v_in; + in a = acc.a; + } + bind v_out = vel.v; + + calc pos : Position { + in dt = dyn2::dt; + in x0 = dyn2::x_in; + in v0 = vel.v; + } + bind x_out = pos.x; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Analysis Examples/Turbojet Stage Analysis.sysml b/test-data/sysml2/official/sysml/examples/Analysis Examples/Turbojet Stage Analysis.sysml new file mode 100644 index 00000000..5e2991c2 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Analysis Examples/Turbojet Stage Analysis.sysml @@ -0,0 +1,110 @@ +package 'Turbojet Stage Analysis' { + private import Quantities::ScalarQuantityValue; + private import MeasurementReferences::DimensionOneValue; + private import ISQ::*; + + package 'Thermodynamic Functions' { + calc def 'Ideal Gas Law' { in rho; in R_bar; in T; + return p = rho * R_bar * T; + } + + calc def 'Reversible Adiabatic Compression Density' { in rho_1; in p_1; in p_2; in gamma; + return rho_2 = rho_1 * (p_2 / p_1)^(1/gamma); + } + + calc def 'Reversible Adiabatic Compression Temperature' { in T_1; in p_1; in p_2; in gamma; + return T_2 = T_1 * (p_2 / p_1)**((gamma - 1) / gamma); + } + + calc def 'Total Pressure' { in P_static; in rho; in V; + 1/2 * rho * V^2 + P_static + } + + // Showing explicit parameter typing + calc def 'Total Temperature' { in T_static : TemperatureValue; in Cp : DimensionOneValue; in V : VolumeValue; + return : TemperatureValue = 1/(2 * Cp) * V^2 + T_static; + } + + calc def 'Total Enthalpy' { in h_total; in h_static; in V; + return H_total = 1/2 * V^2 + h_static; + } + } + + package 'Thermodynamics Structure' { + part def 'Ideal Gas Parcel' { + comment + /* + The parcel is an infinitesimal volume used to analyze points in a flow + */ + attribute 'Molar Mass'; + attribute 'Density'; + attribute 'Pressure'; + attribute 'Temperature'; + attribute 'Enthalpy'; + attribute 'Specific Gas Constant'; + } + + part def 'Moving Ideal Gas Parcel' specializes 'Ideal Gas Parcel' { + comment about 'Stagnation Pressure' + /* + Stagnation pressure is the pressure of the parcel if the kinetic energy defined by its + velocity in a given coordinate frame is converted to gas internal energy through deceleration + to a velocity that matches the current frame. + */ + attribute 'Stagnation Pressure'; + attribute 'Stagnation Temperature'; + attribute 'Stagnation Enthalpy'; + + comment about 'Static Pressure' + /* + Static pressure is the pressure of the parcel as it moves + */ + attribute 'Static Pressure' redefines 'Ideal Gas Parcel'::'Pressure'; + attribute 'Static Temperature' redefines 'Ideal Gas Parcel'::'Temperature'; + attribute 'Static Enthalpy' redefines 'Ideal Gas Parcel'::'Enthalpy'; + } + + action def 'Thermodynamic Process'; // need start and end shots to show beginning and end attributes + + action def 'Adiabatic Process' specializes 'Thermodynamic Process' { + /* + Thermodynamic process typically have their states defined at beginning and end + of the process (since these starts are path-independent) + */ + action 'Stage 1' :>> start; + action 'Stage 2' :>> done; + } + + action def 'Reversible Adiabatic Process' specializes 'Adiabatic Process'; + } + + package 'Low-Pressure Compressor Analysis' { + + part 'Analysis Context' { + private import 'Thermodynamic Functions'::*; + + part 'Inlet Gas' : 'Thermodynamics Structure'::'Moving Ideal Gas Parcel' { + // Explicit binding notation + calc 'Solve for Pressure1' : 'Ideal Gas Law'; + bind 'Density' = 'Solve for Pressure1'.rho; + bind 'Specific Gas Constant' = 'Solve for Pressure1'.R_bar; + bind 'Static Temperature' = 'Solve for Pressure1'.T; + bind 'Static Pressure' = 'Solve for Pressure1'.p; + + // Shorthand parameter binding notation + calc 'Solve for Pressure2' : 'Ideal Gas Law' { + in rho = 'Density'; + in R_bar = 'Specific Gas Constant'; + in T = 'Static Temperature'; + } + + // Invocation expression notation + attribute :>> 'Static Pressure' = 'Ideal Gas Law'('Density', 'Specific Gas Constant', 'Static Temperature'); + + // Equation as a constraint (note "==") + constraint { 'Static Pressure' == 'Ideal Gas Law'('Density', 'Specific Gas Constant', 'Static Temperature') } + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Analysis Examples/Vehicle Analysis Demo.sysml b/test-data/sysml2/official/sysml/examples/Analysis Examples/Vehicle Analysis Demo.sysml new file mode 100644 index 00000000..1310f62a --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Analysis Examples/Vehicle Analysis Demo.sysml @@ -0,0 +1,286 @@ +package 'Vehicle Analysis Demo' { + private import ScalarValues::*; + private import ISQ::*; + private import USCustomaryUnits::*; + + private import VehicleQuantities::*; + private import VehicleModel::*; + private import FuelEconomyRequirementsModel::*; + private import DynamicsModel::*; + private import FuelEconomyAnalysisModel::*; + + package VehicleQuantities { + private import Quantities::*; + private import MeasurementReferences::*; + + attribute def DistancePerVolumeUnit :> DerivedUnit { + private attribute distancePF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = 1; } + private attribute volumePF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = -3; } + attribute :>> quantityDimension { :>> quantityPowerFactors = (distancePF, volumePF); } + } + + attribute def DistancePerVolumeValue :> ScalarQuantityValue { + :>> num : Real; + :>> mRef : DistancePerVolumeUnit; + } + + attribute gallon : VolumeUnit = 231.0 * 'in' ** 3; + attribute mpg : DistancePerVolumeUnit = 'mi' / gallon; + } + + package VehicleModel { + item def Fuel; + + port def FuelPort { + out item fuel: Fuel; + } + + part def FuelTank { + attribute volumeMax : VolumeValue; + attribute fuelVolume : VolumeValue; + attribute fuelLevel : Real = fuelVolume / volumeMax; + + port fuelInPort : ~FuelPort; + port fuelOutPort : FuelPort; + } + + part def Wheel { + attribute diameter : LengthValue; + } + + part def Vehicle { + attribute mass : MassValue; + attribute cargoMass : MassValue; + + attribute wheelDiameter : LengthValue; + attribute driveTrainEfficiency : Real; + + attribute fuelEconomy_city : DistancePerVolumeValue; + attribute fuelEconomy_highway : DistancePerVolumeValue; + + port fuelInPort : ~FuelPort; + } + + part vehicle_c1 : Vehicle { + port :>> fuelInPort { + in item :>> fuel; + } + + part fuelTank : FuelTank { + port :>> fuelInPort { + in item :>> fuel; + } + } + + bind fuelInPort.fuel = fuelTank.fuelInPort.fuel; + + part wheel : Wheel[4] { + :>> diameter = wheelDiameter; + } + } + } + + package FuelEconomyRequirementsModel { + requirement def FuelEconomyRequirement { + attribute actualFuelEconomy : DistancePerVolumeValue; + attribute requiredFuelEconomy : DistancePerVolumeValue; + + require constraint { actualFuelEconomy >= requiredFuelEconomy } + } + + requirement cityFuelEconomyRequirement : FuelEconomyRequirement { + :>> requiredFuelEconomy = 25 [mpg]; + } + + requirement highwayFuelEconomyRequirement : FuelEconomyRequirement { + :>> requiredFuelEconomy = 30 [mpg]; + } + } + + package DynamicsModel { + calc def Acceleration { in p : PowerValue; in m : MassValue; in v : SpeedValue; + return : AccelerationValue = p / (m * v); + } + + calc def Velocity { in v0 : SpeedValue; in a : AccelerationValue; in dt : TimeValue; + return : SpeedValue = v0 + a * dt; + } + + calc def Position { in x0 : LengthValue; in v : SpeedValue; in dt : TimeValue; + return : LengthValue = x0 + v * dt; + } + + constraint def StraightLineDynamicsEquations { + in p : PowerValue; + in m : MassValue; + in dt : TimeValue; + in x_i : LengthValue; + in v_i : SpeedValue; + in x_f : LengthValue; + in v_f : SpeedValue; + in a : AccelerationValue; + + attribute v_avg : SpeedValue = (v_i + v_f)/2; + + a == Acceleration(p, m, v_avg) & + v_f == Velocity(v_i, a, dt) & + x_f == Position(x_i, v_avg, dt) + } + + action def StraightLineDynamics { + in power : PowerValue; + in mass : MassValue; + in delta_t : TimeValue; + in x_in : LengthValue; + in v_in : SpeedValue; + out x_out : LengthValue; + out v_out : SpeedValue; + out a_out : AccelerationValue; + + assert constraint dynamics : StraightLineDynamicsEquations { + in p = power; + in m = mass; + in dt = delta_t; + in x_i = x_in; + in v_i = v_in; + in x_f = x_out; + in v_f = v_out; + in a = a_out; + } + } + } + + package FuelEconomyAnalysisModel { + private import SequenceFunctions::size; + private import SampledFunctions::SampledFunction; + private import SampledFunctions::SamplePair; + private import ControlFunctions::forAll; + + attribute def ScenarioState { + position : LengthValue; + velocity : SpeedValue; + } + + attribute def NominalScenario :> SampledFunction { + attribute def TimeStateRecord :> SamplePair { + t : TimeValue :>> domainValue; + s : ScenarioState :>> rangeValue; + } + :>> samples : TimeStateRecord; + n : Natural = size(samples); + } + + analysis def FuelEconomyAnalysis { + subject vehicle: Vehicle; + in attribute scenario : NominalScenario; + in requirement fuelEconomyRequirement : FuelEconomyRequirement; + return calculatedFuelEconomy : DistancePerVolumeValue; + + objective fuelEconomyAnalysisObjective { + doc + /* + * The objective of this analysis is to determine whether the + * current vehicle design configuration can satisfy the fuel + * economy requirement. + */ + + assume constraint { + vehicle.wheelDiameter == 33 ['in'] & + vehicle.driveTrainEfficiency == 0.4 + } + + require fuelEconomyRequirement { + :>> actualFuelEconomy = calculatedFuelEconomy; + } + } + + action dynamicsAnalysis { + in sc: NominalScenario; + out power : PowerValue[*]; + out acceleration : AccelerationValue[*]; + /* + * Solve for the required engine power as a function of time + * to support the scenarios. + */ + assert constraint straightLineDynamics { + (1..sc.n-1)->forAll {in i: Integer; + private thisSample : NominalScenario::TimeStateRecord = + sc.samples#(i); + private nextSample : NominalScenario::TimeStateRecord = + sc.samples#(i+1); + StraightLineDynamicsEquations ( + p = power#(i), + m = vehicle.mass, + dt = nextSample.t - thisSample.t, + x_i = thisSample.s.position, + v_i = thisSample.s.velocity, + x_f = nextSample.s.position, + v_f = nextSample.s.velocity, + a = acceleration#(i) + ) + } + } + } + + action fuelConsumptionAnalysis { + in power : PowerValue[*] = dynamicsAnalysis.power; + in acceleration : AccelerationValue[*] = dynamicsAnalysis.acceleration; + out fuelEconomy : DistancePerVolumeValue = calculatedFuelEconomy; + /* + * Solve the engine equations to determine how much fuel is + * consumed. The engine RPM is a function of the speed of the + * vehicle and the gear state. + */ + } + } + } + + part vehicleFuelEconomyAnalysisContext { + requirement vehicleFuelEconomyRequirementsGroup { + subject vehicle : Vehicle; + + requirement vehicleFuelEconomyRequirement_city :> cityFuelEconomyRequirement { + doc /* The vehicle shall provide a fuel economy that is greater than or equal to + * 25 miles per gallon for the nominal city driving scenarios. + */ + + :>> actualFuelEconomy = vehicle.fuelEconomy_city; + + assume constraint { vehicle.cargoMass == 1000 [lb] } + } + + requirement vehicleFuelEconomyRequirement_highway :> highwayFuelEconomyRequirement { + doc /* The vehicle shall provide a fuel economy that is greater than or equal to + * 30 miles per gallon for the nominal highway driving scenarios. + */ + + :>> actualFuelEconomy = vehicle.fuelEconomy_highway; + + assume constraint { vehicle.cargoMass == 1000 [lb] } + } + + } + + attribute cityScenario : NominalScenario; + attribute highwayScenario : NominalScenario; + + analysis cityFuelEconomyAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle_c1; + in attribute scenario = cityScenario; + in requirement fuelEconomyRequirement = cityFuelEconomyRequirement; + } + + analysis highwayFuelEconomyAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle_c1; + in attribute scenario = highwayScenario; + in requirement fuelEconomyRequirement = highwayFuelEconomyRequirement; + } + + part vehicle_c1_analysized :> vehicle_c1 { + attribute :>> fuelEconomy_city = cityFuelEconomyAnalysis.calculatedFuelEconomy; + attribute :>> fuelEconomy_highway = highwayFuelEconomyAnalysis.calculatedFuelEconomy; + } + + satisfy vehicleFuelEconomyRequirementsGroup by vehicle_c1_analysized; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFCoreLib.sysml b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFCoreLib.sysml new file mode 100644 index 00000000..1c7d1d65 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFCoreLib.sysml @@ -0,0 +1,55 @@ +// /** Mandatory Services and Systems */ +library package AHFCoreLib { + private import AHFProfileLib::*; + private import ScalarValues::*; + private import AHFProfileMetadata::*; + + #service port def ServiceDiscovery { + // The functionalities as Requests (Operations) cannot be defined yet + // We could consider using flows to designate the functionalities + } + + #service port def ServiceDiscoveryDD :> ServiceDiscovery{ + } + + #service port def Authorisation { + attribute publickey:String; // just as examples + } + + #service port def AuthorisationDD :> Authorisation{ + } + + + #clouddd ArrowheadCore{ + // /** Design Level */ + // First the system definitions (SysD) of core systems + + #system service_registry { + #service serviceDiscovery : ServiceDiscovery ; + } + + #system authorization{ + #service authorisation : Authorisation; + attribute protocol:String = "HTTP"; + } + + #system orchestrationDesign; // just indicated for now + + // /** Design Description level */ + #systemdd service_registry_DD :> service_registry{ + #servicedd :>> serviceDiscovery:ServiceDiscoveryDD { + #idd serviceDiscovery_HTTP ;// nested port for HTTP protocol + // here we refer the functionalities like operation Register etc. + #idd serviceDiscovery_MQTT ; // nested port for MQTT protocol + } + } + + #systemdd authorization_DD :> authorization{ + #servicedd :>> authorisation { + #idd authorisation_HTTP ; // nested port for HTTP protocol + #idd authorisation_MQTT ; // nested port for MQTT protocol + } + action Echo_behavior :> ServiceMethod; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFNorwayTopics.sysml b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFNorwayTopics.sysml new file mode 100644 index 00000000..5f370c5a --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFNorwayTopics.sysml @@ -0,0 +1,160 @@ +package AHFNorway { + doc /* This is the Norwegian use-case for Arrowhead Framework */ + // The use-case is for Productive4.0 and Arrowhead Tools + // The system is taken from a chemical factory + // This is focusing on the monitoring of products when delivered + private import AHFProfileLib::*; + private import AHFProfileMetadata::*; + private import AHFCoreLib::**; + private import ScalarValues::*; + + #service def APISService { + doc /* Service design */ + + attribute :>> serviceDefinition = "APISPullService"; + attribute :>> intrfce_protocol = "{JSON}"; + attribute :>> serviceURL = "pull"; + } + + #servicedd port def APIS_DD :> APISService { + doc /* Service design description with nested protocol-specific ports */ + + #idd port APIS_HTTP { + // the asynch implementation of synchronous remote calls + out cll:CallGiveItems; + in retrn:ResultGiveItems; + } + + #idd port APIS_MQTT { + // GetAllItems functionality + out pub:Publish; + out retall:Return_AllItems; + in subscr:Subscribe; + } + } + + // Asynchronous signals + attribute def Publish {nametopic:String;} + attribute def Subscribe{nametopic:String;} + attribute def Return_AllItems {itms:String;} + attribute def Subscribe_giveItems{itms:String;} + attribute def Return_Ack{ack:Boolean;} + + // Signals for implementing the remote procedure call by asynch signals + attribute def CallGiveItems{itms:String; } + attribute def ResultGiveItems{ack:Boolean;} + + #clouddd AHFNorway_LocalCloudDD :> ArrowheadCore { + #systemdd TellUConsumer { + #servicedd serviceDiscovery:~ServiceDiscoveryDD ; // communicating with ServiceRegistry + #servicedd apisp:APIS_DD ; + + attribute :>> systemname = "UngerApisClient"; + attribute :>> address = "Unger_network_ip"; + attribute :>> portno = 0; + + // We want an operation call to GiveItems, and actually sending the payload + // Call apisp::APIS_HTTP::giveItems(in allitems: String = "All the items", out ackback:Boolean); + + state TellUbehavior{ + entry send new CallGiveItems("All the items") via apisp.APIS_HTTP; + then Wait; + state Wait; + accept rs:ResultGiveItems + // Here do whatever about the result rs.ret + then Wait; + } + + } + + #systemdd APISProducer { + #servicedd serviceDiscovery:~ServiceDiscoveryDD ; // communicating with ServiceRegistry + #servicedd tellu:~APIS_DD; // providing the APISService + #servicedd apisc:APIS_DD ; // talking to APISConsumer + + :>> systemname = "PrediktorApisServer"; + :>> address = "Prediktor_network_ip"; + :>> portno = 6565; + attribute x:Boolean; + + action giveItems :> ServiceMethod + { in itms:String; out ack:Boolean; + /* Forward itms and return an ack */ + first start; + then send new Return_AllItems(itms) via apisc.APIS_MQTT; + success = true; + bind ack = success; + } + + state APISPbehavior{ + entry send new Publish("Return_AllItems") via apisc.APIS_MQTT; + then WaitOnData; + + state WaitOnData; + accept cl:CallGiveItems via tellu.APIS_HTTP + do action { + first start; + then action giveItems{ in itms=cl.itms; out ack=x; } + then send new ResultGiveItems(x) via tellu.APIS_HTTP; + } + then WaitOnData; + } + } + + #systemdd APISConsumer { + #servicedd serviceDiscovery:~ServiceDiscovery ; // communicating with ServiceRegistry + #servicedd apisp:~APIS_DD ; + :>> systemname = "TellUClient"; + :>> address = "Prediktor_network_ip"; + :>> portno = 1; + + // Now sending signal to the remote behavior through the port functionality + state MQTT_APISP { + entry send new Subscribe("Return_AllItems") via apisp.APIS_MQTT; + then Idle; + state Idle; + accept Return_AllItems via apisp.APIS_MQTT + // Get the stuff and do something with them + then Idle; + } + } + + part MQTTServer { + port getTopic:~APIS_DD; + port giveTopic:APIS_DD; + + state Serve{ + entry; + then Publ; + state Publ; + accept pub:Publish via getTopic.APIS_MQTT + // store information about who will provide "Publish::nametopic" + then Subsr; + + state Subsr; + accept Subscribe via giveTopic.APIS_MQTT + // store information about who want to receive "Subscribe::nametopic" + then Idle; + + state Idle; + accept retrnall:Return_AllItems via getTopic.APIS_MQTT + do send retrnall via giveTopic.APIS_MQTT + then Idle; + } + } + + connect APISProducer.apisc to MQTTServer.getTopic; + connect MQTTServer.giveTopic to APISConsumer.apisp; + + connect TellUConsumer.apisp to APISProducer.tellu; + + // Then we need to connect the application systems to the mandatory systems + connect APISProducer.serviceDiscovery to service_registry.serviceDiscovery; + connect TellUConsumer.serviceDiscovery to service_registry.serviceDiscovery; + connect APISConsumer.serviceDiscovery to service_registry.serviceDiscovery; + + // Same procedure for the other mandatory services + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFProfileLib.sysml b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFProfileLib.sysml new file mode 100644 index 00000000..e723d58d --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFProfileLib.sysml @@ -0,0 +1,117 @@ +library package AHFProfileLib { + // Systems and Services and their functionalities + private import ScalarValues::*; + + // Design level + port def SD{ + doc /* Service definition */ + + attribute serviceDefinition:String; + attribute serviceURL:String; + attribute intrfce_protocol:String; // which may be "REST" or "MQTT" etc. + } + + part def SysLocalCloudsDesign { + doc /* System of Systems Definition */ + + // System of Local Clouds + part locclouds:LocalCloudDesign[1..*]; + } + + part system_of_systems:SysLocalCloudsDD; // defining a top level usage + + part def LocalCloudDesign { + doc /* Local Cloud definition */ + + part systems:SysD[1..*]; + } + + part def SysD { + doc /* System definitions */ + + port services: SD[1..*]; + attribute systemname: String; + attribute address: String; + attribute portno: Integer; + } + + // Design Description level + port def IDD :> SD{ + doc /* Interface Design Description of services */ + + attribute encoding_kind:String; + } + + port def SDDD :> SD{ + doc /* Service Definition Design Description */ + + port idds:IDD[*]; // nested protocol-specific services + } + + part def SysLocalCloudsDD :> SysLocalCloudsDesign { + doc /* System of Systems Detailed Description */ + + part :>> locclouds:LocalCloudDD[1..*]; // the descriptions + } + + part def LocalCloudDD :> LocalCloudDesign { + part :>> systems:SysDD[1..*]; + } + + part def SysDD :> SysD{ + doc /* System Detailed Description */ + + port :>> services:SDDD; + action ServiceMethod[1..*]; //means general behaviors + } +} + +library package AHFProfileMetadata{ + private import Metaobjects::SemanticMetadata; + private import AHFProfileLib::*; + + port global_sd:SD; + metadata def SDMetadata :> SemanticMetadata{ + // :>> baseType = system_of_systems.locclouds.systems.services meta SysML::PortUsage; + // :>> baseType = SysD::services meta SysML::PortUsage; + :>> baseType default global_sd meta SysML::PortUsage; + } + + metadata def SysLocalCloudsMetadata :> SemanticMetadata{ + :>> baseType = system_of_systems meta SysML::PartUsage; + } + + metadata def LocalCloudsMetadata :> SemanticMetadata{ + :>> baseType default system_of_systems::locclouds meta SysML::PartUsage; + } + + metadata def SysDMetadata :> SemanticMetadata{ + :>> baseType default system_of_systems::locclouds::systems meta SysML::PartUsage; + // :>> baseType default LocalCloudDesign::systems meta SysML::PartUsage; + } + + metadata def IDDMetadata :> SDMetadata{ + // :>> baseType = system_of_systems.locclouds.systems.services.idd meta SysML::PortUsage; + :>> baseType = SDDD::idds meta SysML::PortUsage; + // :>> global_sddd.idd; + } + + port global_sddd:SDDD; + metadata def SDDDMetadata :> SDMetadata { + // :>> baseType = system_of_systems.locclouds.systems.services meta SysML::PortUsage; + :>> baseType = global_sddd meta SysML::PortUsage; + } + + metadata def LocalCloudsDDMetadata :> LocalCloudsMetadata{ + :>> baseType = system_of_systems::locclouds meta SysML::PartUsage; + } + + part global_clouddd:LocalCloudDD; + part global_systemsdd:SysDD; + metadata def SysDDMetadata :> SysDMetadata{ + // :>> baseType = system_of_systems.locclouds.systems meta SysML::PartUsage; + //:>> baseType = LocalCloudDD::systems meta SysML::PartUsage; + :>> baseType = global_systemsdd meta SysML::PartUsage; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFSequences.sysml b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFSequences.sysml new file mode 100644 index 00000000..f240e8c9 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Arrowhead Framework Example/AHFSequences.sysml @@ -0,0 +1,122 @@ +// ** This is the Norwegian use-case for Arrowhead Framework */ +package AHFNorwaySequences { + // Here we show sequences of the Norwegian use-case + private import AHFProfileLib::*; + private import AHFCoreLib::*; + private import AHFNorway::*; + private import ScalarValues::*; + + part AHFN_LocalCloudDD_Seqs = AHFNorway_LocalCloudDD{ + occurrence def APIS_transfer_lifetime { + // lifetime orderings + ref part tlc = AHFNorway_LocalCloudDD.TellUConsumer{ + event occurrence call_getItems1; + then event occurrence return_getItems1; + event occurrence call_getItems2; + then event occurrence return_getItems2; + } + ref part apsp = AHFNorway_LocalCloudDD.APISProducer{ + event occurrence send_publish_returnallitems; + then event occurrence receive_call_getItems1; + then event occurrence send_returnallitems1; + then event occurrence return_getItems_ack1; + then event occurrence receive_call_getItems2; + then event occurrence send_returnallitems2; + then event occurrence return_getItems_ack2; + } + ref part mqtts = AHFNorway_LocalCloudDD.MQTTServer{ + event occurrence receive_publish_returnallitems; + then event occurrence receive_subscribe_returnallitems; + then event forw1:MQTTforwarding; + then event forw2:MQTTforwarding; + } + ref part apsc = AHFNorway_LocalCloudDD.APISConsumer{ + event occurrence send_subscribe_returnallitems; + then event forw1:MQTTforwarding; + then event forw2:MQTTforwarding; + } + occurrence forw1:MQTTforwarding; + occurrence forw2:MQTTforwarding; + + message publish_returnallitems of Publish + from apsp.send_publish_returnallitems to mqtts.receive_publish_returnallitems; + message subscribe_returnallitems of Subscribe + from apsc.send_subscribe_returnallitems to mqtts.receive_subscribe_returnallitems; + message call_getItems1 of CallGiveItems[1] + from tlc.call_getItems1 to apsp.receive_call_getItems1; + bind apsp.send_returnallitems1 = forw1.mq; // binding the sending to the actual gate + /* How to express that this event sends a Return_AllItems? */ + message returnack1 of ResultGiveItems + from apsp.return_getItems_ack1 to tlc.return_getItems1; + message call_getItems2 of CallGiveItems[1] + from tlc.call_getItems2 to apsp.receive_call_getItems2; + bind apsp.send_returnallitems2 = forw2.mq; // binding the sending to the actual gate + message returnack2 of ResultGiveItems + from apsp.return_getItems_ack2 to tlc.return_getItems2; + } + + occurrence def MQTTforwarding { + ref part mqttsf = AHFNorway_LocalCloudDD.MQTTServer{ + event occurrence receive_returnallitems; + then event occurrence send_returnallitems; + } + + ref part apscf :> AHFNorway_LocalCloudDD.APISConsumer { + event occurrence receive_returnallitems; + } + + in event occurrence mq; // parameter for gate + + message sendallitems1 of Return_AllItems + from mq to mqttsf.receive_returnallitems; + message sendallitems2 of Return_AllItems + from mqttsf.send_returnallitems to apscf.receive_returnallitems; + } + + + interface APIS_transfer_interface : Interfaces::Interface connect ( + tlu ::> AHFNorway_LocalCloudDD.TellUConsumer.apisp.APIS_HTTP, // port reference + apsph ::> AHFNorway_LocalCloudDD.APISProducer.tellu.APIS_HTTP, + apspm ::> AHFNorway_LocalCloudDD.APISProducer.apisc.APIS_MQTT, + apsc ::> AHFNorway_LocalCloudDD.APISConsumer.apisp.APIS_MQTT, + mqget ::> AHFNorway_LocalCloudDD.MQTTServer.getTopic, + mqgive ::> AHFNorway_LocalCloudDD.MQTTServer.giveTopic) { + + flow publish_returnallitems of Publish + from apspm.pub to mqget.APIS_MQTT.pub; + flow subscribe_returnallitems of Subscribe + from apsc.subscr to mqgive.APIS_MQTT.subscr; + flow call_getItems of CallGiveItems[1] + from tlu.cll to apsph.cll; + flow returnallitems of Return_AllItems + from apspm.retall to mqget.APIS_MQTT.retall; + flow sendallitems of Return_AllItems + from mqgive.APIS_MQTT.retall to apsc.retall; + flow returnack of ResultGiveItems + from apsph.retrn to tlu.retrn; + + // Successions on each lifetime + // tlu + succession first call_getItems.start + then returnack.done; + // apisp (taking both ports) + succession first publish_returnallitems.start + then call_getItems.done; + succession first call_getItems.done + then returnallitems.start; + succession first returnallitems.start + then returnack.start; + // MQTTServer + succession first publish_returnallitems.done + then subscribe_returnallitems.done; + succession first subscribe_returnallitems + then returnallitems.done; + succession first returnallitems.done + then sendallitems.start; + // apisc + succession first subscribe_returnallitems.start + then sendallitems.done; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_N_ary.sysml b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_N_ary.sysml new file mode 100644 index 00000000..4f38b4e3 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_N_ary.sysml @@ -0,0 +1,21 @@ +package ProductSelection_N_ary_SysML { + + item def ShoppingCart; + item def Product; + item def Account; + + // User-specified connection defiation definition + connection def ProductSelection { + end [0..1] item cart: ShoppingCart[1]; + end [0..*] item selectedProduct: Product[1]; + end [1..1] item account : Account[1]; + } + + // Equivalent connection defiation definition with named end items. + connection def ProductSelection1 { + end inCart[0..1] item cart: ShoppingCart[1]; + end selectedProducts[0..*] item selectedProduct: Product[1]; + end withAccount[1..1] item account : Account[1]; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_OwnedEnds.sysml b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_OwnedEnds.sysml new file mode 100644 index 00000000..a4eab6ed --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_OwnedEnds.sysml @@ -0,0 +1,47 @@ +package ProductSelection_OwnedEnds_SysML { + + item def SelectionInfo; + item def ShoppingCart; + item def Product; + + // User-specified connection defiation definition + connection def ProductSelection { + item info: SelectionInfo; + + end [0..1] item cart: ShoppingCart[1]; + end [0..*] nonunique item selectedProduct: Product[1]; + } + + // Equivalent connection defiation definition with named end items. + connection def ProductSelection1 { + item info: SelectionInfo; + + end inCart[0..1] item cart: ShoppingCart[1]; + end selectedProducts[0..*] item selectedProduct: Product[1]; + } + + connection def SingleProductSelection specializes ProductSelection { + end [0..1] item cart: ShoppingCart[1]; + end [0..1] item selectedProduct: Product[1]; + } + + connection def SingleProductSelection1 specializes ProductSelection1 { + end inCart1 [0..1] item cart: ShoppingCart[1]; + end selectedProduct1 [0..1] item selectedProduct: Product[1]; + } + + item def OnlineCustomer { + item info1: SelectionInfo; + item myCart: ShoppingCart[1]; + item products: Product[0..*]; + + connection ps1 : ProductSelection connect myCart to products { + :>> info = info1; + } + + connection ps2 : ProductSelection connect [1] myCart to [1] products { + :>> info = info1; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_UnownedEnds.sysml b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_UnownedEnds.sysml new file mode 100644 index 00000000..14e7d211 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Association Examples/ProductSelection_UnownedEnds.sysml @@ -0,0 +1,37 @@ +package ProductSelection_UnownedEnds_SysML { + + item def SelectionInfo; + item def ShoppingCart { + item selectedProducts : Product[0..*]; + } + item def Product { + item inCart: ShoppingCart[0..1]; + } + + connection def ProductSelection { + item info: SelectionInfo[1]; + + end item cart: ShoppingCart[1] crosses selectedProduct.inCart; + end item selectedProduct: Product[1] crosses cart.selectedProducts; + } + + connection def SingleProductSelection :> ProductSelection { + end item cart: ShoppingCart[1]; + end [0..1] item selectedProduct: Product[1]; + } + + item def OnlineCustomer { + item info1: SelectionInfo; + item myCart: ShoppingCart[1]; + item products: Product[0..*]; + + connection ps1 : ProductSelection connect myCart to products { + :>> info = info1; + } + + connection ps2 : ProductSelection connect [1] myCart to [1] products { + :>> info = info1; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Camera Example/Camera.sysml b/test-data/sysml2/official/sysml/examples/Camera Example/Camera.sysml new file mode 100644 index 00000000..28d9fd1f --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Camera Example/Camera.sysml @@ -0,0 +1,14 @@ +part def Camera { + private import PictureTaking::*; + + perform action takePicture[*] :> PictureTaking::takePicture; + + part focusingSubsystem { + perform takePicture.focus; + } + + part imagingSubsystem { + perform takePicture.shoot; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Camera Example/PictureTaking.sysml b/test-data/sysml2/official/sysml/examples/Camera Example/PictureTaking.sysml new file mode 100644 index 00000000..3994a3a7 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Camera Example/PictureTaking.sysml @@ -0,0 +1,12 @@ +package PictureTaking { + part def Exposure; + + action def Focus { out xrsl: Exposure; } + action def Shoot { in xsf: Exposure; } + + action takePicture { + action focus: Focus[1]; + flow of Exposure from focus.xrsl to shoot.xsf; + action shoot: Shoot[1]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/CauseAndEffectExample.sysml b/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/CauseAndEffectExample.sysml new file mode 100644 index 00000000..0cc238de --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/CauseAndEffectExample.sysml @@ -0,0 +1,55 @@ +package CauseAndEffectExample { + private import CauseAndEffect::*; + + part def Causer1; + part def Causer2; + part def Effected1; + part def Effected2; + + #multicausation connection def MultiCauseEffect { + end #cause cause1 : Causer1; + end #cause cause2 : Causer2; + end #effect effect1 : Effected1; + end #effect effect2 : Effected2; + } + + part causer1 : Causer1; + part causer2 : Causer2; + part effected1 : Effected1; + part effected2 : Effected2; + + #multicausation connection : MultiCauseEffect connect + ( cause1 ::> causer1, cause2 ::> causer2, + effect1 ::> effected1, effect2 ::> effected2 ); + + #multicausation connect + ( cause1 ::> causer1, cause2 ::> causer2, + effect1 ::> effected1, effect2 ::> effected2 ); + + occurrence a; + item b; + part c; + action d; + + #multicausation connection { + end #cause ::> a; + end #cause ::> b; + end #effect ::> c; + end #effect ::> d; + } + + #cause causeA ::> a; + #cause causeB ::> b; + #effect effectC ::> c; + #effect effectD ::> d; + + #multicausation connect ( causeA, causeB, effectC, effectD ); + + #causation connect a to c; + #causation connect b to d { + @CausationMetadata { + isNecessary = true; + probability = 0.1; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/MedicalDeviceFailure.sysml b/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/MedicalDeviceFailure.sysml new file mode 100644 index 00000000..75626e65 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Cause and Effect Examples/MedicalDeviceFailure.sysml @@ -0,0 +1,25 @@ +package MedicalDeviceFailure { + private import CauseAndEffect::*; + + part medicalDevice { + part battery { + event occurrence depleted; + event occurrence cannotBeCharged; + } + + event occurrence deviceFails; + + ref patient { + event occurrence therapyDelayed; + } + + #multicausation connection { + end #cause ::> battery.depleted; + end #cause ::> battery.cannotBeCharged; + end #effect ::> deviceFails; + } + + #causation connect deviceFails to patient.therapyDelayed; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Comment Examples/Comments.sysml b/test-data/sysml2/official/sysml/examples/Comment Examples/Comments.sysml new file mode 100644 index 00000000..324319d8 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Comment Examples/Comments.sysml @@ -0,0 +1,15 @@ +package Comments { + doc /* Documentation Comment */ + + doc /* Documentation about Package */ + + comment cmt /* Named Comment */ + comment cmt_cmt about cmt /* Comment about Comment */ + + comment about C /* Documention Comment on Part Def */ + part def C { + doc /* Documentation in Part Def */ + comment /* Comment in Part Def */ + comment about Comments /* Comment about Package */ + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Flashlight Example/Flashlight Example.sysml b/test-data/sysml2/official/sysml/examples/Flashlight Example/Flashlight Example.sysml new file mode 100644 index 00000000..07c48aab --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Flashlight Example/Flashlight Example.sysml @@ -0,0 +1,59 @@ +package 'Flashlight Example' { + + attribute def OnOffCmd; + attribute def Light; + + port def OnOffCmdPort { + out onOffCmd : OnOffCmd; + } + + port def LightPort { + out light: Light; + } + + part context { + part user { + port onOffCmdPort: OnOffCmdPort; + perform illuminateRegion.sendOnOffCmd { + out onOffCmd = onOffCmdPort.onOffCmd; + } + } + + interface userToFlashlight connect user.onOffCmdPort to flashlight.onOffCmdPort { + perform illuminateRegion.onOffCmdFlow; + } + + part flashlight { + port onOffCmdPort: ~OnOffCmdPort; + + perform illuminateRegion.produceDirectedLight { + in onOffCmd = onOffCmdPort.onOffCmd; + out light = lightPort.light; + } + + port lightPort: LightPort ; + } + part reflectingSource { + port lightPort: ~LightPort; + + perform illuminateRegion.reflectLight { + in light = lightPort.light; + } + } + } + + action illuminateRegion { + action sendOnOffCmd { out onOffCmd: OnOffCmd; } + + succession flow onOffCmdFlow from sendOnOffCmd.onOffCmd to produceDirectedLight.onOffCmd; + + action produceDirectedLight { in onOffCmd; out light: Light; } + + succession flow lightFlow from produceDirectedLight.light to reflectLight.light; + + action reflectLight { in light: Light; } + } + + + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithEnvelopingShape.sysml b/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithEnvelopingShape.sysml new file mode 100644 index 00000000..a7186d4e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithEnvelopingShape.sysml @@ -0,0 +1,17 @@ +package CarWithEnvelopingShape { + private import ShapeItems::Box; + private import SI::mm; + + part def Car { + doc + /* + * Example car with simple enveloping shape that is a solid box + */ + + item boundingBox : Box [1] :> boundingShapes { + :>> length = 4800 [mm]; + :>> width = 1840 [mm]; + :>> height = 1350 [mm]; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithShapeAndCSG.sysml b/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithShapeAndCSG.sysml new file mode 100644 index 00000000..a52284b2 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Geometry Examples/CarWithShapeAndCSG.sysml @@ -0,0 +1,88 @@ +package CarWithShapeAndCSG { + private import SpatialItems::*; + private import ShapeItems::*; + private import Objects::Point; + private import Quantities::VectorQuantityValue; + private import MeasurementReferences::CoordinateFrame; + private import MeasurementReferences::TranslationRotationSequence; + private import MeasurementReferences::Translation; + private import MeasurementReferences::Rotation; + private import SI::*; + + part def Car :> SpatialItem { + doc + /* + * Car with simple engine + */ + + item :>> shape = new Cuboid(4800 [mm], 1840 [mm], 1350 [mm]); + + attribute datum :>> coordinateFrame { + :>> mRefs = (mm, mm, mm); + } + + part powerSource : Engine [1] :> componentParts { + :>> ecf { + :>> mRefs = datum.mRefs; + :>> transformation : TranslationRotationSequence { + :>> source = datum; + :>> elements = ( new Translation((3800, (1840-190)/2, 40)[datum]) ); + } + } + } + } + + part def Engine :> SpatialItem { + doc + /* + * Simple 2-cylinder engine + * + * Note: The engine shape is modeled as a rectangular box with two cylindrical holes, a gross simplification. + */ + + item :>> shape [1]; + + attribute engineCoordinateFrame :>> coordinateFrame; + + part rawEngineBlock :> subSpatialParts [1] { + item :>> shape : Box [1] { + :>> length = 300 [mm]; + :>> width = 190 [mm]; + :>> height = 330 [mm]; + } + } + + private attribute rearCylinderSpacing = 90 [mm]; + private item cylinder1 :> subSpatialParts [1] { + item :>> shape : Cylinder [1] { + :>> radius = 55 [mm]; + :>> height = 350 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> source = ecf; + :>> elements = (new Translation( (rearCylinderSpacing, rawEngineBlock.shape.width/2, -10)[ecf])); + } + } + } + + private attribute cylinderSpacing = 2*cylinder1.shape.radius + 20 [mm]; + private item cylinder2 :> subSpatialParts [1] { + item :>> shape : Cylinder [1] { + :>> radius = cylinder1.shape.radius; + :>> height = cylinder1.shape.height; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> source = ecf; + :>> elements = ( new Translation((rearCylinderSpacing + cylinderSpacing, rawEngineBlock.shape.width/2, -10)[ecf]) ); + } + } + } + + /* CSG difference of rawEngineBlock minus cylinder1 minus cylinder2 */ + attribute :> differencesOf[1] { + item :>> elements = (rawEngineBlock, cylinder1, cylinder2); + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Geometry Examples/ExternalShapeRefExample.sysml b/test-data/sysml2/official/sysml/examples/Geometry Examples/ExternalShapeRefExample.sysml new file mode 100644 index 00000000..4bcd856a --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Geometry Examples/ExternalShapeRefExample.sysml @@ -0,0 +1,31 @@ +package ExternalShapeRefExample { + private import ScalarValues::String; + private import ShapeItems::*; + private import ISQ::mass; + private import SI::mm; + + metadata def ExternalShapeRef { + doc + /* + * Metadata to reference an externally defined shape. + */ + + attribute purpose : String[1]; + attribute shapeIri : String[1]; + } + + part myBatteryUnit { + item :>> shape : Shell { + metadata ExternalShapeRef { + purpose = "highLoD"; + shapeIri = "file:/detailed-geometry/LEMS-250W_BatteryHousing_Example.step"; + } + } + + private item envelopingBoxBatteryUnit : Box :> envelopingShapes { + :>> length = 140[mm]; + :>> width = 148[mm]; + :>> height = 90[mm]; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Geometry Examples/SimpleQuadcopter.sysml b/test-data/sysml2/official/sysml/examples/Geometry Examples/SimpleQuadcopter.sysml new file mode 100644 index 00000000..be69a47e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Geometry Examples/SimpleQuadcopter.sysml @@ -0,0 +1,247 @@ +package SimpleQuadcopter { + private import ISQ::*; + private import SI::*; + private import SpatialItems::*; + private import ShapeItems::*; + private import RealFunctions::sqrt; + private import TrigFunctions::pi; + private import TrigFunctions::tan; + private import MeasurementReferences::CoordinateFrame; + private import MeasurementReferences::TranslationRotationSequence; + private import MeasurementReferences::Translation; + private import MeasurementReferences::Rotation; + + part motorShape : SpatialItem { + item :>> shape : Cylinder { + :>> radius = 18 [mm]; + :>> height = 30 [mm]; + } + } + + part def Strut :> SpatialItem { + // By default will get same coordinateFrame.mRefs as owning SpatialItem, i.e.: + // attribute :>> coordinateFrame { :>> mRefs = (mm, mm, mm); } + + /* rawStrut is a construction shape: a rectangular beam */ + part rawStrut :> subSpatialParts { + item :>> shape : Box { + :>> length = 160 [mm]; + :>> width = 15 [mm]; + :>> height = 8 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (0, shape.width/2, 0)[source])); + } + } + } + + /* motorCutout is a construction shape: a cylinder of the same shape as the */ + part motorCutout :> subSpatialParts { + item :>> shape = motorShape.shape; + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (175, 0, -1)[source])); + } + } + } + + /* Strut shape is CSG difference of rawStrut minus motorCutout */ + attribute :> differencesOf[1] { + item :>> elements = (rawStrut, motorCutout); + } + } + + part def PropellerMotorAssy :> SpatialItem { + // By default will get same coordinateFrame.mRefs as owning CompoundSpatialItem, i.e.: + // attribute :>> coordinateFrame { :>> mRefs = (mm, mm, mm); } + + part propeller :> subSpatialParts { + item :>> shape : Cylinder { + doc /* propeller stay-out volume, without propeller shaft */ + :>> radius = 80 [mm]; + :>> height = 6 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (175, 0, 31)[source])); + } + } + } + + part motor :> subSpatialParts { + item :>> shape = motorShape.shape; + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (175, 0, 0)[source])); + } + } + } + + // By default the shape of a PropellerMotorAssy is the union of its owned composite items and parts that are SpatialItems. + } + + part def Camera :> SpatialItem { + // By default will get same coordinateFrame.mRefs as owning CompoundSpatialItem, i.e.: + // attribute :>> coordinateFrame { :>> mRefs = (mm, mm, mm); } + + part cameraHousing :> subSpatialParts { + item :>> shape : Cylinder { + :>> radius = 15 [mm]; + :>> height = 24 [mm]; + } + } + + /* The field of view is modeled as an item, since it is not a part of the quadcopter but rather a stay-out volume + * that can for example be used to formulate a constraint. + */ + item fieldOfView :> subSpatialParts { + doc /* Conical field of view with half-top angle 20 degree */ + item :>> shape : Cone { + :>> radius = height * tan(20 * pi/180) [mm]; + :>> height = 500 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Rotation( (0, 1, 0)[source], 180['°'])); + } + } + } + + // By default the shape of a Camera is the union of its owned composite items and parts that are SpatialItems. + } + + part quadCopter : SpatialItem { + attribute datum :>> coordinateFrame { + doc /* The datum is the top level coordinate frame of the system-of-interest, i.e., the quadcopter. + * By convention its origin is placed at the bottom of the mainBody with the +X axis pointing in the + * forward fligth (velocity) direction and the +Z axis pointing upward. The +Y axis completes the + * right-handed Cartesian coordinate system. + */ + :>> mRefs = (mm, mm, mm); + } + + part mainBody :> subSpatialParts { + + /* rawBody is a construction shape: the enveloping rectangular box */ + part rawBody :> subSpatialParts { + item :>> shape : Box { + :>> length = 160 [mm]; + :>> width = 15 [mm]; + :>> height = 8 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (0, shape.width/2, 0)[source])); + } + } + } + + /* cuttingBox is a construction shape: the enveloping rectangular box */ + part cuttingCornersBox :> subSpatialParts { + item :>> shape : Box { + :>> length = 105 [mm]; + :>> width = 105 [mm]; + :>> height = 60 [mm]; + } + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (0, -shape.length/sqrt(2), -10)[source]), + new Rotation((0, 0, 1)[source], 45['°'])); + } + } + } + + /* Main body shape is the CSG intersection of rawBody and cuttingCornersBox */ + attribute :> intersectionsOf[1] { + item :>> elements = (rawBody, cuttingCornersBox); + } + // Current syntax is not end-user friendly + // It will be possible to specify following simple CSG expression: + // item :>> shape = rawBody & cuttingCornersBox; + } + + // Helper construction parameters + private attribute xStrut : LengthValue = 49.60[mm]; + private attribute yStrut : LengthValue = 24.65[mm]; + private attribute zStrut : LengthValue = 25[mm]; + private attribute zPMAssy : LengthValue = 12[mm]; + + part strut1 : Strut :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (xStrut.num, yStrut.num, zStrut.num)[source]), + new Rotation((0, 0, 1)[source], 45['°'])); + } + } + } + part strut2 : Strut :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (-xStrut.num, yStrut.num, zStrut.num)[source]), + new Rotation((0, 0, 1)[source], 135['°'])); + } + } + } + part strut3 : Strut :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (-xStrut.num, -yStrut.num, zStrut.num)[source]), + new Rotation((0, 0, 1)[source], 225['°'])); + } + } + } + part strut4 : Strut :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (xStrut.num, -yStrut.num, zStrut.num)[source]), + new Rotation((0, 0, 1)[source], 315['°'])); + } + } + } + + part propellerMotorAssy1 : PropellerMotorAssy :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (xStrut.num, yStrut.num, zPMAssy.num)[source]), + new Rotation((0, 0, 1)[source], 45['°'])); + } + } + } + part propellerMotorAssy2 : PropellerMotorAssy :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (-xStrut.num, yStrut.num, zPMAssy.num)[source]), + new Rotation((0, 0, 1)[source], 135['°'])); + } + } + } + part propellerMotorAssy3 : PropellerMotorAssy :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (-xStrut.num, -yStrut.num, zPMAssy.num)[source]), + new Rotation((0, 0, 1)[source], 225['°'])); + } + } + } + part propellerMotorAssy4 : PropellerMotorAssy :> subSpatialParts { + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (xStrut.num, -yStrut.num, zPMAssy.num)[source]), + new Rotation((0, 0, 1)[source], 315['°'])); + } + } + } + + /* The camera is placed protruding from the +X face of the main body, rotated about the +Y axis over 50° downwards */ + part camera : Camera :> subSpatialParts{ + attribute :>> coordinateFrame { + :>> transformation : TranslationRotationSequence { + :>> elements = (new Translation( (59, 0, 2)[source]), + new Rotation((0, 1, 0)[source], 50['°'])); + } + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Geometry Examples/VehicleGeometryAndCoordinateFrames.sysml b/test-data/sysml2/official/sysml/examples/Geometry Examples/VehicleGeometryAndCoordinateFrames.sysml new file mode 100644 index 00000000..d12d6204 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Geometry Examples/VehicleGeometryAndCoordinateFrames.sysml @@ -0,0 +1,130 @@ +package VehicleGeometryAndCoordinateFrames { + private import TrigFunctions::*; + private import ISQ::*; + private import SI::*; + private import Time::*; + + private import ShapeItems::*; + private import SpatialItems::*; + + private import MeasurementReferences::CoordinateFrame; + private import MeasurementReferences::TranslationRotationSequence; + private import MeasurementReferences::Translation; + private import MeasurementReferences::Rotation; + + private import Collections::Array; + private import ScalarValues::Boolean; + private import ScalarValues::Real; + private import ScalarValues::Natural; + private import ControlFunctions::forAll; + + part def Vehicle :> SpatialItem; + + part def Chassis :> SpatialItem { + item :>> shape = new Box(4800 [mm], 1840 [mm], 1350 [mm]); + } + + part def Wheel :> SpatialItem { + doc + /* + * Generic wheel with lugbolts + * + * The radius is estimated for a 22 inch hub plus 110 mm tire height. + * The wheel width is equal to the cylinder height. + * The wheel has 5 lugbolts that are evenly distributed along a circle centered at the wheel's center. + */ + + item :>> shape : Cylinder { + :>> radius = 22/2*25.4 + 110 [mm]; + :>> height = 220 [mm]; + } + attribute wheelCoordinateFrame : CoordinateFrame; + + attribute numberOfBolts : Natural = 5; + part lugBolts : LugBolt[1..numberOfBolts] :> subSpatialParts; + + /* + * As an example of a more involved placement of composite parts, constrain the positions of the coordinate frame origins + * of the lugbolts to a circle with radius lbpr distributed evenly over 360°. + */ + attribute lugBoltPlacementRadius :>> radius default 60 [mm]; + private attribute lugBoltDistributionAngle :>> planeAngle = 360/numberOfBolts ['°']; + private attribute lbda : Real = lugBoltDistributionAngle.num * (pi/180); // lugBoltDistributionAngle in radian + assert constraint { + (1..numberOfBolts)->forAll { + in i : Natural; + private attribute lbcf = lugBolts#(i).coordinateFrame; + private attribute trs : TranslationRotationSequence { + :>> source = wcf; + :>> target = lbcf; + :>> elements = new Translation((lbpr*cos((i-1)*lbda), lbpr*sin((i-1)*lbda), -8)[wcf]); + } + lbcf.transformation == trs + } + } + } + + part def LugBolt :> SpatialItem { + item :>> shape : Cylinder { + :>> radius = 14 [mm]; + :>> height = 40 [mm]; + } + } + + part vehicle : Vehicle, SpatialItem { + /* + * Vehicle frame origin at center of bottom plate of chassis + * with +Z upwards and +X in the forward (front) direction + */ + attribute datum :>> coordinateFrame { + :>> mRefs = (mm, mm, mm); + } + + part chassis : Chassis[1] :> componentParts { + attribute :>> coordinateFrame { + attribute :>> transformation : TranslationRotationSequence { + attribute :>> source = datum; + attribute :>> elements = new Translation((-(shape as Box).length/2, -(shape as Box).width/2, 0)[datum]); + } + } + } + + private attribute plusXAxis : Array { :>> dimensions = 3; :>> elements : Real[3] = (1, 0, 0); } + private attribute frontWheelXShift : Real = 1670; + private attribute rearWheelXShift : Real = -1820; + private attribute wheelYShift : Real = 720; + + part leftFrontWheel : Wheel[1] :> componentParts { + attribute :>> coordinateFrame { + attribute :>> transformation : TranslationRotationSequence { + attribute :>> source = datum; + attribute :>> elements = (new Translation((frontWheelXShift, wheelYShift, 80)[datum]), new Rotation(plusXAxis[datum], -90['°'])); + } + } + } + part rightFrontWheel : Wheel[1] :> componentParts { + attribute :>> coordinateFrame { + attribute :>> transformation : TranslationRotationSequence { + attribute :>> source = datum; + attribute :>> elements = (new Translation((frontWheelXShift, -wheelYShift, 80)[datum]), new Rotation((1, 0, 0)[datum], 90['°'])); + } + } + } + part leftRearWheel : Wheel[1] :> componentParts { + attribute :>> coordinateFrame { + attribute :>> transformation : TranslationRotationSequence { + attribute :>> source = datum; + attribute :>> elements = (new Translation((rearWheelXShift, wheelYShift, 80)[datum]), new Rotation((1, 0, 0)[datum], 90['°'])); + } + } + } + part rightRearWheel : Wheel[1] :> componentParts { + attribute :>> coordinateFrame { + attribute :>> transformation : TranslationRotationSequence { + attribute :>> source = datum; + attribute :>> elements = (new Translation((rearWheelXShift, -wheelYShift, 80)[datum]), new Rotation((-1, 0, 0)[datum], 90['°'])); + } + } + } + } +} diff --git a/test-data/sysml2/official/sysml/examples/Import Tests/AliasImport.sysml b/test-data/sysml2/official/sysml/examples/Import Tests/AliasImport.sysml new file mode 100644 index 00000000..8a4cd5e8 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Import Tests/AliasImport.sysml @@ -0,0 +1,13 @@ +package AliasImport { + package Definitions { + part def Vehicle; + + alias Car for Vehicle; + } + + package Usages { + private import Definitions::Car; + + part vehicle : Car; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Import Tests/CircularImport.sysml b/test-data/sysml2/official/sysml/examples/Import Tests/CircularImport.sysml new file mode 100644 index 00000000..110dfb61 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Import Tests/CircularImport.sysml @@ -0,0 +1,27 @@ +package CircularImport { + + package P1 { + public import P2::*; + part def A; + } + package P2 { + public import P1::*; + part def B; + } + package Test1 { + public import P1::*; + part x: A; + part y: B; + } + package Test2 { + public import P2::*; + part x: A; + part y: B; + } + + part x: P1::A; + + // The following should not fail. + part y: P1::B; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Import Tests/PrivateImportTest.sysml b/test-data/sysml2/official/sysml/examples/Import Tests/PrivateImportTest.sysml new file mode 100644 index 00000000..c57b82fd --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Import Tests/PrivateImportTest.sysml @@ -0,0 +1,33 @@ +package PrivateImportTest { + package P1 { + part def A; + } + package P2 { + private import P1::*; + } + + part x: P1::A; + + public import P2::*; + // This should fail. + // A is not visible, because the import in P2 is private. + // part y: A; + // part y1: P2::A; + + package P3 { + part def B; + } + + private import P3::*; + + // This should not fail. + // Private import only restricts visibility outside the package. + part z: B; + + package P4 { + public import all P2::*; + + // This should not fail because "import all" overrides private import. + part z1: A; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Import Tests/QualifiedNameImportTest.sysml b/test-data/sysml2/official/sysml/examples/Import Tests/QualifiedNameImportTest.sysml new file mode 100644 index 00000000..dce2d6d5 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Import Tests/QualifiedNameImportTest.sysml @@ -0,0 +1,13 @@ +package QualifiedNameImportTest { + package P1 { + part def A; + } + package P2 { + package P2a { + public import P1::*; + } + // The following should not fail. + // A is a member of P2a because of the import. + part x: P2a::A; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Individuals Examples/AnalysisIndividualExample.sysml b/test-data/sysml2/official/sysml/examples/Individuals Examples/AnalysisIndividualExample.sysml new file mode 100644 index 00000000..d54b51b5 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Individuals Examples/AnalysisIndividualExample.sysml @@ -0,0 +1,95 @@ +package AnalysisIndividualExample { + private import ScalarValues::*; + private import Quantities::*; + private import ISQ::*; + private import USCustomaryUnits::*; + + package VehicleQuantities { + private import MeasurementReferences::*; + + attribute def DistancePerVolumeUnit :> DerivedUnit { + private attribute distancePF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = 1; } + private attribute volumePF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = -3; } + attribute :>> quantityDimension { :>> quantityPowerFactors = (distancePF, volumePF); } + } + + attribute def DistancePerVolumeValue :> ScalarQuantityValue { + :>> num : Real; + :>> mRef : DistancePerVolumeUnit; + } + + attribute gallon : VolumeUnit = 231.0 * 'in' ** 3; + attribute mpg : DistancePerVolumeUnit = 'mi' / gallon; + attribute hp : PowerUnit = 745.7[SI::W]; + } + + package VehicleModel { + public import VehicleQuantities::*; + + part def Vehicle { + attribute power :> ISQ::power; + } + + part def Engine { + attribute peakPower :> ISQ::power; + attribute fuelEfficiency : Real; + } + + part vehicle_c1 : Vehicle { + attribute :>> power = engine.peakPower; + part engine : Engine[1]; + } + } + + package FuelEconomyAnalysisModel { + private import VehicleModel::*; + private import SequenceFunctions::size; + private import SampledFunctions::SampledFunction; + private import SampledFunctions::SamplePair; + private import ControlFunctions::forAll; + + action def FuelConsumption { + in power : PowerValue[*]; + out fuelEconomy : DistancePerVolumeValue; + } + + analysis def FuelEconomyAnalysis { + subject vehicle: Vehicle; + + action fuelConsumption : FuelConsumption { + in power = vehicle.power; + out fuelEconomy : DistancePerVolumeValue; + } + + return calculatedFuelEconomy : DistancePerVolumeValue = + fuelConsumption.fuelEconomy; + } + } + + package IndividualAnalysisModel { + private import VehicleModel::*; + private import FuelEconomyAnalysisModel::*; + + individual part def Vehicle_1 :> Vehicle; + individual part def Engine_1 :> Engine; + + individual analysis def FuelEconomyAnalysis_1 :> FuelEconomyAnalysis; + individual action def FuelConsumption_1 :> FuelConsumption; + + individual analysis fuelEconomyAnalysis_1 : FuelEconomyAnalysis_1 { + subject vehicle : Vehicle_1 :> vehicle_c1 { + individual part :>> engine : Engine_1 { + attribute :>> peakPower = 200[hp]; + attribute :>> fuelEfficiency = 0.4; + } + } + individual action :>> fuelConsumption : FuelConsumption_1 { + snapshot :>> done :> fuelConsumption { + out :>> fuelEconomy = 35[mph]; + } + } + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Individuals Examples/JohnIndividualExample.sysml b/test-data/sysml2/official/sysml/examples/Individuals Examples/JohnIndividualExample.sysml new file mode 100644 index 00000000..c8393f44 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Individuals Examples/JohnIndividualExample.sysml @@ -0,0 +1,59 @@ +package JohnIndividualExample { + + item def Person { + doc + /* + * This is the definition of the class of persons, each of whom has an age. + */ + + attribute age : ScalarValues::Natural; + + timeslice asPresident : Person [0..*] { + doc + /* + * These are the periods during which a Person is president. + */ + } + } + + individual item def John :> Person { + doc + /* + * This the definition of the individual Person who is John. + * There is at most one such person. + */ + } + + item def Country { + doc + /* + * This is the definition of the class of countries, each of which may have + * at most one president (at any point in time). + */ + ref presidentOfCountry[0..1] : Person :> presidentOfCountry.asPresident; + } + + individual item def UnitedStates :> Country { + doc + /* + * This is the definition of the individual country that is the + * United States. It contains a single instance. The United States + * always has a president who must be at least 35 years old. + */ + + ref presidentOfUS[1] :>> presidentOfCountry { + assert constraint { age >= 35 } + } + } + + individual UnitedStatesWithJohnAsPresident : UnitedStates { + timeslice item UnitedStatesWhenJohnIsPresident[*] : UnitedStates { + doc + /* + * These are the time slices of the United States during + * which John is president of the United States. + */ + ref :>> presidentOfUS : John; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModel.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModel.sysml new file mode 100644 index 00000000..1ddd03fe --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModel.sysml @@ -0,0 +1,42 @@ +package ServerSequenceModel { + private import ScalarValues::String; + public import SignalDefinitions::*; + + package SignalDefinitions { + item def Subscribe { + attribute topic : String; + ref part subscriber; + } + + item def Publish { + attribute topic : String; + ref publication; + } + + item def Deliver { + ref publication; + } + } + + part def PubSubSequence { + part producer[1] { + event occurrence publish_source_event; + } + + message publish_message from producer.publish_source_event to server.publish_target_event; + + part server[1] { + event occurrence subscribe_target_event; + then event occurrence publish_target_event; + then event occurrence deliver_source_event; + } + + message subscribe_message from consumer.subscribe_source_event to server.subscribe_target_event; + message deliver_message from server.deliver_source_event to consumer.deliver_target_event; + + part consumer { + event occurrence subscribe_source_event; + then event occurrence deliver_target_event; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModelOutside.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModelOutside.sysml new file mode 100644 index 00000000..6e205fac --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceModelOutside.sysml @@ -0,0 +1,20 @@ +package ServerSequenceModelOutside { + public import ServerSequenceModel::*; + + part def PubSubSequenceOutside :> PubSubSequence { + part :>> producer { + event publish_source_event = publish_message.start; + } + + part :>> server { + event occurrence :>> subscribe_target_event = subscribe_message.done; + then event occurrence :>> publish_target_event = publish_message.done; + then event occurrence :>> deliver_source_event = deliver_message.start; + } + + part :>> consumer { /* Redundant with timing constraints on server and generic transfers. */ + event occurrence :>> subscribe_source_event = subscribe_message.start; + then event occurrence :>> deliver_target_event = deliver_message.done; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-2.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-2.sysml new file mode 100644 index 00000000..95a3f0e8 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-2.sysml @@ -0,0 +1,97 @@ +package ServerSequenceOutsideRealization_2 { + private import ScalarValues::String; + private import ServerSequenceModelOutside::*; + private import Configuration::*; + + package Configuration { + + port def PublicationPort; + + port def SubscriptionPort; + + part producer_2[1] { + attribute someTopic : String; + private item somePublication; + /* Requiring FIFO sort (as opposed to just default) to make arrival/leave ordering + * in ServerSequenceModelOutside.sysml equivalent to accept/send new ordering in + * ServerSquenceRealization-2.sysml. */ + :>> incomingTransferSort = Occurrences::earlierFirstIncomingTransferSort; + + port publicationPort : ~PublicationPort; + + perform action producerBehavior { + action publish send new Publish(someTopic, somePublication) via publicationPort; + } + } + + interface producer_2.publicationPort to server_2.publicationPort; + + part server_2[1] { + port publicationPort : PublicationPort; + port subscriptionPort : SubscriptionPort; + :>> incomingTransferSort = Occurrences::earlierFirstIncomingTransferSort; + + exhibit state serverBehavior { + entry; then waitForSubscription; + + state waitForSubscription; + transition subscribing + first waitForSubscription + accept sub : Subscribe via subscriptionPort + then waitForPublication; + + state waitForPublication; + transition delivering + first waitForPublication + accept pub : Publish via publicationPort + if pub.topic == subscribing.sub.topic + do send new Deliver(pub.publication) to subscribing.sub.subscriber + then waitForPublication; + } + } + + interface consumer_2.subscriptionPort to server_2.subscriptionPort; + + part consumer_2[1] { + attribute myTopic : String; + :>> incomingTransferSort = Occurrences::earlierFirstIncomingTransferSort; + + port subscriptionPort : ~SubscriptionPort; + + perform action consumerBehavior { + action subscribe send new Subscribe(myTopic, consumer_2) to server_2; + then action delivery accept Deliver via consumer_2; + } + } + + } + + part realization_2 : PubSubSequence { + part :>> producer :> producer_2; + part :>> server :> server_2; + part :>> consumer :> consumer_2; + + flow :>> publish_message: Transfers::MessageTransfer { + end :>> source ::> producer.publicationPort; + end :>> target ::> server.publicationPort; + } + flow :>> subscribe_message: Transfers::MessageTransfer { + end :>> source ::> consumer.subscriptionPort; + end :>> target ::> server.subscriptionPort; + } + flow :>> deliver_message: Transfers::MessageTransfer { + end :>> source ::> server; + end :>> target ::> consumer; + } + + /* Binding sent/accept messages to specification model messages. */ + /* Sends */ + bind producer_2.producerBehavior.publish.sentMessage = publish_message; + bind consumer_2.consumerBehavior.subscribe.sentMessage = subscribe_message; + bind server_2.serverBehavior.delivering.effect.sentMessage = deliver_message; + /* Accepts */ + bind consumer_2.consumerBehavior.delivery.acceptedMessage = subscribe_message; + bind server_2.serverBehavior.subscribing.accepter.acceptedMessage = subscribe_message; + bind server_2.serverBehavior.delivering.accepter.acceptedMessage = publish_message; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-3.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-3.sysml new file mode 100644 index 00000000..e5313a4f --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceOutsideRealization-3.sysml @@ -0,0 +1,159 @@ +package ServerSequenceOutsideRealization_3 { + private import ScalarValues::String; + private import ServerSequenceModelOutside::*; + private import Configuration::*; + + package Configuration { + + port def PublicationPort { + in ref publish : Publish; + } + + port def SubscriptionPort { + in ref subscribe : Subscribe; + out ref deliver : Deliver; + } + + interface def PublicationInterface { + end source : ~PublicationPort; + end target : PublicationPort; + } + + interface def SubscriptionInterface { + end source : ~SubscriptionPort; + end target : SubscriptionPort; + } + + part producer_3[1] { + attribute someTopic : String; + private item somePublication; + + port publicationPort : ~PublicationPort { + out ref :>> publish; + } + + perform action producerBehavior { + action publish { + out ref request : Publish[1] = new Publish(someTopic, somePublication); + } + } + + /* Internal flows are instantaneous to make arrival/leave ordering in SequenceModelOutside.sysml + * equivalent to ordering participant internals in ServerSequenceRealization-3.sysml. */ + flow publish_request from producerBehavior.publish.request to publicationPort.publish + { attribute :>> isInstant = true;} + } + + interface publication_interface : PublicationInterface connect producer_3.publicationPort to server_3.publicationPort { + flow publish_request from publication_interface.source.publish to publication_interface.target.publish; + } + + part server_3[1] { + port publicationPort : PublicationPort { + in ref :>> publish; + } + port subscriptionPort : SubscriptionPort { + in ref :>> subscribe; + out ref :>> deliver; + } + + flow subscribe_request from subscriptionPort.subscribe to serverBehavior.subscribing.request + { attribute :>> isInstant = true;} + flow publish_request from publicationPort.publish to serverBehavior.publishing.request + { attribute :>> isInstant = true;} + flow deliver_response from serverBehavior.delivering.response to subscriptionPort.deliver + { attribute :>> isInstant = true;} + + perform action serverBehavior { + + action subscribing { + in ref request : Subscribe[1]; + out attribute topic : String[1] = request.topic; + } + + then merge continuePublishing; + then action publishing { + in ref request : Publish[1]; + out attribute topic[1] = request.topic; + out ref publication[1] = request.publication; + } + + then decide; + if publishing.topic == subscribing.topic then delivering; + else continuePublishing; + + then action delivering { + in topic : String[1] = subscribing.topic; + in publication[1] = publishing.publication; + out ref response : Deliver = new Deliver(publication); + } + then continuePublishing; + + } + } + + interface subscription_interface : SubscriptionInterface connect consumer_3.subscriptionPort to server_3.subscriptionPort { + flow subscribe_request from subscription_interface.source.subscribe to subscription_interface.target.subscribe; + flow deliver_response from subscription_interface.target.deliver to subscription_interface.source.deliver; + } + + part consumer_3[1] { + attribute myTopic : String; + + port subscriptionPort : ~SubscriptionPort { + out ref :>> subscribe; + in ref :>> deliver; + } + + flow subscribe_request from consumerBehavior.subscribe.request to subscriptionPort.subscribe + { attribute :>> isInstant = true;} + flow deliver_response from subscriptionPort.deliver to consumerBehavior.delivery.response + { attribute :>> isInstant = true;} + + perform action consumerBehavior { + action subscribe { + out ref request : Subscribe = new Subscribe(myTopic); + } + then action delivery { + in ref response : Deliver; + } + } + } + + } + + part realization_2 : PubSubSequence { + part :>> producer :> producer_3 { + event producerBehavior.publish[1] :>> publish_source_event; + } + + part :>> server :> server_3 { + event serverBehavior.subscribing[1] :>> subscribe_target_event; + event serverBehavior.publishing[1] :>> publish_target_event; + event serverBehavior.delivering[1] :>> deliver_source_event; + } + + part :>> consumer :> consumer_3 { + event consumerBehavior.subscribe[1] :>> subscribe_source_event; + event consumerBehavior.delivery[1] :>> deliver_target_event; + } + + flow :>> publish_message from producer.producerBehavior.publish.request to server.serverBehavior.publishing.request { + event producer.publish_request[1]; + then event publication_interface.publish_request[1]; + then event server.publish_request[1]; + } + + flow :>> subscribe_message from consumer.consumerBehavior.subscribe.request to server.serverBehavior.subscribing.request { + event consumer.subscribe_request[1]; + then event subscription_interface.subscribe_request[1]; + then event server.subscribe_request[1]; + } + + flow :>> deliver_message from server.serverBehavior.delivering.response to consumer.consumerBehavior.delivery.response { + event server.deliver_response[1]; + then event subscription_interface.deliver_response[1]; + then event consumer.deliver_response[1]; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-2.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-2.sysml new file mode 100644 index 00000000..c1793ca4 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-2.sysml @@ -0,0 +1,102 @@ +package ServerSequenceRealization_2 { + private import ScalarValues::String; + private import ServerSequenceModel::*; + private import Configuration::*; + + package Configuration { + + port def PublicationPort; + + port def SubscriptionPort; + + part producer_2[1] { + attribute someTopic : String; + private item somePublication; + + port publicationPort : ~PublicationPort; + + perform action producerBehavior { + action publish send new Publish(someTopic, somePublication) via publicationPort; + } + } + + interface producer_2.publicationPort to server_2.publicationPort; + + part server_2[1] { + port publicationPort : PublicationPort; + port subscriptionPort : SubscriptionPort; + + exhibit state serverBehavior { + entry; then waitForSubscription; + + state waitForSubscription; + transition subscribing + first waitForSubscription + accept sub : Subscribe via subscriptionPort + then waitForPublication; + + state waitForPublication; + transition delivering + first waitForPublication + accept pub : Publish via publicationPort + if pub.topic == subscribing.sub.topic + do send new Deliver(pub.publication) to subscribing.sub.subscriber + then waitForPublication; + } + } + + interface consumer_2.subscriptionPort to server_2.subscriptionPort; + + part consumer_2[1] { + attribute myTopic : String; + + port subscriptionPort : ~SubscriptionPort; + + perform action consumerBehavior { + action subscribe send new Subscribe(myTopic, consumer_2) to server_2; + then action delivery accept Deliver via consumer_2; + } + } + + } + + part realization_2 : PubSubSequence { + part :>> producer :> producer_2 { + event producerBehavior.publish[1] :>> publish_source_event; + } + + part :>> server :> server_2 { + event serverBehavior.subscribing.accepter[1] :>> subscribe_target_event; + event serverBehavior.delivering.accepter[1] :>> publish_target_event; + event serverBehavior.delivering.effect[1] :>> deliver_source_event; + } + + part :>> consumer :> consumer_2 { + event consumerBehavior.subscribe[1] :>> subscribe_source_event; + event consumerBehavior.delivery[1] :>> deliver_target_event; + } + + flow :>> publish_message: Transfers::MessageTransfer { + end :>> source ::> producer.publicationPort; + end :>> target ::> server.publicationPort; + } + flow :>> subscribe_message: Transfers::MessageTransfer { + end :>> source ::> consumer.subscriptionPort; + end :>> target ::> server.subscriptionPort; + } + flow :>> deliver_message: Transfers::MessageTransfer { + end :>> source ::> server; + end :>> target ::> consumer; + } + + /* Binding sent/accept messages to specification model messages. */ + /* Sends */ + bind producer_2.producerBehavior.publish.sentMessage = publish_message; + bind consumer_2.consumerBehavior.subscribe.sentMessage = subscribe_message; + bind server_2.serverBehavior.delivering.effect.sentMessage = deliver_message; + /* Accepts */ + bind consumer_2.consumerBehavior.delivery.acceptedMessage = subscribe_message; + bind server_2.serverBehavior.subscribing.accepter.acceptedMessage = subscribe_message; + bind server_2.serverBehavior.delivering.accepter.acceptedMessage = publish_message; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-3.sysml b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-3.sysml new file mode 100644 index 00000000..5fb51f6e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Interaction Sequencing Examples/ServerSequenceRealization-3.sysml @@ -0,0 +1,151 @@ +package ServerSequenceRealization_3 { + private import ScalarValues::String; + private import ServerSequenceModel::*; + private import Configuration::*; + + package Configuration { + + port def PublicationPort { + in ref publish : Publish; + } + + port def SubscriptionPort { + in ref subscribe : Subscribe; + out ref deliver : Deliver; + } + + interface def PublicationInterface { + end source : ~PublicationPort; + end target : PublicationPort; + } + + interface def SubscriptionInterface { + end source : ~SubscriptionPort; + end target : SubscriptionPort; + } + + part producer_3[1] { + attribute someTopic : String; + private item somePublication; + + port publicationPort : ~PublicationPort { + out ref :>> publish; + } + + perform action producerBehavior { + action publish { + out ref request : Publish[1] = new Publish(someTopic, somePublication); + } + } + + flow publish_request from producerBehavior.publish.request to publicationPort.publish; + } + + interface publication_interface : PublicationInterface connect producer_3.publicationPort to server_3.publicationPort { + flow publish_request from publication_interface.source.publish to publication_interface.target.publish; + } + + part server_3[1] { + port publicationPort : PublicationPort { + in ref :>> publish; + } + port subscriptionPort : SubscriptionPort { + in ref :>> subscribe; + out ref :>> deliver; + } + + flow subscribe_request from subscriptionPort.subscribe to serverBehavior.subscribing.request; + flow publish_request from publicationPort.publish to serverBehavior.publishing.request; + flow deliver_response from serverBehavior.delivering.response to subscriptionPort.deliver; + + perform action serverBehavior { + + action subscribing { + in ref request : Subscribe[1]; + out attribute topic : String[1] = request.topic; + } + + then merge continuePublishing; + then action publishing { + in ref request : Publish[1]; + out attribute topic[1] = request.topic; + out ref publication[1] = request.publication; + } + + then decide; + if publishing.topic == subscribing.topic then delivering; + else continuePublishing; + + then action delivering { + in topic : String[1] = subscribing.topic; + in publication[1] = publishing.publication; + out ref response : Deliver = new Deliver(publication); + } + then continuePublishing; + + } + } + + interface subscription_interface : SubscriptionInterface connect consumer_3.subscriptionPort to server_3.subscriptionPort { + flow subscribe_request from subscription_interface.source.subscribe to subscription_interface.target.subscribe; + flow deliver_response from subscription_interface.target.deliver to subscription_interface.source.deliver; + } + + part consumer_3[1] { + attribute myTopic : String; + + port subscriptionPort : ~SubscriptionPort { + out ref :>> subscribe; + in ref :>> deliver; + } + + flow subscribe_request from consumerBehavior.subscribe.request to subscriptionPort.subscribe; + flow deliver_response from subscriptionPort.deliver to consumerBehavior.delivery.response; + + perform action consumerBehavior { + action subscribe { + out ref request : Subscribe = new Subscribe(myTopic); + } + then action delivery { + in ref response : Deliver; + } + } + } + + } + + part realization_2 : PubSubSequence { + part :>> producer :> producer_3 { + event producerBehavior.publish[1] :>> publish_source_event; + } + + part :>> server :> server_3 { + event serverBehavior.subscribing[1] :>> subscribe_target_event; + event serverBehavior.publishing[1] :>> publish_target_event; + event serverBehavior.delivering[1] :>> deliver_source_event; + } + + part :>> consumer :> consumer_3 { + event consumerBehavior.subscribe[1] :>> subscribe_source_event; + event consumerBehavior.delivery[1] :>> deliver_target_event; + } + + flow :>> publish_message from producer.producerBehavior.publish.request to server.serverBehavior.publishing.request { + event producer.publish_request[1]; + then event publication_interface.publish_request[1]; + then event server.publish_request[1]; + } + + flow :>> subscribe_message from consumer.consumerBehavior.subscribe.request to server.serverBehavior.subscribing.request { + event consumer.subscribe_request[1]; + then event subscription_interface.subscribe_request[1]; + then event server.subscribe_request[1]; + } + + flow :>> deliver_message from server.serverBehavior.delivering.response to consumer.consumerBehavior.delivery.response { + event server.deliver_response[1]; + then event subscription_interface.deliver_response[1]; + then event consumer.deliver_response[1]; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassConstraintExample.sysml b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassConstraintExample.sysml new file mode 100644 index 00000000..d8af9dfd --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassConstraintExample.sysml @@ -0,0 +1,117 @@ +package MassConstraintExample { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + part def Engine { + attribute m :> mass; + } + + part def Transmission { + attribute m :> mass; + } + + part def Vehicle1 { + attribute m : MassValue = eng.m + trans.m; + + part eng : Engine { + attribute :>> m : MassValue; + } + + part trans : Transmission { + attribute :>> m : MassValue; + } + } + + part def Vehicle2 { + assert constraint { m == eng.m + trans.m } + + attribute m : MassValue; + + part eng : Engine { + attribute :>> m : MassValue; + } + + part trans : Transmission { + attribute :>> m : MassValue; + } + } + + constraint def MassConstraint3 { + in totalMass : MassValue; + in partMasses : MassValue[0..*]; + + totalMass == sum(partMasses) + } + + part def Vehicle3 { + assert constraint massConstraint : MassConstraint3 { + in totalMass = m; + in partMasses = (eng.m, trans.m); + } + + attribute m : MassValue; + + part eng { + attribute m : MassValue; + } + + part trans { + attribute m : MassValue; + } + } + + constraint def MassConstraint4 { + in totalMass : MassValue; + in partMasses : MassValue[0..*]; + } + + constraint mc : MassConstraint4 { + in totalMass : MassValue; + in partMasses : MassValue[0..*]; + + totalMass == sum(partMasses) + } + + part def Vehicle4 { + assert mc { + in totalMass = m; + in partMasses = (eng.m, trans.m); + } + + attribute m : MassValue; + + part eng : Engine { + attribute :>> m : MassValue; + } + + part trans : Transmission { + attribute :>> m : MassValue; + } + } + + constraint def MassLimit { + in mass : MassValue; + in maxMass : MassValue; + + mass <= maxMass + } + + part def Vehicle5 { + assert constraint ml : MassLimit { + in mass = m; + in maxMass = 2500 [kg]; + } + + attribute m : MassValue = eng.m + trans.m; + + part eng : Engine { + attribute :>> m : MassValue; + } + + part trans : Transmission { + attribute :>> m : MassValue; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassRollup.sysml b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassRollup.sysml new file mode 100644 index 00000000..e483162e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/MassRollup.sysml @@ -0,0 +1,27 @@ +package MassRollup { + private import NumericalFunctions::*; + + part def MassedThing { + attribute mass :> ISQ::mass; + attribute totalMass :> ISQ::mass; + } + + part simpleThing : MassedThing { + attribute redefines totalMass = mass; + } + + part compositeThing : MassedThing { + part subcomponents: MassedThing[*]; + + attribute redefines totalMass default + mass + sum(subcomponents.totalMass); + } + + part filteredMassThing :> compositeThing { + abstract attribute minMass :> ISQ::mass; + + attribute redefines totalMass = + mass + sum(subcomponents.totalMass.?{in p :> ISQ::mass; p > minMass}); + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/Vehicles.sysml b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/Vehicles.sysml new file mode 100644 index 00000000..fb8736c4 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Mass Roll-up Example/Vehicles.sysml @@ -0,0 +1,37 @@ +package VehicleMasses { + private import ScalarValues::*; + private import MassRollup::*; + + part def CarPart :> MassedThing { + attribute serialNumber: String; + } + + part car: CarPart :> compositeThing { + attribute vin redefines serialNumber; + + part carParts: CarPart[*] redefines subcomponents; + + part engine :> simpleThing, carParts { + //... + } + + part transmission :> simpleThing, carParts { + //... + } + } + + // Example usage + private import SI::*; + part c :> car { + redefines mass = 1000 [kg]; + part redefines engine { + redefines mass = 100 [kg]; + } + + part redefines transmission { + redefines mass = 50 [kg]; + } + } + + // c.totalMass --> 1150.0 [kg] +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Metadata Examples/IssueMetadataExample.sysml b/test-data/sysml2/official/sysml/examples/Metadata Examples/IssueMetadataExample.sysml new file mode 100644 index 00000000..b6c011f1 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Metadata Examples/IssueMetadataExample.sysml @@ -0,0 +1,30 @@ +package IssueMetadataExample { + private import ModelingMetadata::Issue; + + //Example: the following identifies an issue with the interface + + metadata InterfaceCompatibilityIssue : Issue about engineToTransmissionInterface { + text = "This issue is about the interface compatability between the engine and transmission." + + "The interface def includes an end defined by a ClutchPort." + + "However, the interface usage connects the transmission port that is defined by ~DrivePwrPort." + + "This should have surfaced a compatibility issue, since the interface is not really compatible with its definition"; + } + + interface def EngineToTransmissionInterface{ + end p1:DrivePwrPort; + end p2:ClutchPort; + } + port def DrivePwrPort; + port def ClutchPort; + + part engine{ + port drivePwrPort:DrivePwrPort; + } + part transmission{ + port clutchPort:~DrivePwrPort; + } + + interface engineToTransmissionInterface:EngineToTransmissionInterface + connect engine.drivePwrPort to transmission.clutchPort; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Metadata Examples/RationaleMetadataExample.sysml b/test-data/sysml2/official/sysml/examples/Metadata Examples/RationaleMetadataExample.sysml new file mode 100644 index 00000000..fa6b602d --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Metadata Examples/RationaleMetadataExample.sysml @@ -0,0 +1,24 @@ +package RationaleMetadataExample { + private import ModelingMetadata::Rationale; + + /* Example: the following provides the rationale for selecting the engine4cyl based on a trade study analysis. + The rationale could be contained in the vehicle configuration with the selected engine */ + + part engine; + part engine4cyl :> engine; + part engine6cyl :> engine; + + metadata engineSelectionRationale : Rationale about engine4cyl { + text = "This rationale for selecting the engine4cyl refers to the engineTradeOffAnalysis."; + explanation = engineTradeOffAnalysis; + } + + private import TradeStudies::*; + analysis engineTradeOffAnalysis:TradeStudy{ + subject alternatives :> engine [2] = (engine4cyl, engine6cyl); + + /* ... */ + + return selectedEngine :> engine; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Metadata Examples/RequirementMetadataExample.sysml b/test-data/sysml2/official/sysml/examples/Metadata Examples/RequirementMetadataExample.sysml new file mode 100644 index 00000000..4501e4b7 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Metadata Examples/RequirementMetadataExample.sysml @@ -0,0 +1,34 @@ +package RequirementMetadataExample { + private import Metaobjects::SemanticMetadata; + private import ModelingMetadata::*; + private import RiskMetadata::*; + private import RiskLevelEnum::*; + + requirement def Goal; + requirement goals : Goal[*] nonunique; + metadata def goal :> SemanticMetadata { + :>> baseType = goals meta SysML::RequirementUsage; + } + + requirement <'1'> vehicleMassRequirement { + doc /* The total mass of a vehicle shall be less than or equal to the required mass. */ + + @StatusInfo { + status = StatusKind::tbd; + risk { + totalRisk = high; + technicalRisk = medium; + scheduleRisk = low; + costRisk = medium; + } + originator = "Bob"; + owner = "Mary"; + } + } + + #goal requirement deliverPayload { + assume #goal constraint payloadMassLimit; + require #goal vehicleMassRequirement; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Metadata Examples/RiskMetadataExample.sysml b/test-data/sysml2/official/sysml/examples/Metadata Examples/RiskMetadataExample.sysml new file mode 100644 index 00000000..5db0fe86 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Metadata Examples/RiskMetadataExample.sysml @@ -0,0 +1,19 @@ +package RiskMetadataExample { + private import RiskMetadata::*; + private import RiskLevelEnum::*; + + part engine4cyl{ + @Risk { + totalRisk = high; + technicalRisk = medium; + scheduleRisk = medium; + } + @Risk { + totalRisk { + probability = 0.3; + impact = 0.7; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Metadata Examples/VerificationMetadataExample.sysml b/test-data/sysml2/official/sysml/examples/Metadata Examples/VerificationMetadataExample.sysml new file mode 100644 index 00000000..98269d03 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Metadata Examples/VerificationMetadataExample.sysml @@ -0,0 +1,15 @@ +package VerificationMetadataExample { + private import VerificationCases::*; + private import VerificationMethodKind::*; + + verification def MassTest; + verification massTests:MassTest { + @VerificationMethod{ kind = (test,demo); } + objective { + } + action weighVehicle { + @VerificationMethod{ kind = analyze; } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Packet Example/PacketUsage.sysml b/test-data/sysml2/official/sysml/examples/Packet Example/PacketUsage.sysml new file mode 100644 index 00000000..39963799 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Packet Example/PacketUsage.sysml @@ -0,0 +1,16 @@ +package 'Packet Usage' { + public import Packets::*; + private import ScalarValues::Real; + + part packet1: 'Thermal Data Packet'; + part packet2: 'Thermal Data Packet'; + part packet3: 'Thermal Data Packet' { + attribute 'special data field' redefines 'packet data field'{ + attribute redefines 'user data field' { + attribute 'special data': Real; + } + } + } + +} + diff --git a/test-data/sysml2/official/sysml/examples/Packet Example/Packets.sysml b/test-data/sysml2/official/sysml/examples/Packet Example/Packets.sysml new file mode 100644 index 00000000..11067e15 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Packet Example/Packets.sysml @@ -0,0 +1,35 @@ +package Packets { + private import ScalarValues::*; + private import Time::DateTime; + + attribute 'packet header' { } + + attribute 'packet data field' { + attribute 'packet secondary header' redefines 'packet header'; + attribute 'user data field'; + } + + part def 'Data Packet' { + attribute 'packet primary header' redefines 'packet header' { + attribute 'packet version number': Integer; + attribute 'packet identification': String; + attribute 'packet data length': Integer; + } + attribute redefines 'packet data field'; + } + + part def 'Thermal Data Packet' :> 'Data Packet' { + attribute 'packet data field' redefines Packets::'packet data field'{ + attribute 'packet secondary header' redefines 'packet header' { + attribute 'packet timestamp': DateTime; + attribute 'telemetry packet type': String; + } + + attribute 'user data field' redefines Packets::'packet data field'::'user data field' { + attribute timestamp: DateTime; + attribute temperature: Real; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Requirements Examples/HSUVRequirements.sysml b/test-data/sysml2/official/sysml/examples/Requirements Examples/HSUVRequirements.sysml new file mode 100644 index 00000000..3eb53a2e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Requirements Examples/HSUVRequirements.sysml @@ -0,0 +1,39 @@ +package HSUVRequirements { + private import Requirements::*; + + requirement <'UR1.1'> Load: FunctionalRequirementCheck { + // The following requirements are composite sub-requirements. + requirement Passengers; + requirement FuelCapacity; + requirement Cargo; + } + + requirement <'UR1.2'> EcoFriendliness: PerformanceRequirementCheck { + requirement <'URI1.2.1'> Emissions: PerformanceRequirementCheck { + /* The car shall meet 2010 Kyoto Accord emissions standards. */ + } + } + + requirement <'UR1.3'> Performance: PerformanceRequirementCheck { + requirement Acceleration; + requirement <'UR1.3.1'> FuelEconomy: PerformanceRequirementCheck { + /* User shall obtain fuel economy better than that provided by + * 95% of cars built in 2004. + */ + } + requirement Braking; + requirement Range; + requirement Power; + } + + requirement <'UR1.4'> Ergonomics; + + // Syntactically, should this be explicitly marked as a "group"? + requirement HybridSUVSpec { + // The following requirements are required by reference. + require Load; + require EcoFriendliness; + require Performance; + require Ergonomics; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Requirements Examples/RequirementDerivationExample.sysml b/test-data/sysml2/official/sysml/examples/Requirements Examples/RequirementDerivationExample.sysml new file mode 100644 index 00000000..69d0eb76 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Requirements Examples/RequirementDerivationExample.sysml @@ -0,0 +1,39 @@ +package RequirementDerivationExample { + private import RequirementDerivation::*; + + requirement def Req1; + + requirement def Req1_1; + requirement def Req1_2; + + #derivation connection def Req1_Derivation { + end #original r1 : Req1; + end #derive r1_1 : Req1_1; + end #derive r1_2 : Req1_2; + } + + part def System; + part def Subsystem1; + part def Subsystem2; + + part system : System { + part sub1 : Subsystem1; + part sub2 : Subsystem2; + } + + part satisfactionContext { + ref :>> system; + + satisfy requirement req1 : Req1 by system; + satisfy requirement req1_1 : Req1_1 by system.sub1; + satisfy requirement req1_2 : Req1_2 by system.sub2; + + #derivation connection : Req1_Derivation { + end r1 ::> req1; + end r1_1 ::> req1_1; + end r1_2 ::> req1_1; + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Requirements Examples/VehicleRequirementDerivation.sysml b/test-data/sysml2/official/sysml/examples/Requirements Examples/VehicleRequirementDerivation.sysml new file mode 100644 index 00000000..6db4ff57 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Requirements Examples/VehicleRequirementDerivation.sysml @@ -0,0 +1,40 @@ +package VehicleRequirementDerivation { + private import RequirementDerivation::*; + + part vehicle { + attribute mass :> ISQ::mass; + + part chassis { + attribute mass :> ISQ::mass; + } + + part engine { + attribute mass :> ISQ::mass; + } + } + + requirement def MassRequirement { + subject mass :> ISQ::mass; + attribute massLimit :> ISQ::mass; + require constraint { mass <= massLimit } + } + + requirement vehicleMassRequirement : MassRequirement { + subject :>> mass = vehicle.mass; + } + + requirement chassisMassRequirement : MassRequirement { + subject :>> mass = vehicle.chassis.mass; + } + + requirement engineMassRequirement : MassRequirement { + subject :>> mass = vehicle.engine.mass; + } + + #derivation connection { + end #original ::> vehicleMassRequirement; + end #derive ::> chassisMassRequirement; + end #derive ::> engineMassRequirement; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Room Model/RoomModel.sysml b/test-data/sysml2/official/sysml/examples/Room Model/RoomModel.sysml new file mode 100644 index 00000000..e591fae8 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Room Model/RoomModel.sysml @@ -0,0 +1,77 @@ +// SysML v2 Interpretation of the SysML v1 Room Connection Example +package RoomModel { + package RoomDefinitionModelLibrary{ + private import Port_Definitions::*; + private import Flow_Definitions::*; + package Part_Definitions{ + // Rooms + part def Classroom { + port classEntry: EntryWay_to_Classroom; + } + part def Storageroom { + port storageEntry: EntryWay_to_Storageroom; + } + part def Hallway { + // conjugate ports with ~ + port hallExit_to_Classroom: ~EntryWay_to_Classroom; + port hallExit_to_Storageroom: ~EntryWay_to_Storageroom; + } + } + package Port_Definitions{ + port def EntryWay_to_Classroom { + //flow properties + in ref student:Student; + in ref teacher:Teacher; + in ref furniture:Furniture; + in ref air:Air; + } + port def EntryWay_to_Storageroom { + //flow properties + in ref furniture: Furniture; + in ref air: Air; + } + } + package Flow_Definitions { + // Conveyed items between Hallway, Classroom, and Storageroom + part def Air; + part def Furniture; + part def Student; + part def Teacher; + } + } + package Room_Configuration{ + // defining the parts and their interconnection in context + private import RoomDefinitionModelLibrary::*; + private import RoomDefinitionModelLibrary::Part_Definitions::*; + private import RoomDefinitionModelLibrary::Port_Definitions::*; + private import RoomDefinitionModelLibrary::Flow_Definitions::*; + part roomContext{ + part c:Classroom; + part s:Storageroom; + part h:Hallway; + + // Connectors and item flows between hallway and classroom + flow HallToClassroom_Air + from h.hallExit_to_Classroom.air + to c.classEntry.air; + flow HallToClassroom_Furniture + from h.hallExit_to_Classroom.furniture + to c.classEntry.furniture; + flow HallToClassroom_Student + from h.hallExit_to_Classroom.student + to c.classEntry.student; + flow HallToClassroom_Teacher + from h.hallExit_to_Classroom.teacher + to c.classEntry.teacher; + flow HallToStorageroom_Air + from h.hallExit_to_Storageroom.air + to s.storageEntry.air; + flow HallToStorageroom_Furniture + from h.hallExit_to_Storageroom.furniture + to s.storageEntry.furniture; + } + } +} + + + diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ActionTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ActionTest.sysml new file mode 100644 index 00000000..32b8101b --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ActionTest.sysml @@ -0,0 +1,53 @@ +package ActionTest { + action def A{ in x; } + + action a: A { + first start; + + action b { in y = x; } + + bind x = b.y; + } + + attribute def S; + + action a1 { + first start; + then merge m; + then accept S; + then accept sig after 10[SI::s]; + then accept at new Time::Iso8601DateTime("2022-01-30T01:00:00Z"); + + then send new S() to b; + then accept when b.f; + then decide; + if true then m; + else done; + } + + action a2 { + in s : S; + action aa { + out part target; + } + flow aa.target to snd.receiver; + action snd send { + in :>> payload = s; + } + action snd2 send via this to aa.target; + bind s = snd2.payload; + } + + action b { + attribute f : ScalarValues::Boolean; + ref action a : A; + } + + action def c { + first start; + then action c1 { + terminate c1; + } + then terminate; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/AliasTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/AliasTest.sysml new file mode 100644 index 00000000..00e3785e --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/AliasTest.sysml @@ -0,0 +1,22 @@ +package AliasTest { + private import ISQSpaceTime::breadth; // import of an alias + attribute b :> breadth; + + part def P1 { + port porig1; + alias po1 for porig1; + } + + part p1 : P1 { + port po1 :>> po1; + } + + part p2 : P1 { + port pdest; + alias pd1 for pdest; + } + + + connect p1.po1 to p2.pdest; + connect p1.po1 to p2.pd1; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/AllocationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/AllocationTest.sysml new file mode 100644 index 00000000..fcf26dab --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/AllocationTest.sysml @@ -0,0 +1,36 @@ +package AllocationTest { + part def Logical { + part component; + } + + part def Physical { + part assembly { + part element; + } + } + + part l : Logical { + part :>> component; + } + part p : Physical { + part :>> assembly { + part :>> element; + } + allocate l.component to assembly.element; + } + + allocation def A; + + allocation def Logical_to_Physical :> A { + end logical : Logical; + end physical : Physical; + } + + allocation allocation1 : Logical_to_Physical allocate l to p; + allocation allocation2 : Logical_to_Physical allocate ( + logical ::> l, + physical ::> p + ); + + allocate l.component to p.assembly.element; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/AnalysisTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/AnalysisTest.sysml new file mode 100644 index 00000000..b345419f --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/AnalysisTest.sysml @@ -0,0 +1,38 @@ +package AnalysisTest { + + part def V { + m; + } + + part vv : V; + + requirement def AnalysisObjective { + doc /* ... */ + } + + analysis def AnalysisCase { + subject v : V; + + objective obj : AnalysisObjective { + subject = result; + } + + v.m + } + + analysis def AnalysisPlan { + subject v : V; + + objective { + doc /* ... */ + } + + analysis analysisCase : AnalysisCase { return mass; } + } + + part analysisContext { + analysis analysisPlan : AnalysisPlan { + subject v = vv; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/AssignmentTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/AssignmentTest.sysml new file mode 100644 index 00000000..a2a88431 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/AssignmentTest.sysml @@ -0,0 +1,52 @@ +package AssignmentTest { + + part def Counter { + attribute count : ScalarValues::Integer := 0; + + action incr { + assign count := count + 1; + } + + action decr { + assign count := count - 1; + } + } + + attribute def Incr; + attribute def Decr; + + state def Counting { + part counter : Counter; + entry assign counter.count := 0; + + then state wait; + accept Incr + then increment; + accept Decr + then decrement; + + state increment { + do assign counter.count := counter.count + 1; + } + then wait; + + state decrement { + do assign counter.count := counter.count - 1; + } + then wait; + } + + calc def Increment { + in c : Counter; + return : Counter; + + perform c.incr; + c + } + + action a { + state counting : Counting; + assign counting.counter.count := counting.counter.count + 1; + assign counting.counter.count := Increment(counting.counter).count; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/CalculationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/CalculationTest.sysml new file mode 100644 index 00000000..4890d550 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/CalculationTest.sysml @@ -0,0 +1,30 @@ +package CalculationExample { + private import ISQ::*; + private import NumericalFunctions::*; + + part def VehiclePart { + attribute m : MassValue; + } + + part def Vehicle :> VehiclePart; + + part vehicle : Vehicle { + part eng : VehiclePart; + part trans : VehiclePart; + attribute ::> m = ms.totalMass; + } + + calc def MassSum { + in partMasses : MassValue[0..*]; + return totalMass : MassValue = sum(partMasses); + } + + calc ms: MassSum { + in partMasses = (vehicle.eng.m, vehicle.trans.m); + return totalMass; + } + + part vehicles[*] = (vehicle, vehicle); + attribute masses1[*] = (vehicles as VehiclePart).m; + attribute masses2[*] = (vehicles as vehicle).m; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/CommentTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/CommentTest.sysml new file mode 100644 index 00000000..1cf70de3 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/CommentTest.sysml @@ -0,0 +1,44 @@ + /* AAA */ + //a lexical comment ("note") is not a part of model +package CommentTest { + // inside package + /* +*AAA + * BBB*/ + /* + * + * + * AAA *** + *BBB + */ + + /* + * AAAA + * BBBB */ + /* AAAA + + + * BBBB + * + * CCCC + */ + locale "en_US" /* + * AAAA + * BBBB + * CCC DDD + */ + + /* comment inside a package */ + doc locale "en_US" /* Documentation about Package */ + comment cmt /* Named Comment */ + comment cmt_cmt about cmt /* Comment about Comment */ + + comment about C /* Documention Comment about Part Def */ + part def C { + doc /* Documentation in Part Def */ + comment /* Comment in Part Def */ + comment about CommentTest locale "en_US" /* Comment about Package */ + } + /* abc */ + part def A; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ConjugationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ConjugationTest.sysml new file mode 100644 index 00000000..eccdaa17 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ConjugationTest.sysml @@ -0,0 +1,35 @@ +package ConjugationTest { + port def P; + + part def B { + port p1: P; + port p2: ~P; + } + + connection def A { + end port p1: P; + end port p2: ~P; + } + + interface def I { + end p1: P; + end p2: ~P; + } + + part def B1 { + part p { + port p1: P; + port p2: ~P; + } + + connection a: A { + end port p3: P ::> p.p1; + end port p4: ~P ::> p.p2; + } + interface i: I { + end port p3: P ::> p.p1; + end port p4: ~P ::> p.p2; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ConnectionTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ConnectionTest.sysml new file mode 100644 index 00000000..1cfb9df6 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ConnectionTest.sysml @@ -0,0 +1,77 @@ +package ConnectionTest { + + part p { + part x { + part x1; + } + } + + part def P { + part y; + + connect p to y; + + part p1 :> p; + + connect p1.x to y; + connect p1.x.x1 to y; + + part a; + part b; + + bind a = b; + binding ab bind a = b; + binding ab1 : AB bind a = b; + + first a then b; + succession s first a then b; + succession s1 : AB first a then b; + } + + abstract connection def C { + part p; + end end1; + end end2; + end end3; + } + + part d1; + part d2; + part d3; + part d4; + + connection bus : C connect (d1, d2, d3, d4); + + connection : C { + end :>> end1 ::> d1; + end end2 ::> d2; + end end3 ::> d3; + } + + connection { + part q; + end ref end1 ::> d1 :> q; + end end2 ::> d2; + } + + abstract flow def F; + + message : F from p to p; + + part def A { + ref b : B; + } + + part def B; + + connection def AB { + end [1] item a : A { + @M; + } + end b : B; + } + + metadata def M; + + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ConstraintTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ConstraintTest.sysml new file mode 100644 index 00000000..686807e2 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ConstraintTest.sysml @@ -0,0 +1,90 @@ +package ConstraintTest { + private import ISQ::MassValue; + private import SI::kg; + private import NumericalFunctions::sum; + + constraint def MassAnalysis { + attribute totalMass: MassValue; + attribute componentMasses: MassValue[0..*]; + + totalMass == sum(componentMasses) + } + + part def Component { + attribute mass: MassValue; + } + + part vehicle : Component { + part engine : Component; + part frontAxleAssembly : Component; + part rearAxleAssembly : Component; + } + + part vehicle1a :> vehicle { + assert constraint massAnalysis : MassAnalysis { + attribute redefines totalMass; + attribute redefines componentMasses; + } + + bind massAnalysis.totalMass = mass; + bind massAnalysis.componentMasses = engine.mass; + bind massAnalysis.componentMasses = frontAxleAssembly.mass; + bind massAnalysis.componentMasses = rearAxleAssembly.mass; + } + + part vehicle1b :> vehicle { + assert constraint massAnalysis : MassAnalysis { + attribute redefines totalMass = mass; + attribute redefines componentMasses = (engine.mass, frontAxleAssembly.mass, rearAxleAssembly.mass); + } + } + + constraint def MassAnalysis2 { + in totalMass : MassValue; + in componentMasses: MassValue[0..*]; + + totalMass == sum(componentMasses) + } + + part vehicle2a :> vehicle { + assert constraint massConstraint : MassAnalysis2; + + bind massConstraint.totalMass = mass; + bind massConstraint.componentMasses = engine.mass; + bind massConstraint.componentMasses = frontAxleAssembly.mass; + bind massConstraint.componentMasses = rearAxleAssembly.mass; + } + + part vehicle2b :> vehicle { + assert constraint massAnalysis2 : MassAnalysis2 { + in totalMass = mass; + in componentMasses = (engine.mass, frontAxleAssembly.mass, rearAxleAssembly.mass); + } + } + + constraint def MassAnalysis3 { + in totalMass : MassValue; + in componentMasses: MassValue[0..*]; + } + + constraint massAnalysis3 : MassAnalysis3 { + in totalMass : MassValue; + in componentMasses: MassValue[0..*]; + + totalMass == sum(componentMasses) + } + + part vehicle3 :> vehicle { + assert massAnalysis3 { + in totalMass = mass; + in componentMasses = (engine.mass, frontAxleAssembly.mass, rearAxleAssembly.mass); + } + } + + part vehicle4 :> vehicle { + assert constraint { mass == engine.mass + frontAxleAssembly.mass + rearAxleAssembly.mass } + } + + constraint massLimitation { mass : MassValue; massLimit : MassValue; mass < massLimit } + assert not massLimitation { :>> mass = vehicle3.mass; :>> massLimit = vehicle4.mass; } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ControlNodeTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ControlNodeTest.sysml new file mode 100644 index 00000000..0b2ca290 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ControlNodeTest.sysml @@ -0,0 +1,35 @@ +action def ControlNodeTest { + action A1; + then J; + + action A2 { + out a; + } + then J; + + flow A2.a to F.a; + + join J; + then fork F { + in a; + out b1; + out b2; + } + then B1; + then B2; + + flow F.b1 to B1.b; + flow F.b2 to B2.b; + + action B1 { + in b; + } + then M; + + action B2 { + in b; + } + then M; + + merge M; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/DecisionTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/DecisionTest.sysml new file mode 100644 index 00000000..4996f6ce --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/DecisionTest.sysml @@ -0,0 +1,22 @@ +action def DecisionTest { + attribute x = 1; + + decide 'test x'; + if x == 1 then A1; + if x > 1 then A2; + else A3; + + then decide D; + if true then A1; + if false then A2; + + action A1; + action A2; + action A3; + + public succession S first A1 + if x == 0 then A2; + + private first A3; + if x > 0 then 'test x'; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/DefaultValueTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/DefaultValueTest.sysml new file mode 100644 index 00000000..223e92bd --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/DefaultValueTest.sysml @@ -0,0 +1,18 @@ +package DefaultValueTest { + + part def V { + attribute m default = 10; + attribute n = 20; + } + + part v1 : V { + attribute :>> m = 20; + } + + part def W :> V { + attribute :>> m default = n; + } + + part v2 = new W(); + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/DependencyTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/DependencyTest.sysml new file mode 100644 index 00000000..d39e4122 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/DependencyTest.sysml @@ -0,0 +1,20 @@ +package DependencyTest { + + package System { + package 'Application Layer'; + package 'Service Layer'; + package 'Data Layer'; + } + + private import System::*; + + dependency Use from 'Application Layer' to 'Service Layer'; + dependency from 'Service Layer' to 'Data Layer'; + + attribute x; + attribute y; + attribute z; + + dependency z to x, y; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/EnumerationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/EnumerationTest.sysml new file mode 100644 index 00000000..2dc2fb4b --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/EnumerationTest.sysml @@ -0,0 +1,54 @@ +package EnumerationTest { + + attribute def Color { + attribute val : ScalarValues::Natural; + } + + enum def ColorKind :> Color { + doc + /* + * An EnumerationDefinition can contain only EnumerationUsages. However, + * it can specialize an AttributeDefinition in order to inherit + * common features for its enumeration values. + */ + + enum red { + :>> val = 0; + } + enum blue { + :>> val = 1; + } + enum green { + :>> val = 2; + } + } + + enum color : ColorKind; + enum color1 = ColorKind::blue; // Implicitly typed by ColorKind. + attribute color2 : ColorKind = color1; + + enum def E1 { a; b; c; + doc + /* + * The "enum" keyword is optional for EnumerationUsages used to define the + * enumerated values of an EnumerationDefinition. + */ + } + + enum def E2; + + attribute def Size :> ScalarValues::Real { + doc + /* + * An EnumerationDefinition can also be used to restrict a supertype to + * specific values. + */ + } + enum def SizeChoice :> Size { + = 60.0; + = 70.0; + = 80.0; + } + enum size: SizeChoice = 60.0; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/FeaturePathTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/FeaturePathTest.sysml new file mode 100644 index 00000000..0c469c45 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/FeaturePathTest.sysml @@ -0,0 +1,43 @@ +package Q { + part def F { + part a : A; + } + + part f : F; + + part def A { + part g = f.a; + } + + part def B { + part f : F; + part a : A; + } + + part def C { + part b : B { + connect f.a to a.g; + bind f.a = a.g; + } + + part c subsets b.f { + part aa subsets a; + } + + flow b.f.a to c.aa; + } + + part e1 { + attribute x : E; + // Ensure that "e1" resolves correctly. + bind e1.x = E::e2; + } + + enum def E { + enum e1; + enum e2; + } + + part g = new A().g.g.g; + +} diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ImportTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ImportTest.sysml new file mode 100644 index 00000000..c767014c --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ImportTest.sysml @@ -0,0 +1,18 @@ +package ImportTest { + package Pkg1 { + private import Pkg2::Pkg21::Pkg211::P211; + private import Pkg2::Pkg21::*; + private import Pkg211::*::**; + part p11 : Pkg211::P211; + part def P12; + } + + package Pkg2 { + private import Pkg1::*; + package Pkg21 { + package Pkg211 { + part def P211 :> P12; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/IndividualTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/IndividualTest.sysml new file mode 100644 index 00000000..cbc804bd --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/IndividualTest.sysml @@ -0,0 +1,39 @@ +package IndividualTest { + individual def IO1; + individual occurrence def IO2 { + individual io : IO1; + } + + individual item def II1 { + individual item ii : II1; + } + + item def I { + part i : I; + } + individual item def II2 :> I { + individual item :>> i : II2; + } + + individual part def IP1 { + individual part p : IP1; + } + + part def P { + part p : P; + } + individual part def IP2 :> P { + individual part :>> p : IP2; + } + + individual action def AP1 { + individual action a : AP1; + } + + action def A { + action a : A; + } + individual action def IA2 :> A { + individual action :>> a : IA2; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/InterfaceTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/InterfaceTest.sysml new file mode 100644 index 00000000..2f2c714d --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/InterfaceTest.sysml @@ -0,0 +1,27 @@ +package InterfaceTest { + + port def P1; + port def P2; + + interface def I1 { + end port p1: P1; + end port p2: P2; + } + + interface def I2 { + end p1: P1; + end p2: P2; + } + + part def A { + part x { + port p1 : P1; + } + part y { + port p2 : P2; + } + interface i1 : I1 connect x.p1 to y.p2; + abstract interface i = i1; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ItemTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ItemTest.sysml new file mode 100644 index 00000000..92e212d4 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ItemTest.sysml @@ -0,0 +1,23 @@ +package ItemTest { + + item f: A; + + public item def A { + item b: B; + protected ref part c: C; + } + + abstract item def B { + public abstract part a: A; + } + + private part def C { + private in ref y: A, B; + } + + port def P { + in item a1: A; + out item a2: A; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/MetadataTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/MetadataTest.sysml new file mode 100644 index 00000000..2ebd767b --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/MetadataTest.sysml @@ -0,0 +1,42 @@ +package MetadataTest { + private import 'User Defined Extensions'::*; + + library package 'User Defined Extensions' { + + #Security enum def ClassificationLevel :> ScalarValues::Natural { + uncl : ClassificationLevel = 0; + conf : ClassificationLevel = 1; + #Security enum secret : ClassificationLevel = 2; + } + + metadata def Classified { + ref :>> annotatedElement : SysML::Usage; + ref classificationLevel : ClassificationLevel; + } + + metadata def Security; + } + + ref x { + metadata Classified { + classificationLevel = ClassificationLevel::conf; + } + } + + ref y { + @Classified { + classificationLevel = ClassificationLevel::conf; + } + @Security; + } + + private ref #Classified #Security z1; + abstract #Classified z2; + + ref z { + #Security #Classified metadata Classified { + classificationLevel = ClassificationLevel::secret; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/MultiplicityTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/MultiplicityTest.sysml new file mode 100644 index 00000000..f42d0ae8 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/MultiplicityTest.sysml @@ -0,0 +1,19 @@ +package MultiplicityTest { + + part def P; + attribute n : ScalarValues::Integer = 5; + + part a[1]; + part b[0..2] : P; + part c : P[2..*]; + part d[*]; + + part e[n]; + part f[n..*]; + part g[1..n]; + + attribute def A { + attribute i :ScalarValues::Integer; + attribute x : A[i]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/OccurrenceTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/OccurrenceTest.sysml new file mode 100644 index 00000000..46701ca5 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/OccurrenceTest.sysml @@ -0,0 +1,32 @@ +package OccurrenceTest { + occurrence def Occ { + attribute a; + ref occurrence occ1 : Occ; + occurrence occ2 : Occ; + item x; + part y; + + individual snapshot s : Ind; + timeslice t; + } + + occurrence occ : Occ { + occurrence o1 : Occ; + ref occurrence o2 : Occ; + item z; + } + + individual occurrence def Ind { + snapshot s2; + timeslice t2; + } + individual occurrence ind : Ind, Occ { + snapshot s3; + individual timeslice t3 :> ind; + individual snapshot s4 : Ind; + } + + occurrence o1 { + occurrence o2; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ParameterTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ParameterTest.sysml new file mode 100644 index 00000000..f1a6d1d5 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ParameterTest.sysml @@ -0,0 +1,16 @@ +package ParameterTest { + attribute def A { + attribute x : ScalarValues::String; + attribute y : A; + } + + attribute a : A; + + calc def F { in p : A; in q : ScalarValues::Integer; return : ScalarValues::Integer; } + + attribute f = F(a, 2); + attribute g = F(q = 1, p = a); + + attribute b = new A(y=a, x=""); + attribute c = new A("test2"); +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/PartTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/PartTest.sysml new file mode 100644 index 00000000..1ec56ab3 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/PartTest.sysml @@ -0,0 +1,55 @@ +package PartTest { + + part f: A; + + public part def A { + part <'1'> b: B; + protected port c: C; + constant attribute x[0..2]; + derived constant ref attribute y :> x; + ref z : ScalarValues::Integer; + } + + item def S; + + abstract part def B { + public abstract part a: A[1..2]; + public abstract part b subsets a; + public abstract part c[0..1] subsets a; + port x: ~C { + port p; + ref port q; + } + package P { } + + succession flow x.p to a1.aa.receiver; + + action a1 { + accept S via x; + action aa accept S; + } + perform action a2; + + state s1; + exhibit state s2; + } + + private port def C { + private in ref y: A, B { + part B_b redefines B::b; + part B_c redefines B::c; + port B_x redefines B::x; + } + alias z1 for y; + alias z2 for y; + port c1 : C; + ref port c2 : C; + } + + part p1 :> p2; + part p2 :> p3; + part p3 :> p1; + + part p4 :> p4; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/RequirementTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/RequirementTest.sysml new file mode 100644 index 00000000..e708fbcf --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/RequirementTest.sysml @@ -0,0 +1,38 @@ +package RequirementTest { + constraint def C; + constraint c : C; + private import q::**; + requirement def R { + assume constraint c1 : C; + require c; + doc /* */ + requirement; + requirement def <'1'> A { + doc /* Text */ + subject s; + } + } + requirement def R1 { + require constraint c1 :>> c; + } + part p; + part q { + requirement r : R; + satisfy r by p; + assert satisfy r by q; + } + + requirement r1 : R1; + not satisfy r1 by p; + assert not satisfy r1 by q; + + constraint c1; + constraint c2; + concern c3; + + requirement def R2 { + assume c1 [0..*]; + require c2 [0..*]; + frame c3[0..*]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/RootPackageTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/RootPackageTest.sysml new file mode 100644 index 00000000..4be14fa2 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/RootPackageTest.sysml @@ -0,0 +1,14 @@ +package P1 { + part def A; +} + +package P2 { + private import P1::*; + part a : A; +} + +private import P2::*; + +package P3 { + part b subsets a; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/StateTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/StateTest.sysml new file mode 100644 index 00000000..d65864d9 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/StateTest.sysml @@ -0,0 +1,72 @@ +package StateTest { + attribute def Sig { + x; + } + attribute def Exit; + + part p; + + action act; + + state def S { + do action A; + entry; then S1; + + state S1; + accept s : Sig + do action D + then S2; + + state S2 { + do send new Sig(T.s.x) to p; + state S3; + } + accept Exit then done; + + transition + first S1 + accept s : Sig + do action D + then S2.S3; + + transition T + first S2.S3 + accept s : Sig via p + if true + do send s to p + then S1; + + exit act; + + state S3 { + state S3a; + } + + transition first S3.S3a then S1; + } + + state s0 { + state s1 { + state s2; + } + state s3 { + state s4; + } + transition t1 first s1.s2 then s3.s4; + } + + state s parallel { + state s1; + state s2; + } + + state s4 { + do action a; + action c; + } + + state s5 :> s4 { + do action b :>> c; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/StructuredControlTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/StructuredControlTest.sysml new file mode 100644 index 00000000..7c2cade9 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/StructuredControlTest.sysml @@ -0,0 +1,36 @@ +package StructuredControlTest { + + action { + attribute i : ScalarValues::Integer := 0; + attribute b : ScalarValues::Boolean; + + if i < 0 { + assign i := 0; + } else if i == 0 { + assign i := 1; + } else { + assign i := i + 1; + } + + if i > 0 { + assign i := i + 1; + } + + then action aLoop + while i > 0 { + assign i := i - 1; + } until b; + + then while i > 0 { + assign i := i - 1; + } + + loop { + assign i := i - 1; + } until b; + + for n : ScalarValues::Integer in (1, 2, 3) { + assign i := i * n; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/TextualRepresentationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/TextualRepresentationTest.sysml new file mode 100644 index 00000000..9eed883d --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/TextualRepresentationTest.sysml @@ -0,0 +1,22 @@ +package TextualRepresentationTest { + private import ScalarValues::Real; + + item def C { + attribute x: Real; + assert constraint x_constraint { + rep inOCL language "ocl" + /* self.x > 0.0 */ + } + } + + action def setX { + in c : C; + in newX : Real; + + language "alf" + /* c.x = newX; + * WriteLine("Set new x"); + */ + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/TradeStudyTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/TradeStudyTest.sysml new file mode 100644 index 00000000..c9ce1ca0 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/TradeStudyTest.sysml @@ -0,0 +1,21 @@ +package TradeStudyTest { + private import ScalarValues::Real; + private import TradeStudies::*; + + part def Engine; + part engine1: Engine; + part engine2: Engine; + + analysis engineTradeStudy : TradeStudy { + subject : Engine[1..*] = (engine1, engine2); + objective : MaximizeObjective; + + calc :>> evaluationFunction { + in part : Engine; + return : Real; + } + + return part : Engine; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/UseCaseTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/UseCaseTest.sysml new file mode 100644 index 00000000..4705fa6d --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/UseCaseTest.sysml @@ -0,0 +1,43 @@ +package UseCaseTest { + + part def System; + part def User; + + use case def UseSystem { + subject system : System; + actor user : User; + + objective { + /* Goal */ + } + + include use case uc1 : UC1; + include use case uc2 { + subject = system; + actor user = UseSystem::user; + } + } + + use case def UC1; + + part user : User; + + use case uc2 { + subject; + actor :>> user; + } + + use case u : UseSystem; + + part system : System { + include uc2; + perform u; + use case uc1 : UC1; + } + + use case uc3 { + include u; + include system.uc1; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/VariabilityTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/VariabilityTest.sysml new file mode 100644 index 00000000..c6567c16 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/VariabilityTest.sysml @@ -0,0 +1,41 @@ +package VariabilityTest { + part def P { + attribute a; + } + + part def Q :> P; + attribute def B; + variation part def V :> P { + variant part x : Q { + attribute b : B :>> a; + } + } + + part q : Q; + variation part v : P { + variant q { + attribute b : B :>> a; + } + } + + part y : P = v::q; + + variation action def A { + variant action a1; + variant action a2; + } + + variation use case uc1 { + variant use case uc11; + variant use case uc12; + } + + variation analysis a1; + + variation verification v1; + + variation requirement r { + variant requirement r1; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/VerificationTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/VerificationTest.sysml new file mode 100644 index 00000000..1224ab31 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/VerificationTest.sysml @@ -0,0 +1,39 @@ +package VerificationTest { + + part def V { + m : ScalarValues::Integer; + } + + part vv : V; + + requirement def R { + doc /* ... */ + } + + requirement r : R; + + verification def VerificationCase { + subject v : V; + objective { + verify requirement : R; + } + + VerificationCases::PassIf(v.m == 0) + } + + verification def VerificationPlan { + subject v : V; + + objective { + verify r; + } + + verification verificationCase : VerificationCase; + } + + part verificationContext { + verification verificationPlan : VerificationPlan { + subject v = vv; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Simple Tests/ViewTest.sysml b/test-data/sysml2/official/sysml/examples/Simple Tests/ViewTest.sysml new file mode 100644 index 00000000..7a2c75eb --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Simple Tests/ViewTest.sysml @@ -0,0 +1,50 @@ +package ViewTest { + package P { + public part p1; + private part p2; + } + + part def S; + + concern def C { + subject; + stakeholder s : S; + } + + concern c : C { + subject; + stakeholder s1; + } + + viewpoint def VP { + frame c; + } + + rendering def R; + + rendering r : R; + + view def V { + viewpoint vp: VP { + frame concern c1; + concern c2; + } + render rendering r1: R[0..1]; + + view v: V[0..*] { + expose P::*; + render r; + + rendering r2; + + alias vp1 for p1; + // Note: "expose" imports all. + alias vp2 for p2; + } + } + + view v : V { + render r [0..*]; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/State Space Representation Examples/CartSample.sysml b/test-data/sysml2/official/sysml/examples/State Space Representation Examples/CartSample.sysml new file mode 100644 index 00000000..ce82d151 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/State Space Representation Examples/CartSample.sysml @@ -0,0 +1,64 @@ +// State Space Representation cart example + +package CartSample { + private import StateSpaceRepresentation::*; + part def Cart { + attribute mass :> ISQ::mass; + + attribute def CartInput :> Input { + attribute force :> ISQ::force; + } + + attribute def CartOutput :> Output { + attribute velocity :> ISQ::speed; + } + + attribute def CartState :> StateSpace { + attribute velocity :> ISQ::speed; + } + + attribute def CartStateDerivative :> StateDerivative { + ref :>> stateSpace : CartState; + attribute accel :> ISQ::acceleration; + } + } + + part def Pusher { + attribute def PusherOutput :> Output { + attribute force :> ISQ::force; + } + } + + part context { + part cart : Cart { + action cartBehavior : ContinuousStateSpaceDynamics { + in input : CartInput; + out output : CartOutput; + :>> stateSpace : CartState; + + calc :>> getDerivative { + in input: CartInput; + in stateSpace: CartState; + new CartStateDerivative(input.force / mass) + } + calc :>> getOutput { + in :>> stateSpace : CartState; + new CartOutput(stateSpace.velocity) + } + } + } + part pusher : Pusher { + attribute pusherForce :> ISQ::force; + + action pusherBehavior : ContinuousStateSpaceDynamics { + in input; + out output : PusherOutput; + calc :>> getOutput { + new PusherOutput(pusherForce) + } + } + } + + flow pusher.pusherBehavior.output to cart.cartBehavior.input; + } +} diff --git a/test-data/sysml2/official/sysml/examples/State Space Representation Examples/EVSample.sysml b/test-data/sysml2/official/sysml/examples/State Space Representation Examples/EVSample.sysml new file mode 100644 index 00000000..ffddc377 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/State Space Representation Examples/EVSample.sysml @@ -0,0 +1,319 @@ +// State Space Representation EV example +package EVSample { + private import SI::*; + private import StateSpaceRepresentation::*; + + attribute <'A⋅h'> 'ampere hour' : ElectricChargeUnit = A*h; + + part def Vehicle { + attribute mass :> ISQ::mass; + + attribute def VehicleInput :> Input { + attribute force :> ISQ::force; + } + + attribute def VehicleOutput :> Output { + attribute accel :> ISQ::acceleration; + attribute velocity :> ISQ::speed; + attribute distance :> ISQ::distance; + } + + attribute def VehicleState :> StateSpace { + attribute velocity :> ISQ::speed; + attribute distance :> ISQ::distance; + } + } + + part def Battery { + attribute baseVoltage :> ISQ::electricPotential; + attribute socInit: ScalarValues::Real; + attribute capacity :> ISQ::electricCharge; + attribute internalResistance :> ISQ::resistance; + + attribute def BatteryInput :> Input { + attribute current :> ISQ::electricCurrent; + } + + attribute def BatteryOutput :> Output { + attribute voltage :> ISQ::electricPotential; + } + + attribute def BatteryState :> StateSpace { + attribute soc: ScalarValues::Real; + } + + } + + part def Motor { + torquePerCurrent :> Quantities::scalarQuantities = ISQ::torque / ISQ::electricCurrent; + + attribute motR :> ISQ::resistance; + attribute motL :> ISQ::inductance; + + attribute def MotorInput :> Input { + attribute voltage :> ISQ::electricPotential; + attribute friction :> ISQ::torque; + } + + attribute def MotorOutput :> Output { + attribute current :> ISQ::electricCurrent; + attribute torque :> ISQ::torque; + } + + attribute def MotorState :> StateSpace { + attribute current :> ISQ::electricCurrent; + } + } + + part def Tire { + attribute radius :> ISQ::length; + attribute moment :> ISQ::momentOfInertia; + + attribute def TireInput :> Input { + attribute torque :> ISQ::torque; + attribute accel :> ISQ::acceleration; + } + + attribute def TireOutput :> Output { + attribute force :> ISQ::force; + attribute outTorque :> ISQ::torque; + } + } + + requirement def VehicleRequirement { + subject vehicle : Vehicle; + } + + analysis def VehicleAnalysis { + subject vehicle : Vehicle; + requirement vehicleRequirement : VehicleRequirement; + } + + + requirement def RangeRequirement :> VehicleRequirement { + doc /* The range of EV must be longer than the required spec under the flat road. */ + attribute actualRange : LengthValue; + attribute requiredRange : LengthValue; + + require constraint { actualRange >= requiredRange } + } + + analysis def RangeAnalysis :> VehicleAnalysis { + return simulatedRange : LengthValue; + + requirement rangeRequirement :>> vehicleRequirement : RangeRequirement; + + objective rangeAnalysisObjective { + doc /* This analysis is to estimate the range of + * the EV by simulating the vehicle driving under the compact vehicle regulation. + */ + require rangeRequirement { + :>> actualRange = simulatedRange; + } + } + } + + requirement def EfficiencyRequirement :> VehicleRequirement { + doc /* The efficiency of EV must be better than the required spec. */ + attribute actualEfficiency; + attribute requiredEfficiency; + + require constraint { actualEfficiency >= requiredEfficiency } + } + + analysis def EfficiencyAnalysis :> VehicleAnalysis { + return simulatedEfficiency; + + requirement efficiencyRequirement :>> vehicleRequirement : EfficiencyRequirement; + + objective efficiencyAnalysisObjective { + require efficiencyRequirement { + attribute :>> actualEfficiency = simulatedEfficiency; + } + } + } + + requirement def MaxSpeedRequirement :> VehicleRequirement { + doc /* The maximum speed of EV must be larger than the required spec. */ + attribute actualMaxSpeed :> ISQ::speed; + attribute requiredMaxSpeed :> ISQ::speed; + } + + analysis def MaxSpeedAnalysis :> VehicleAnalysis { + return simulatedMaxSpeed; + + requirement maxSpeedRequirement :>> vehicleRequirement : MaxSpeedRequirement; + + objective maxSpeedAnalysisObjective { + require maxSpeedRequirement { + attribute :>> actualMaxSpeed = simulatedMaxSpeed; + } + } + } + + + part vehicle : Vehicle { + attribute :>> mass default 1000[kg]; + + /* airFrictionCoefficient [kg / m] = 1/2 * rho[kg/m^3] * Cd * S[m^2], + * where rho is air density, S is front projected area. */ + attribute airFrictionCoefficient = 0.2; + + attribute efficiency; + + action vehicleBehavior : ContinuousStateSpaceDynamics { + in input : VehicleInput; + out output : VehicleOutput; + :>> stateSpace : VehicleState; + } + + part battery: Battery { + :>> baseVoltage = 300[V]; + :>> capacity = 50['A⋅h']; + :>> socInit = 0.8; + :>> internalResistance = 1.8['Ω']; + action batteryBehavior : ContinuousStateSpaceDynamics { + in input : BatteryInput; + out output : BatteryOutput; + :>> stateSpace : BatteryState; + } + } + + flow battery.batteryBehavior.output to motor.motorBehavior.input; + + part motor: Motor { + :>> motR = 4['Ω']; + :>> motL = 0.2[H]; + + action motorBehavior : ContinuousStateSpaceDynamics { + in input : MotorInput; + out output : MotorOutput; + :>> stateSpace : MotorState; + } + } + + flow motor.motorBehavior.output to tire.tireBehavior.input; + + part tire: Tire { + :>> moment default 300['kg⋅m²']; + :>> radius default 0.7[m]; + action tireBehavior : ContinuousStateSpaceDynamics { + in input : TireInput; + out output : TireOutput; + } + } + + flow tire.tireBehavior.output to motor.motorBehavior.input; + flow tire.tireBehavior.output to vehicleBehavior.input; + } + + part vehicle_compact :> vehicle { + attribute :>> mass = 800[kg]; + part :>> tire { + :>> moment = 200['kg⋅m²']; + :>> radius = 0.5[m]; + } + } + + part smallEVRangeContext { + requirement smallEVRequirement : VehicleRequirement { + doc /* The small EVs must be ligher than 900[kg] */ + subject :>> vehicle = vehicle_compact; + /* To comform with the regulation and the battery mass will impact it. */ + assume constraint { vehicle.mass < 900[kg] } + } + + analysis smallEVAnalysis : VehicleAnalysis { + subject :>> vehicle :> vehicle_compact; + requirement :>> vehicleRequirement = smallEVRequirement; + } + + requirement rangeRequirementSmall :> smallEVRequirement : RangeRequirement { + doc /* The small EVs must run longer than 130km */ + attribute :>> requiredRange = 130[km]; + } + + analysis rangeAnalysisSmall :> smallEVAnalysis : RangeAnalysis { + requirement :>> rangeRequirement = rangeRequirementSmall; + return simulatedRange = vehicle.vehicleBehavior.output.distance; + } + + requirement efficiencyRequirementSmall :> smallEVRequirement : EfficiencyRequirement { + doc /* The target efficiency of small EVs is 0.9. */ + attribute :>> requiredEfficiency = 0.9; + } + + analysis efficiencyAnalysisSmall :> smallEVAnalysis : EfficiencyAnalysis { + requirement :>> efficiencyRequirement = efficiencyRequirementSmall; + + return simulatedEfficiency = vehicle.efficiency; + } + + requirement maxSpeedRequirementSmall :> smallEVRequirement : MaxSpeedRequirement { + doc /* The target maximum speed of small EVs is 130 [km/h]. */ + attribute :>> requiredMaxSpeed = 130 [km/h]; + } + + analysis maxSpeedAnalysisSmall :> smallEVAnalysis : MaxSpeedAnalysis { + subject; + requirement :>> maxSpeedRequirement = maxSpeedRequirementSmall; + out voltage :> ISQ::electricPotential = vehicle.battery.batteryBehavior.output.voltage; + return simulatedMaxSpeed = vehicle.vehicleBehavior.output.velocity; + } + } + + part vehicle_large :> vehicle { + attribute :>> mass = 1100[kg]; + part :>> tire { + :>> moment = 300['kg⋅m²']; + :>> radius = 0.7[m]; + } + } + + part largeEVRangeContext { + requirement largeEVRequirement : VehicleRequirement { + doc /* The large EVs must be ligher than 900[kg] */ + subject :>> vehicle = vehicle_large; + /* To comform with the regulation and the battery mass will impact it. */ + assume constraint { vehicle.mass < 1200[kg] } + } + + analysis largeEVAnalysis : VehicleAnalysis { + subject :>> vehicle :> vehicle_large; + requirement :>> vehicleRequirement = largeEVRequirement; + } + + requirement rangeRequirementLarge :> largeEVRequirement : RangeRequirement { + doc /* The large EVs must run longer than 200km */ + attribute :>> requiredRange = 200[km]; + } + + analysis rangeAnalysisLarge :> largeEVAnalysis : RangeAnalysis { + requirement :>> rangeRequirement = rangeRequirementLarge; + return simulatedRange = vehicle.vehicleBehavior.output.distance; + } + + requirement efficiencyRequirementLarge :> largeEVRequirement : EfficiencyRequirement { + doc /* The target efficiency of large EVs is 0.8. */ + attribute :>> requiredEfficiency = 0.8; + } + + analysis efficiencyAnalysisLarge :> largeEVAnalysis : EfficiencyAnalysis { + requirement :>> efficiencyRequirement = efficiencyRequirementLarge; + + return simulatedEfficiency = vehicle.efficiency; + } + + requirement maxSpeedRequirementLarge :> largeEVRequirement : MaxSpeedRequirement { + doc /* The target maximum speed of large EVs is 140 [km/h]. */ + attribute :>> requiredMaxSpeed = 140 [km/h]; + } + + analysis maxSpeedAnalysisLarge :> largeEVAnalysis : MaxSpeedAnalysis { + subject; + requirement :>> maxSpeedRequirement = maxSpeedRequirementLarge; + out voltage = vehicle.battery.batteryBehavior.output.voltage; + return simulatedMaxSpeed = vehicle.vehicleBehavior.output.velocity; + } + } +} diff --git a/test-data/sysml2/official/sysml/examples/Timeslice and Snapshot Examples/TimeVaryingAttribute.sysml b/test-data/sysml2/official/sysml/examples/Timeslice and Snapshot Examples/TimeVaryingAttribute.sysml new file mode 100644 index 00000000..aa5b6c7f --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Timeslice and Snapshot Examples/TimeVaryingAttribute.sysml @@ -0,0 +1,51 @@ +package TimeVaryingAttribute { + private import SI::s; + + item def PwrCmd { + attribute pwrLevel: ScalarValues::Integer; + } + + part def Transport2 { + private import Time::*; + attribute startTime = TimeOf(start); + attribute elapseTime :> ISQ::duration; + attribute :>> localClock.currentTime = startTime + elapseTime; + + out item pwrCmd:PwrCmd; + // Lifetime conditions + timeslice :>> portionOfLife { + snapshot :>> start { + :>> elapseTime = 0 [s]; + :>> pwrCmd.pwrLevel = 0; + } + snapshot :>> done { + :>> elapseTime = 2 [s]; + :>> pwrCmd.pwrLevel = 1; + } + } + + // Alternative: + // // initial conditions + // :>> portionOfLife.start : C { + // :>> elapseTime = 0 [s]; + // :>> pwrCmd.pwrLevel = 0; + // } + + timeslice transportPeriod { + snapshot :>> start{ + :>> elapseTime = 1 [s]; + } + snapshot :>> done { + :>> elapseTime = 1.5 [s]; + } + :>> pwrCmd.pwrLevel = 2*elapseTime.num; + } + +// Alternative: +// // final conditions +// :>> portionOfLife.done { +// :>> elapseTime = 2 [s]; +// :>> pwrCmd.pwrLevel = 1; +// } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Variability Examples/VehicleVariabilityModel.sysml b/test-data/sysml2/official/sysml/examples/Variability Examples/VehicleVariabilityModel.sysml new file mode 100644 index 00000000..f07311af --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Variability Examples/VehicleVariabilityModel.sysml @@ -0,0 +1,165 @@ +package VehicleVariabilityModel { + + package DesignModel { + public import PartDefinitions::*; + public import PartsTree::*; + public import ActionDefinitions::*; + public import ActionTree::*; + + package PartDefinitions { + part def Vehicle; + + attribute def Diameter; + part def Cylinder { + attribute diameter : Diameter[1]; + } + + part def Engine; + part def Transmission; + part def Sunroof; + + port def AutoPort; + } + + package PartsTree { + part vehicle : Vehicle { + part engine : Engine[1]; + part transmission : Transmission[1]; + part sunroof : Sunroof[0..1]; + } + + part engine : Engine { + port autoPort : AutoPort; + part cylinder : Cylinder[2..*]; + } + + part '4cylEngine' :> engine { + part :>> cylinder[4]; + } + + part '6cylEngine' :> engine { + part :>> cylinder[6]; + } + + part transmission : Transmission; + part manualTransmission :> transmission; + part automaticTransmission :> transmission; + } + + package ActionDefinitions { + action def GenerateTorque; + action def AmplifyTorque; + action def ProvidePower; + } + + package ActionTree { + action generateTorque4Cyl : GenerateTorque; + action generateTorque6Cyl : GenerateTorque; + + action amplifyTorqueManual : AmplifyTorque; + action amplifyTorqueAutomatic : AmplifyTorque; + } + } + + package '150% Model' { + private import DesignModel::*; + + package PartsTree { + + // Variation point definitions + + variation attribute def DiameterChoices :> Diameter { + variant attribute diameterSmall; + variant attribute diameterLarge; + } + + variation part def EngineChoices :> Engine { + variant '4cylEngine'; + variant '6cylEngine' { + variation port :>> autoPort { + variant port autoPort1; + variant port autoPort2; + } + + part :>> cylinder { + attribute :>> diameter : DiameterChoices; + } + + assert constraint { + (autoPort == autoPort::autoPort1 and cylinder.diameter == cylinder::diameter::diameterSmall) xor + (autoPort == autoPort::autoPort2 and cylinder.diameter == cylinder::diameter::diameterLarge) + } + } + } + + // Part superset model + + abstract part vehicleFamily :> vehicle { + // Variation point usage + part :>> engine : EngineChoices[1]; + + // Variation point with embedded variant definitions + variation part :>> transmission : Transmission[1] { + variant manualTransmission; + variant automaticTransmission; + } + + assert constraint { + (engine == engine::'4cylEngine' and transmission == transmission::manualTransmission) xor + (engine == engine::'6cylEngine' and transmission == transmission::automaticTransmission) + } + + // Variation point on variant multiplicity (inherited multiplicity is [0..1]) + variation part :>> sunroof { + variant part withSunroof[1]; + variant part withoutSunroof[0]; + } + + perform ActionTree::providePowerFamily; + } + } + + package ActionTree { + + // Action superset Model + + action providePowerFamily : ProvidePower { + variation action generateTorque : GenerateTorque { + variant generateTorque4Cyl; + variant generateTorque6Cyl; + } + + variation action amplifyTorque : AmplifyTorque { + variant amplifyTorqueManual; + variant amplifyTorqueAutomatic; + } + + assert constraint { + (generateTorque == generateTorque::generateTorque4Cyl and + amplifyTorque == amplifyTorque::amplifyTorqueManual + ) xor + (generateTorque == generateTorque::generateTorque6Cyl and + amplifyTorque == amplifyTorque::amplifyTorqueAutomatic + ) + } + } + } + } + + package '100% Model' { + private import '150% Model'::*; + + // Vehicle instance model + + part vehicle4Cyl :> PartsTree::vehicleFamily { + part :>> engine = engine::'4cylEngine'; + part :>> transmission = transmission::manualTransmission; + part :>> sunroof = sunroof::withoutSunroof; + + perform action :>> providePowerFamily { + action :>> generateTorque = generateTorque::generateTorque4Cyl; + action :>> amplifyTorque = amplifyTorque::amplifyTorqueManual; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Vehicle Example/SysML v2 Spec Annex A SimpleVehicleModel.sysml b/test-data/sysml2/official/sysml/examples/Vehicle Example/SysML v2 Spec Annex A SimpleVehicleModel.sysml new file mode 100644 index 00000000..f3fb8695 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Vehicle Example/SysML v2 Spec Annex A SimpleVehicleModel.sysml @@ -0,0 +1,1581 @@ +package SimpleVehicleModel{ + // 2023-02 release + public import Definitions::*; + public import ISQ::*; + package Definitions{ + public import PartDefinitions::*; + public import PortDefinitions::*; + public import ItemDefinitions::*; + public import SignalDefinitions::*; + public import InterfaceDefinitions::*; + public import AllocationDefinitions::*; + public import ActionDefinitions::*; + public import StateDefinitions::*; + public import RequirementDefinitions::*; + public import AttributeDefinitions::*; + public import IndividualDefinitions::*; + public import MetadataDefinitions::**; + public import KeyWord_MetadataDefinitions::*; + package PartDefinitions{ + part def Vehicle { + attribute mass :> ISQ::mass; + attribute dryMass:>ISQ::mass; + attribute cargoMass:>ISQ::mass; + attribute position:>ISQ::length; + attribute velocity:>ISQ::speed; + attribute acceleration:>ISQ::acceleration; + attribute electricalPower:>ISQ::power; + attribute Tmax:>ISQ::temperature; + attribute maintenanceTime: Time::DateTime; + attribute brakePedalDepressed: Boolean; + port ignitionCmdPort:IgnitionCmdPort; + port pwrCmdPort:PwrCmdPort; + port vehicleToRoadPort:VehicleToRoadPort; + port statusPort:StatusPort; + perform action providePower; + perform action provideBraking; + perform action controlDirection; + perform action performSelfTest; + perform action applyParkingBrake; + perform action senseTemperature; + exhibit state vehicleStates parallel { + ref controller : VehicleController; + state operatingStates { + entry action initial; + state off; + state starting; + state on { + entry performSelfTest; + do providePower; + exit applyParkingBrake; + constraint {electricalPower<=500[W]} + } + + transition initial then off; + + transition off_To_starting + first off + accept ignitionCmd:IgnitionCmd via ignitionCmdPort + if ignitionCmd.ignitionOnOff==IgnitionOnOff::on and brakePedalDepressed + do send new StartSignal() to controller + then starting; + + transition starting_To_on + first starting + accept VehicleOnSignal + then on; + + transition on_To_off + first on + accept VehicleOffSignal + do send new OffSignal() to controller + then off; + } + + state healthStates { + entry action initial; + do senseTemperature{ + out temp; + } + + state normal; + state maintenance; + state degraded; + + transition initial then normal; + + transition normal_To_maintenance + first normal + accept at maintenanceTime + then maintenance; + + transition normal_To_degraded + first normal + accept when senseTemperature.temp > Tmax + do send new OverTemp() to controller + then degraded; + + transition maintenance_To_normal + first maintenance + accept ReturnToNormal + then normal; + + transition degraded_To_normal + first degraded + accept ReturnToNormal + then normal; + } + } + } + part def Engine{ + attribute mass :> ISQ::mass; + attribute peakHorsePower:>ISQ::power; + attribute fuelEfficiency:Real; + attribute cost:Real; + attribute displacement :> ISQ::volume; + port engineControlPort: ~ControlPort; + port fuelInPort: ~ FuelPort; + port fuelCmdPort:FuelCmdPort; + port drivePwrPort:DrivePwrPort; + port ignitionCmdPort:IgnitionCmdPort; + port flyWheelPort; + perform action generateTorque; + exhibit state engineStates{ + state off; + state starting; + state on{ + do generateTorque; + } + } + } + part def StarterMotor{ + port gearPort:GearPort; + } + part def Cylinder; + part def Transmission{ + attribute gearRatio:Real; + port clutchPort:~DrivePwrPort; + exhibit state transmissionStates; + } + part def Driveshaft; + part def AxleAssembly; + part def Axle{ + attribute mass:>ISQ::mass; + } + part def FrontAxle:>Axle{ + attribute steeringAngle:>ISQ::angularMeasure; + } + part def HalfAxle{ + port shankCompositePort:ShankCompositePort{ + } + } + part def Differential; + part def Wheel{ + attribute diameter:LengthValue; + port lugNutCompositePort:LugNutCompositePort; + } + part def Hub{ + port shankCompositePort:ShankCompositePort; + } + abstract part def Software; + part def VehicleSoftware:>Software; + part def VehicleController:>Software { + port controlPort:ControlPort; + exhibit state controllerStates parallel { + state operatingStates { + entry action initial; + state off; + state on; + transition initial then off; + transition 'off-on' + first off + accept StartSignal + then on; + transition 'on-off' + first on + accept OffSignal + then off; + } + } + } + part def CruiseController:>Software { + port setSpeedPort:~SetSpeedPort; + port speedSensorPort:~SpeedSensorPort; + port cruiseControlPort:CruiseControlPort; + exhibit state cruiseControllerStates; + } + part def SpeedSensor{ + port speedSensorPort:SpeedSensorPort; + } + part def FuelTank{ + attribute mass :> ISQ::mass; + ref item fuel:Fuel{ + attribute :>> fuelMass; + } + attribute fuelKind:FuelKind; + attribute fuelMassMax:>ISQ::mass; + assert constraint fuelConstraint {fuel.fuelMass<=fuelMassMax} + port fuelOutPort:FuelPort; + port fuelInPort:~FuelPort; + } + part def BodyAssy; + part def Body{ + attribute color:Colors; + } + part def Thermostat; + part def WaterHose; + part def Road{ + attribute incline:Real; + attribute friction:Real; + } + part def Engine4Cyl; + part def Engine6Cyl; + part def TransmissionChoices; + part def TransmissionAutomatic; + part def TransmissionManual; + part def Sunroof; + + //logical Components + part def ElectricalGenerator; + part def TorqueGenerator; + part def SteeringSubsystem; + part def BrakingSubsystem; + } + package PortDefinitions{ + port def IgnitionCmdPort{ + in item ignitionCmd:IgnitionCmd; + } + port def StatusPort; + port def GearPort; + port def PwrCmdPort{ + in item pwrCmd:PwrCmd; + } + port def FuelCmdPort:>PwrCmdPort{ + in item fuelCmd:FuelCmd redefines pwrCmd; + } + port def FuelPort{ + out item fuel:Fuel; + } + port def DrivePwrPort{ + out torque:Torque; + } + port def ShaftPort_a; + port def ShaftPort_b; + port def ShaftPort_c; + port def ShaftPort_d; + port def DiffPort; + port def AxlePort; + port def AxleToWheelPort; + port def WheelToAxlePort; + port def WheelToRoadPort; + + port def LugNutCompositePort{ + port lugNutPort:LugNutPort [*]; + } + port def ShankCompositePort{ + port shankPort:ShankPort [*]; + } + port def LugNutPort{ + attribute threadDia; + attribute threadPitch; + } + port def ShankPort{ + attribute threadDia; + attribute threadPitch; + attribute shaftLength; + } + + port def VehicleToRoadPort; + port def ControlPort; + port def CruiseControlPort:>ControlPort; + port def SpeedSensorPort; + port def SetSpeedPort; + + port def DriverCmdPort{ + out item driverCmd[*]:DriverCmd; + } + port def HandPort :> DriverCmdPort { + out item ignitionCmd:IgnitionCmd subsets driverCmd; + out item pwrCmd:PwrCmd subsets driverCmd; + } + } + package ItemDefinitions{ + item def PwrCmd{ + attribute throttleLevel:Real; + } + item def FuelCmd:>PwrCmd; + item def Fuel{ + attribute fuelMass:>ISQ::mass; + } + item def SensedSpeed{ + attribute speed:>ISQ::speed; + } + } + package SignalDefinitions{ + item def Cmd{ + } + item def DriverCmd; + item def IgnitionCmd:>DriverCmd{ + attribute ignitionOnOff:IgnitionOnOff; + } + item def EngineStatus; + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + attribute def StartSignal; + attribute def OffSignal; + attribute def OverTemp; + attribute def ReturnToNormal; + attribute def SetSpeed:>Real; + } + package InterfaceDefinitions{ + interface def EngineToTransmissionInterface{ + end p1:DrivePwrPort; + end p2:~DrivePwrPort; + flow p1.torque to p2.torque; + } + interface def FuelInterface { + end fuelOutPort:FuelPort; + end fuelInPort:~FuelPort; + flow of Fuel from fuelOutPort.fuel to fuelInPort.fuel; + } + + interface def WheelFastenerInterface{ + end lugNutPort:LugNutPort; + end shankPort:ShankPort; + attribute maxTorque : Torque; + constraint {lugNutPort.threadDia == shankPort.threadDia} + } + interface def WheelHubInterface{ + end lugNutCompositePort:LugNutCompositePort; + end shankCompositePort:ShankCompositePort; + interface wheelFastenerInterface:WheelFastenerInterface [5] + connect lugNutCompositePort.lugNutPort to shankCompositePort.shankPort; + } + } + package AllocationDefinitions{ + allocation def LogicalToPhysical{ + end #logical logicalEnd; + end #physical physicalEnd; + } + } + package ActionDefinitions{ + action def ProvidePower { + in item pwrCmd:PwrCmd; + out wheelToRoadTorque:Torque[2]; + } + action def GenerateTorque { + in item fuelCmd:FuelCmd; + out engineTorque:Torque; + } + action def AmplifyTorque { + in engineTorque:Torque; + out transmissionTorque:Torque; + } + action def TransferTorque { + in transmissionTorque:Torque; + out driveshaftTorque:Torque; + } + action def DistributeTorque { + in driveshaftTorque:Torque; + out wheelToRoadTorque:Torque[2]; + } + action def PerformSelfTest; + action def ApplyParkingBrake; + action def SenseTemperature{ + out temp: ISQ::TemperatureValue; + } + } + package StateDefinitions { + state def VehicleStates; + state def ControllerStates; + state def CruiseControllerStates; + } + package RequirementDefinitions{ + requirement def MassRequirement{ + doc /*The actual mass shall be less than the required mass*/ + attribute massRequired:>ISQ::mass; + attribute massActual:>ISQ::mass; + require constraint {massActual<=massRequired} + } + requirement def ReliabilityRequirement{ + doc /*The actual reliability shall be greater than the required reliability*/ + attribute reliabilityRequired:Real; + attribute reliabilityActual:Real; + require constraint {reliabilityActual>=reliabilityRequired} + } + requirement def TorqueGenerationRequirement { + doc /* The engine shall generate torque as a function of RPM as shown in Table 1. */ + subject generateTorque:ActionDefinitions::GenerateTorque; + } + requirement def DrivePowerOutputRequirement { + doc /* The engine shall provide a connection point to transfer torque to the transmission.*/ + } + requirement def FuelEconomyRequirement { + doc /* The vehicle shall maintain an average fuel economomy of at least x miles per gallon for the nominal + driving scenario */ + attribute actualFuelEconomy :> distancePerVolume; + attribute requiredFuelEconomy :> distancePerVolume; + require constraint {actualFuelEconomy >= requiredFuelEconomy} + } + } + package AttributeDefinitions{ + public import ScalarValues::*; + public import Quantities::*; + public import MeasurementReferences::DerivedUnit; + public import SIPrefixes::kilo; + // Numerical Functions provides basic operators such as Sum expression + public import NumericalFunctions::*; + public import SI::*; + public import USCustomaryUnits::*; + alias Torque for ISQ::TorqueValue; + + enum def Colors {black;grey;red;} + enum def DiameterChoices:>ISQ::LengthValue{ + enum = 60 [mm]; + enum = 80 [mm]; + enum = 100 [mm]; + } + attribute cylinderDiameter: DiameterChoices = 80 [mm]; + enum def IgnitionOnOff {on;off;} + enum def FuelKind {gas;diesel;} + + distancePerVolume :> scalarQuantities = distance / volume; + timePerDistance :> scalarQuantities = time / distance; + volumePerDistance :> scalarQuantities = volume / distance; + volumePerTime :> scalarQuantities = volume / time; + + // kpl is approx .425 * mpg + kpl : DerivedUnit = km / L; + rpm : DerivedUnit = 1 / SI::min; + kW : DerivedUnit = kilo * W; + + } + package IndividualDefinitions{ + individual def VehicleRoadContext_1:>GenericContext::Context; + individual def Vehicle_1:>Vehicle; + individual def FrontAxleAssembly_1:>AxleAssembly; + individual def FrontAxle_1:>FrontAxle; + individual def Wheel_1:>Wheel; + individual def Wheel_2:>Wheel; + individual def RearAxleAssembly_1:>AxleAssembly; + individual def Road_1:>Road; + } + package MetadataDefinitions { + public import AnalysisTooling::*; + metadata def Safety { + attribute isMandatory : Boolean; + } + metadata def Security; + } + package KeyWord_MetadataDefinitions{ + public import Metaobjects::SemanticMetadata; + + // the following is used to define the key word failureMode + state failureModes[*] nonunique; + + // with alias + metadata def failureMode :> SemanticMetadata { + :>> baseType = failureModes meta SysML::StateUsage; + } + + occurrence logicalOccurrences [*] nonunique; + + metadata def logical :> SemanticMetadata { + :>> baseType = logicalOccurrences meta SysML::Usage; + } + + occurrence physicalOccurrences [*] nonunique; + + metadata def

physical :> SemanticMetadata { + :>> baseType = physicalOccurrences meta SysML::Usage; + } + } + package GenericContext { + + part def Context { + attribute time:TimeValue; + attribute spatialCF: CartesianSpatial3dCoordinateFrame[1] { :>> mRefs = (m, m, m); } + attribute velocityCF: CartesianVelocity3dCoordinateFrame[1] = spatialCF/s; + attribute accelarationCF: CartesianAcceleration3dCoordinateFrame[1] = velocityCF/s; + } + } + } + + package VehicleLogicalConfiguration{ + package PartsTree{ + #logical part vehicleLogical:Vehicle{ + part torqueGenerator:TorqueGenerator{ + action generateTorque; + } + part electricalGenerator:ElectricalGenerator{ + action generateElectricity; + } + part steeringSystem:SteeringSubsystem; + part brakingSubsystem:BrakingSubsystem; + } + } + } + package VehicleLogicalToPhysicalAllocation{ + public import VehicleConfigurations::VehicleConfiguration_b::PartsTree::**; + public import VehicleLogicalConfiguration::PartsTree::*; + + allocation vehicleLogicalToPhysicalAllocation:LogicalToPhysical + allocate vehicleLogical to vehicle_b{ + allocate vehicleLogical.torqueGenerator to vehicle_b.engine{ + allocate vehicleLogical.torqueGenerator.generateTorque to vehicle_b.engine.generateTorque; + } + allocate vehicleLogical.electricalGenerator to vehicle_b.engine{ + allocate vehicleLogical.electricalGenerator.generateElectricity to vehicle_b.engine.alternator.generateElectricity; + } + } + } + package VehicleConfigurations{ + package VehicleConfiguration_a{ + package PartsTree{ + part vehicle_a:Vehicle{ + attribute mass redefines Vehicle::mass=dryMass+cargoMass+fuelTank.fuel.fuelMass; + attribute dryMass redefines Vehicle::dryMass=sum(partMasses); + attribute redefines Vehicle::cargoMass=0 [kg]; + attribute partMasses [*] nonunique :>ISQ::mass; + part fuelTank:FuelTank{ + attribute redefines mass=75[kg]; + ref item redefines fuel{ + attribute redefines fuelMass=50[kg]; + } + } + part frontAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=800[kg]; + part frontAxle:Axle; + part frontWheels:Wheel[2]; + } + part rearAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=875[kg]; + attribute driveTrainEfficiency:Real = 0.6; + part rearAxle:Axle; + part rearWheels:Wheel[2]{ + attribute redefines diameter; + } + } + } + } + package ActionTree{ + } + package Requirements{ + } + } + package VehicleConfiguration_b{ + //Shapes library for simple geometry + public import ShapeItems::Box; + public import ParametersOfInterestMetadata::mop; + public import ModelingMetadata::*; // incudes status info + + package PartsTree{ + part vehicle_b : Vehicle{ + #mop attribute mass redefines mass=dryMass+cargoMass+fuelTank.fuel.fuelMass; + attribute dryMass redefines dryMass=sum(partMasses); + attribute redefines cargoMass default 0 [kg]; + attribute partMasses=(fuelTank.mass,frontAxleAssembly.mass,rearAxleAssembly.mass,engine.mass,transmission.mass,driveshaft.mass); + attribute avgFuelEconomy :> distancePerVolume; + port fuelCmdPort: FuelCmdPort redefines pwrCmdPort { + in item fuelCmd redefines pwrCmd; + } + port setSpeedPort:~SetSpeedPort; + port vehicleToRoadPort redefines vehicleToRoadPort{ + port wheelToRoadPort1:WheelToRoadPort; + port wheelToRoadPort2:WheelToRoadPort; + } + perform ActionTree::providePower redefines providePower; + perform ActionTree::performSelfTest redefines performSelfTest; + perform ActionTree::applyParkingBrake redefines applyParkingBrake; + perform ActionTree::senseTemperature redefines senseTemperature; + exhibit state vehicleStates redefines vehicleStates; + + // Example vehicle with simple enveloping shape that is a solid + item :> envelopingShapes : Box[1] { + length1:>> length = 4800 [mm]; + width1:>> width = 1840 [mm]; + height1:>> height = 1350 [mm]; + } + + part fuelTank:FuelTank{ + attribute redefines mass=75[kg]; + ref item redefines fuel{ + attribute redefines fuelMass=60[kg]; + } + attribute redefines fuelMassMax=60 [kg]; + } + part frontAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=800[kg]; + port shaftPort_d:ShaftPort_d; + part frontAxle:FrontAxle; + part frontWheels:Wheel[2]; + } + + part rearAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=875[kg]; + attribute driveTrainEfficiency:Real = 0.6; + port shaftPort_d:ShaftPort_d; + perform providePower.distributeTorque; + part rearWheel1:Wheel{ + attribute redefines diameter; + port wheelToRoadPort:WheelToRoadPort; + port lugNutCompositePort :>> lugNutCompositePort{ + port lugNutPort :>> lugNutPort [5]; + } + } + part rearWheel2:Wheel{ + attribute redefines diameter; + port wheelToRoadPort:WheelToRoadPort; + port lugNutCompositePort :>> lugNutCompositePort{ + port lugNutPort :>> lugNutPort [5]; + } + } + part differential:Differential{ + port shaftPort_d:ShaftPort_d; + port leftDiffPort:DiffPort; + port rightDiffPort:DiffPort; + } + part rearAxle{ + part leftHalfAxle:HalfAxle{ + port leftAxleToDiffPort:AxlePort; + port shankCompositePort :>> shankCompositePort{ + port shankPort :>> shankPort [5]; + } + } + part rightHalfAxle:HalfAxle{ + port rightAxleToDiffPort:AxlePort; + port shankCompositePort :>> shankCompositePort { + port shankPort :>> shankPort [5]; + } + } + } + + bind shaftPort_d=differential.shaftPort_d; + connect differential.leftDiffPort to rearAxle.leftHalfAxle.leftAxleToDiffPort; + connect differential.rightDiffPort to rearAxle.rightHalfAxle.rightAxleToDiffPort; + + interface wheelToleftHalAxleInterface:WheelHubInterface + connect [1] rearWheel1.lugNutCompositePort to [1] rearAxle.leftHalfAxle.shankCompositePort; + interface wheelTorightHalAxleInterface:WheelHubInterface + connect [1] rearWheel2.lugNutCompositePort to [1] rearAxle.rightHalfAxle.shankCompositePort; + + } + part starterMotor:StarterMotor; + part engine:Engine{ + perform providePower.generateTorque redefines generateTorque; + part cylinders:Cylinder[4..6]; + part alternator{ + action generateElectricity; + } + satisfy Requirements::engineSpecification by vehicle_b.engine{ + requirement torqueGenerationRequirement :>> torqueGenerationRequirement{ + subject generateTorque redefines generateTorque = vehicle_b.engine.generateTorque; + } + requirement drivePowerOuputRequirement :>> drivePowerOutputRequirement{ + port torqueOutPort redefines torqueOutPort=vehicle_b.engine.drivePwrPort; + } + } + } + part transmission:Transmission{ + attribute mass :> ISQ::mass=100[kg]; + port shaftPort_a:ShaftPort_a; + perform providePower.amplifyTorque; + } + part driveshaft:Driveshaft{ + attribute mass :> ISQ::mass=100[kg]; + port shaftPort_b:ShaftPort_b; + port shaftPort_c:ShaftPort_c; + perform providePower.transferTorque; + } + part vehicleSoftware:VehicleSoftware{ + part vehicleController: VehicleController { + exhibit state controllerStates redefines controllerStates; + part cruiseController:CruiseController; + } + } + part speedSensor:SpeedSensor; + + // parts in bodyAssy and interioer are marked as safety or security features + part bodyAssy:BodyAssy{ + part body:Body{ + attribute :>> color = Colors::red; + } + part bumper {@Safety{isMandatory = true;}} + part keylessEntry {@Security;} + } + part interior { + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + + //connections + bind engine.fuelCmdPort=fuelCmdPort; + + interface engineToTransmissionInterface:EngineToTransmissionInterface + connect engine.drivePwrPort to transmission.clutchPort; + + interface fuelInterface:FuelInterface + connect fuelTank.fuelOutPort to engine.fuelInPort; + + allocate ActionTree::providePower.generateToAmplify to engineToTransmissionInterface; + + bind engine.ignitionCmdPort=ignitionCmdPort; + connect starterMotor.gearPort to engine.flyWheelPort; + connect vehicleSoftware.vehicleController.controlPort to engine.engineControlPort; + bind vehicle_b.setSpeedPort = vehicleSoftware.vehicleController.cruiseController.setSpeedPort; + connect speedSensor.speedSensorPort to vehicleSoftware.vehicleController.cruiseController.speedSensorPort; + bind vehicleSoftware.vehicleController.cruiseController.cruiseControlPort = vehicleSoftware.vehicleController.controlPort; + connect transmission.shaftPort_a to driveshaft.shaftPort_b; + connect driveshaft.shaftPort_c to rearAxleAssembly.shaftPort_d; + bind rearAxleAssembly.rearWheel1.wheelToRoadPort=vehicleToRoadPort.wheelToRoadPort1; + bind rearAxleAssembly.rearWheel2.wheelToRoadPort=vehicleToRoadPort.wheelToRoadPort2; + + satisfy Requirements::vehicleSpecification by vehicle_b{ + requirement vehicleMassRequirement:>>vehicleMassRequirement{ + attribute redefines massActual=vehicle_b.mass; + attribute redefines fuelMassActual = vehicle_b.fuelTank.fuel.fuelMass; + } + } + } + } + package ActionTree{ + action providePower:ProvidePower{ + in item fuelCmd:FuelCmd redefines pwrCmd; + out wheelToRoadTorque redefines wheelToRoadTorque [2] = distributeTorque.wheelToRoadTorque; + action generateTorque:GenerateTorque { + in item = providePower.fuelCmd; + } + action amplifyTorque:AmplifyTorque; + action transferTorque:TransferTorque; + action distributeTorque:DistributeTorque; + + //named flow + flow generateToAmplify from generateTorque.engineTorque to amplifyTorque.engineTorque; + //unnamed flows + flow amplifyTorque.transmissionTorque to transferTorque.transmissionTorque; + flow transferTorque.driveshaftTorque to distributeTorque.driveshaftTorque; + } + action performSelfTest: PerformSelfTest; + action applyParkingBrake: ApplyParkingBrake; + action senseTemperature: SenseTemperature; + } + package DiscreteInteractions{ + package Sequence{ + part def Driver{ + port p1; + port p2; + } + + part part0{ + perform action startVehicle{ + action turnVehicleOn send ignitionCmd via driver.p1{ + in ignitionCmd:IgnitionCmd; + } + action trigger1 accept ignitionCmd:IgnitionCmd via vehicle.ignitionCmdPort; + flow of IgnitionCmd from trigger1.ignitionCmd to startEngine.ignitionCmd; + action startEngine{ + in item ignitionCmd:IgnitionCmd; + out item es:EngineStatus; + } + flow of EngineStatus from startEngine.es to sendStatus.es; + action sendStatus send es via vehicle.statusPort{ + in es:EngineStatus; + } + action trigger2 accept es:EngineStatus via driver.p2; + } + part driver : Driver { + perform startVehicle.turnVehicleOn; + perform startVehicle.trigger2; + event occurrence driverReady; + } + part vehicle : Vehicle { + perform startVehicle.trigger1; + perform startVehicle.sendStatus; + event occurrence doorClosed; + } + first vehicle.doorClosed then driver.driverReady; + message of ignitionCmd:IgnitionCmd from driver.turnVehicleOn to vehicle.trigger1; + message of es:EngineStatus from vehicle.sendStatus to driver.trigger2; + } + } + occurrence CruiseControl1{ + part vehicle_b:>PartsTree::vehicle_b{ + port redefines setSpeedPort{ + event occurrence setSpeedReceived; + } + part redefines speedSensor{ + port redefines speedSensorPort{ + event occurrence sensedSpeedSent; + } + } + part redefines vehicleSoftware{ + part redefines vehicleController{ + part redefines cruiseController{ + port redefines setSpeedPort{ + //analagous to gate: event occurrence bound but may not need this since the port is bound + event occurrence setSpeedReceived = vehicle_b.setSpeedPort.setSpeedReceived; + } + port redefines speedSensorPort{ + event occurrence sensedSpeedReceived; + } + port redefines cruiseControlPort{ + event occurrence fuelCmdSent; + } + } + } + } + part redefines engine{ + port redefines fuelCmdPort{ + event occurrence fuelCmdReceived; + } + } + message sendSensedSpeed of SensedSpeed + from speedSensor.speedSensorPort.sensedSpeedSent to vehicleSoftware.vehicleController.cruiseController.speedSensorPort.sensedSpeedReceived; + message sendFuelCmd of FuelCmd + from vehicleSoftware.vehicleController.cruiseController.cruiseControlPort.fuelCmdSent to engine.fuelCmdPort.fuelCmdReceived; + } + } + occurrence CruiseControl2{ + part vehicle_b:>PartsTree::vehicle_b{ + port redefines setSpeedPort{ + event occurrence setSpeedReceived; + } + part redefines speedSensor{ + port redefines speedSensorPort{ + event sendSensedSpeed.sourceEvent; + } + } + part redefines vehicleSoftware{ + part redefines vehicleController{ + part redefines cruiseController{ + port redefines setSpeedPort{ + //analagous to gate: event occurrence bound but may not need this since the port is bound + event occurrence setSpeedReceived = vehicle_b.setSpeedPort.setSpeedReceived; + } + port redefines speedSensorPort{ + event occurrence setSpeedReceived=setSpeedPort.setSpeedReceived; + then event sendSensedSpeed.targetEvent; + } + port redefines cruiseControlPort{ + event sendFuelCmd.sourceEvent; + } + } + } + } + part redefines engine{ + port redefines fuelCmdPort{ + event sendFuelCmd.targetEvent; + } + } + message sendSensedSpeed of SensedSpeed; + message sendFuelCmd of FuelCmd; + } + } + } + package Requirements{ + public import RequirementDerivation::*; + public import ModelingMetadata::*; // incudes status info + item marketSurvey; + dependency from vehicleSpecification to marketSurvey; + + requirement vehicleSpecification{ + subject vehicle:Vehicle; + requirement <'1'> vehicleMassRequirement: MassRequirement { + doc /* The total mass of the vehicle shall be less than or equal to the required mass. + Assume total mass includes a full tank of gas of 60 kg*/ + attribute redefines massRequired=2000 [kg]; + attribute redefines massActual default vehicle.dryMass + fuelMassActual; + attribute fuelMassActual:>ISQ::mass; + attribute fuelMassMax:>ISQ::mass = 60 [kg]; + assume constraint {fuelMassActual==fuelMassMax} + } + + allocate vehicleMassRequirement to PartsTree::vehicle_b.mass; + + requirement <'2'> vehicleFuelEconomyRequirements{ + doc /* fuel economy requirements group */ + attribute assumedCargoMass:>ISQ::mass; + requirement <'2_1'> cityFuelEconomyRequirement:FuelEconomyRequirement{ + redefines requiredFuelEconomy= 10 [km / L]; + assume constraint {assumedCargoMass<=500 [kg]} + } + requirement <'2_2'> highwayFuelEconomyRequirement:FuelEconomyRequirement{ + redefines requiredFuelEconomy= 12.75 [km / L]; + assume constraint {assumedCargoMass<=500 [kg]} + + //StatusInfo is contained in ModelingMetadata library + // StatusKind has values for open, closed, tbd, tbr, tbd + @StatusInfo { + status = StatusKind::closed; + originator = "Bob"; + owner = "Mary"; + } + } + } + } + requirement engineSpecification { + subject engine1:Engine; + requirement <'1'> engineMassRequirement: MassRequirement { + doc /* The total mass of the engine shall be less than or equal to the required mass.*/ + attribute redefines massRequired=200 [kg]; + attribute redefines massActual = engine1.mass; + } + requirement torqueGenerationRequirement : TorqueGenerationRequirement{ + subject generateTorque default engine1.generateTorque; + } + + requirement drivePowerOutputRequirement : DrivePowerOutputRequirement{ + port torqueOutPort{ + out torque:Torque; + } + } + } + // the engine mass requirement is derived from the vehicle mass requirement + #derivation connection { + end #original ::> vehicleSpecification.vehicleMassRequirement; + end #derive ::> engineSpecification.engineMassRequirement; + } + + } + } + package Engine4Cyl_Variant{ + public import ModelingMetadata::*; // incudes refinement + part engine:Engine{ + part cylinders:Cylinder[4..8] ordered; + } + part engine4Cyl:>engine{ + part redefines cylinders [4]; + part cylinder1 subsets cylinders[1]; + part cylinder2 subsets cylinders[1]; + part cylinder3 subsets cylinders[1]; + part cylinder4 subsets cylinders[1]; + } + #refinement dependency engine4Cyl to VehicleConfiguration_b::PartsTree::vehicle_b::engine; + } + package WheelHubAssemblies{ + // alternative 1 - w/o explicit nesxted interfaces + part wheelHubAssy1{ + part wheel1:Wheel{ + port :>>lugNutCompositePort:LugNutCompositePort { + port lugNutPort :>> lugNutPort [5]; + } + } + part hub1:Hub{ + port :>> shankCompositePort:ShankCompositePort { + port shankPort :>> shankPort [5]; + } + } + interface wheelHubInterface:WheelHubInterface + connect [1] wheel1.lugNutCompositePort to [1] hub1.shankCompositePort; + } + // alternative 2 - w multiple nesxted interfaces + part wheelHubAssy2{ + part wheel1:Wheel{ + port :>>lugNutCompositePort:LugNutCompositePort { + port lugNutPort :>> lugNutPort [5]; + } + } + part hub1:Hub{ + port :>> shankCompositePort:ShankCompositePort { + port shankPort :>> shankPort [5]; + } + } + interface wheelHubInterface:WheelHubInterface + connect [1] lugNutCompositePort ::> wheel1.lugNutCompositePort to [1] shankCompositePort ::> hub1.shankCompositePort { + interface wheelFastenerInterface1 :> wheelFastenerInterface + connect [5] lugNutPort ::> lugNutCompositePort.lugNutPort to [5] shankPort ::> shankCompositePort.shankPort; + } + } + // alternative 3 - w explicit nesxted interfaces + part wheelHubAssy3{ + part wheel1:Wheel{ + port lugNutCompositePort :>> lugNutCompositePort { + port lugNutPort [5] :>> lugNutPort { + attribute :>> threadDia = 14 [mm]; + attribute :>> threadPitch = 1.5 [mm]; + } + port lugNutPort1 [1] :> lugNutPort; + port lugNutPort2 [1] :> lugNutPort; + port lugNutPort3 [1] :> lugNutPort; + } +} + part hub1:Hub{ + port shankCompositePort :>> shankCompositePort { + port shankPort [5] :>> shankPort { + attribute :>> threadDia = 14 [mm]; + attribute :>> threadPitch = 1.5 [mm]; + attribute :>> shaftLength = 70 [mm]; + } + port shankPort1 [1] :> shankPort; + port shankPort2 [1] :> shankPort; + port shankPort3 [1] :> shankPort; + } +} + interface wheelHubInterface:WheelHubInterface + connect [1] lugNutCompositePort ::> wheel1.lugNutCompositePort to [1] shankCompositePort ::> hub1.shankCompositePort { + interface wheelFastenerInterface1 :> wheelFastenerInterface + connect lugNutPort ::> lugNutCompositePort.lugNutPort1 to shankPort ::> shankCompositePort.shankPort1 { + attribute :>> maxTorque = 90 * 1.356 [N*m]; + } + interface wheelFastenerInterface2 :> wheelFastenerInterface + connect lugNutPort ::> lugNutCompositePort.lugNutPort2 to shankPort ::> shankCompositePort.shankPort2 { + attribute :>> maxTorque = 90 * 1.356 [N*m]; + } + interface wheelFastenerInterface3 :> wheelFastenerInterface + connect lugNutPort ::> lugNutCompositePort.lugNutPort3 to shankPort ::> shankCompositePort.shankPort3 { + attribute :>> maxTorque = 90 * 1.356 [N*m]; + } + } + } + } + } + package VehicleAnalysis{ + public import RiskMetadata::*; + public import RiskLevelEnum::*; + // recursive public import uses double asterisk ** + public import VehicleConfigurations::VehicleConfiguration_b::**; + package FuelEconomyAnalysisModel{ + public import SampledFunctions::SampledFunction; + + /* + This analysis model was provided by Hisashi Miyashita on January 27, 2021 + We use the simplest fuel consumption analysis model introduced in: + Akcelik, R. "Fuel efficiency and other objectives in traffic system management." Traffic Engineering and Control 22.2 (1981): 54-65. + + Fuel consumption rate f can be decomposed to: + f = f_a + f_b * tpd_avg, + where tpd_avg is average interrupted travel time per unit distance, actually the inverse of the average velocity [t/km]; + f_a is the best fuel consumption per distance; and + f_b is the additional fuel consumption per distance and average travel time, which can be regarded as the idling fuel consumption. + Approximately, it is proportional to engine displacement and it ranges from 0.5 to 0.6 [l/hour/litre of engine displacement] + according to: + Review of the Incidence, Energy Use and Costs of Passenger Vehicle Idling; Gordon W. Taylor, P.Eng. Prepared for the Office of Energy Efficiency, Natural Resources Canada, 2003 + + We assume f_a can be approximated to + fuel_consumption / distance = BSFC * SGG * required_power_avg * tpd_avg, + where required_power_avg is the required power, and it can be approximately derived from: + total_energy == P_req * tpd_avg * distance == 1/2 * mass / tpd_avg^2 + This part is computed with BestFuelConsumptionPerDistance calc def. + + BSFC means Brake-Specific Fuel Consumption, defined as gram/power. SGG is the specific gravity of gasoline. + The high octane gasoline is about 0.76[l/kg]. + */ + + attribute def Scenario :> SampledFunction { + attribute wayPoint[1..*] { + attribute elapseTime[1] :> ISQ::time; + attribute position[1] :> ISQ::distance; + } + } + + calc def FuelConsumption { + in bestFuelConsumption: Real; + in idlingFuelConsumption: Real; + in tpd_avg:>timePerDistance; + attribute f = bestFuelConsumption + idlingFuelConsumption * tpd_avg; + return dpv :> distancePerVolume = 1/f; + } + + calc def AverageTravelTimePerDistance { + in scenario: Scenario; + return tpd_avg:>timePerDistance; + } + calc def TraveledDistance { + in scenario: Scenario; + return distance:> length; + } + calc def IdlingFuelConsumptionPerTime { + in engine:Engine; + attribute idlingFuelConsumptionPerDisplacement: Real = 0.5; + return f_a : Real = engine.displacement * idlingFuelConsumptionPerDisplacement; + } + + attribute specificGravityOfGasoline: Real = 0.76; + calc def BestFuelConsumptionPerDistance { + in mass: MassValue; + in bsfc: Real; + in tpd_avg:> timePerDistance; + in distance:>length; + attribute required_power_avg:> ISQ::power; + constraint {required_power_avg == 1/2 * mass * tpd_avg **(-3) / distance} + return f_b : Real = bsfc * specificGravityOfGasoline * required_power_avg * tpd_avg; + } + + calc def ComputeBSFC{ + in engine: Engine; + return : Real; + } + + analysis fuelEconomyAnalysis { + subject = vehicle_b; + + objective fuelEconomyAnalysisObjective { + doc /*estimate the vehicle fuel economy*/ + require vehicleSpecification.vehicleFuelEconomyRequirements; + } + + in attribute scenario: Scenario; + // define a series of waypoints + + attribute distance = TraveledDistance(scenario); + attribute tpd_avg = AverageTravelTimePerDistance(scenario); + attribute bsfc = ComputeBSFC(vehicle_b.engine); + attribute f_a = BestFuelConsumptionPerDistance(vehicle_b.mass, bsfc, tpd_avg, distance); + attribute f_b = IdlingFuelConsumptionPerTime(vehicle_b.engine); + + return attribute calculatedFuelEconomy:>distancePerVolume=FuelConsumption(f_a, f_b, tpd_avg); + } + } + package ElectricalPowerAnalysis{ + } + package ReliabilityAnalyis{ + } + package VehicleTradeOffAnalysis{ + /* The following example provides the rationale for selecting the engine4cyl. + The rationale and risk are contained in a metadata library. */ + + @Rationale about engineTradeOffAnalysis::vehicle_b_engine4cyl{ + explanation = VehicleAnalysis::VehicleTradeOffAnalysis::engineTradeOffAnalysis; + text = "the engine4cyl was evaluated to have a higher objective function compared to the engine6cyl based on the trade-off analyiss"; + } + + // The following risk for the engine4cyl could have been included as part of the objective evaluaiton criteria + + @Risk about engineTradeOffAnalysis::vehicle_b_engine4cyl { + totalRisk = medium; + technicalRisk = medium; + scheduleRisk = medium; + costRisk = RiskLevelEnum::low; + } + @Risk about engineTradeOffAnalysis::vehicle_b_engine4cyl::engine::fuelEfficiency { + technicalRisk { + probability = 0.3; + impact = 0.5; + } + } + + + public import TradeStudies::*; + //evaluation function with criterion engine mass, engine power, and engine cost + calc def EngineEvaluation { + in engineMass:>ISQ::mass; + in enginePower:>ISQ::power; + in engineFuelEfficiency:Real; + in engineCost:Real; + return eval:Real; + } + calc def EngineEvaluation_4cyl { + in engineMass:>ISQ::mass; + in enginePower:>ISQ::power; + in engineFuelEfficiency:Real; + in engineCost:Real; + return eval:Real; + } + calc def EngineEvaluation_6cyl { + in engineMass:>ISQ::mass; + in enginePower:>ISQ::power; + in engineFuelEfficiency:Real; + in engineCost:Real; + return eval:Real; + } + analysis engineTradeOffAnalysis:TradeStudy{ + subject vehicleAlternatives[2]:>vehicle_b; + + part vehicle_b_engine4cyl:>vehicleAlternatives{ + part engine redefines engine{ + part cylinders :>> cylinders [4]; + attribute mass redefines mass=180 [kg]; + attribute peakHorsePower redefines peakHorsePower = 180 [W]; + attribute fuelEfficiency redefines fuelEfficiency=.6; + attribute cost redefines cost = 1000; + } + } + part vehicle_b_engine6cyl:>vehicleAlternatives{ + part engine redefines engine{ + part cylinders redefines cylinders [6]; + attribute mass redefines mass=220 [kg]; + attribute peakHorsePower redefines peakHorsePower = 220 [W]; + attribute fuelEfficiency redefines fuelEfficiency=.5; + attribute cost redefines cost = 1500; + } + } + + objective :MaximizeObjective; + /*Select vehicle alternative with the engine whose evaluation function returns the max value*/ + + calc :> evaluationFunction{ + in part vehicle:>vehicle_b_engine4cyl; + return attribute eval:Real=EngineEvaluation_4cyl (vehicle.engine.mass, vehicle.engine.peakHorsePower, vehicle.engine.fuelEfficiency, vehicle.engine.cost); + } + calc :> evaluationFunction{ + in part vehicle:>vehicle_b_engine6cyl; + return attribute eval:Real=EngineEvaluation_6cyl (vehicle.engine.mass, vehicle.engine.peakHorsePower, vehicle.engine.fuelEfficiency, vehicle.engine.cost); + } + return part selectedVehicle:>vehicle_b; + } + } + } + package VehicleVerification{ + public import VehicleConfigurations::VehicleConfiguration_b::**; + public import VerificationCaseDefinitions::*; + public import VerificationCases1::*; + // the following is a model library which contains VerdictKind + public import VerificationCases::*; + public import VerificationSystem::*; + package VerificationCaseDefinitions{ + verification def MassTest; + verification def AccelerationTest; + verification def ReliabilityTest; + } + package VerificationCases1{ + verification massTests:MassTest { + subject vehicle_uut :> vehicle_b; + actor vehicleVerificationSubSystem_1 = verificationContext.massVerificationSystem; + objective { + verify vehicleSpecification.vehicleMassRequirement{ + redefines massActual=weighVehicle.massMeasured; + } + } + // method kinds are test, demo, analyze, should also include inspection, similarity + @ VerificationMethod{ + kind = (VerificationMethodKind::test, VerificationMethodKind::analyze); + } + action weighVehicle { + out massMeasured:>ISQ::mass; + } + then action evaluatePassFail { + in massMeasured:>ISQ::mass; + out verdict = PassIf(vehicleSpecification.vehicleMassRequirement(vehicle_uut)); + } + flow from weighVehicle.massMeasured to evaluatePassFail.massMeasured; + return :>> verdict = evaluatePassFail.verdict; + } + } + package VerificationSystem{ + part verificationContext{ + perform massTests; + part vehicle_UnitUnderTest :> vehicle_b; + part massVerificationSystem{ + part scale{ + perform massTests.weighVehicle; + } + part operator{ + perform massTests.evaluatePassFail; + } + } + } + } + } + package VehicleIndividuals{ + individual a:VehicleRoadContext_1{ + timeslice t0_t2_a{ + snapshot t0_a { + attribute t0 redefines time=0 [s]; + snapshot t0_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t0_v:Vehicle_1{ + :>>Vehicle::position=0 [m]; + :>>Vehicle::velocity=0 [m]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + snapshot t0_fa:FrontAxleAssembly_1{ + snapshot t0_leftFront:Wheel_1; + snapshot t0_rightFront:Wheel_2; + } + } + } + snapshot t1_a{ + attribute t1 redefines time=1 [s]; + snapshot t1_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t1_v:Vehicle_1{ + :>>Vehicle::position=.98 [m]; + :>>Vehicle::velocity=1.96 [m/s]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + snapshot t1_fa:FrontAxleAssembly_1{ + snapshot t1_leftFront:Wheel_1; + snapshot t1_rightFront:Wheel_2; + } + } + } + snapshot t2_a{ + attribute t2 redefines time=2 [s]; + snapshot t2_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t2_v:Vehicle_1{ + :>>Vehicle::position=3.92 [m]; + :>>Vehicle::velocity=3.92 [m/s]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + snapshot t2_fa:FrontAxleAssembly_1{ + snapshot t2_leftFront:Wheel_1; + snapshot t2_rightFront:Wheel_2; + } + } + } + } + } + } + package MissionContext{ + /* Define mission context with mission use cases for vehicle_b */ + public import VehicleConfigurations::VehicleConfiguration_b::**; + public import ParametersOfInterestMetadata::moe; + public import TransportPassengerScenario::*; + package ContextDefinitions{ + part def MissionContext:>GenericContext::Context; + part def Road; + part def Driver{ + port handPort:HandPort{ + } + exhibit state driverStates{ + state initial; + state wait; + transition initial then wait; + //ignition on + transition 'wait-wait-1' + first wait + do send new IgnitionCmd (ignitionOnOff=IgnitionOnOff::on) via handPort + then wait; + // ignition off + transition 'wait-wait-2' + first wait + do send new IgnitionCmd (ignitionOnOff=IgnitionOnOff::off) via handPort + then wait; + } + } + part def Passenger; + + requirement transportRequirements; + use case def TransportPassenger{ + objective TransportObjective { + doc /*deliver passenger to destination safely, comfortably, and within acceptable time*/ + require transportRequirements; + } + subject vehicle:Vehicle; + actor environment; + actor road; + actor driver; + actor passenger [0..4]; + include use case getInVehicle_a:>getInVehicle [1..5]; + include use case getOutOfVehicle_a:>getOutOfVehicle [1..5]; + } + + use case getInVehicle:GetInVehicle { + action unlockDoor_in [0..1]; + then action openDoor_in; + then action enterVehicle; + then action closeDoor_in; + } + use case def GetInVehicle{ + subject vehicle:Vehicle; + actor driver [0..1]; + actor passenger [0..1]; + assert constraint {driver != null xor passenger != null} + } + + use case getOutOfVehicle:GetOutOfVehicle { + action openDoor_out; + then action exitVehicle; + then action closeDoor_out; + then action lockDoor_out; + } + use case def GetOutOfVehicle{ + subject vehicle:Vehicle; + actor driver [0..1]; + actor passenger [0..1]; + assert constraint {driver != null xor passenger != null} + } + } + package TransportPassengerScenario{ + public import ContextDefinitions::TransportPassenger; + + // this version uses nesting vs fork and join for concurrent actions + use case transportPassenger:TransportPassenger{ + first start; + then action a{ + action driverGetInVehicle subsets getInVehicle_a[1]; + action passenger1GetInVehicle subsets getInVehicle_a[1]; + } + then action trigger accept ignitionCmd:IgnitionCmd; + then action b{ + action driveVehicleToDestination; + action providePower; + } + then action c{ + action driverGetOutOfVehicle subsets getOutOfVehicle_a[1]; + action passenger1GetOutOfVehicle subsets getOutOfVehicle_a[1]; + } + then done; + } + + + //this version uses forks and joins + use case transportPassenger_1:TransportPassenger{ + // declare actions + action driverGetInVehicle subsets getInVehicle_a[1]; + action passenger1GetInVehicle subsets getInVehicle_a[1]; + action driverGetOutOfVehicle subsets getOutOfVehicle_a[1]; + action passenger1GetOutOfVehicle subsets getOutOfVehicle_a[1]; + action driveVehicleToDestination; + action providePower; + item def VehicleOnSignal; + join join1; + join join2; + join join3; + action trigger accept ignitionCmd:IgnitionCmd; + + // define control flow + first start; + then fork fork1; + then driverGetInVehicle; + then passenger1GetInVehicle; + first driverGetInVehicle then join1; + first passenger1GetInVehicle then join1; + first join1 then trigger; + first trigger then fork2; + //succession trigger if trigger.ignitionCmd.ignitionOnOff==IgnitionOnOff::on then fork2; + + fork fork2; + then driveVehicleToDestination; + then providePower; + first driveVehicleToDestination then join2; + first providePower then join2; + first join2 then fork3; + + fork fork3; + then driverGetOutOfVehicle; + then passenger1GetOutOfVehicle; + first driverGetOutOfVehicle then join3; + first passenger1GetOutOfVehicle then join3; + + first join3 then done; + } + } + + part missionContext:ContextDefinitions::MissionContext{ + #moe attribute transportTime :> ISQ::time; + perform transportPassenger; + // bind parts to actors of use case + part road:ContextDefinitions::Road = transportPassenger.road; + part driver:ContextDefinitions::Driver = transportPassenger.driver{ + perform transportPassenger.a.driverGetInVehicle.unlockDoor_in; + perform transportPassenger.a.driverGetInVehicle.openDoor_in; + perform transportPassenger.a.driverGetInVehicle.enterVehicle; + perform transportPassenger.a.driverGetInVehicle.closeDoor_in; + perform transportPassenger.c.driverGetOutOfVehicle.openDoor_out; + perform transportPassenger.c.driverGetOutOfVehicle.exitVehicle; + perform transportPassenger.c.driverGetOutOfVehicle.closeDoor_out; + perform transportPassenger.c.driverGetOutOfVehicle.lockDoor_out; + perform transportPassenger.b.driveVehicleToDestination; + } + part passenger1:ContextDefinitions::Passenger = transportPassenger.passenger { + perform transportPassenger.a.passenger1GetInVehicle.unlockDoor_in; + perform transportPassenger.a.passenger1GetInVehicle.openDoor_in; + perform transportPassenger.a.passenger1GetInVehicle.enterVehicle; + perform transportPassenger.a.passenger1GetInVehicle.closeDoor_in; + perform transportPassenger.c.passenger1GetOutOfVehicle.openDoor_out; + perform transportPassenger.c.passenger1GetOutOfVehicle.exitVehicle; + perform transportPassenger.c.passenger1GetOutOfVehicle.closeDoor_out; + perform transportPassenger.c.passenger1GetOutOfVehicle.lockDoor_out; + } + part vehicle_b_1:>vehicle_b = transportPassenger.vehicle{ + attribute :>> position3dVector = (0,0,0) [spatialCF]; + perform transportPassenger.b.providePower redefines providePower; + perform transportPassenger.trigger; + } + connect driver.handPort to vehicle_b_1.ignitionCmdPort; + connect road to vehicle_b_1.vehicleToRoadPort; + } + } + package VehicleSuperSetModel{ + /* all of vehicleFamily is included in the superset model to enable subsetting a specific vehicle configuration*/ + package VariationPointDefinitions { + variation part def TransmissionChoices:>Transmission { + variant part transmissionAutomatic:TransmissionAutomatic; + variant part transmissionManual:TransmissionManual; + } + } + package VehiclePartsTree{ + public import VariationPointDefinitions::*; + abstract part vehicleFamily { + // variation with nested variation + variation part engine:Engine{ + variant part engine4Cyl:Engine4Cyl; + variant part engine6Cyl:Engine6Cyl{ + part cylinder:Cylinder [6]{ + variation attribute diameter:LengthValue{ + variant attribute smallDiameter:LengthValue; + variant attribute largeDiagmeter:LengthValue; + } + } + } + } + // variation point based on variation of part definition + part transmissionChoices:TransmissionChoices; + // optional variation point + part sunroof:Sunroof[0..1]; + // selection constraint + assert constraint selectionConstraint{ + (engine==engine::engine4Cyl and transmissionChoices==TransmissionChoices::transmissionManual) xor + (engine==engine::engine6Cyl and transmissionChoices==TransmissionChoices::transmissionAutomatic) + } + part driveshaft; + part frontAxleAssembly; + part rearAxleAssembly; + } + } + } + package SafetyandSecurityGroups { + public import VehicleConfigurations::VehicleConfiguration_b::PartsTree::*; + package SafetyGroup { + /* Parts that contribute to safety. */ + public import vehicle_b::**; + filter @Safety; + } + package SecurityGroup { + /* Parts that contribute to security. */ + public import vehicle_b::**; + filter @Security; + } + package SafetyandSecurityGroup { + /* Parts that contribute to safety OR security. */ + public import vehicle_b::**; + filter @Safety or @Security; + } + package MandatorySafetyGroup { + /* Parts that contribute to safety AND are mandatory. */ + public import vehicle_b::**; + filter @Safety and (as Safety).isMandatory; + } + } + package Views_Viewpoints{ + package ViewpointDefinitions{ + viewpoint def BehaviorViewpoint; + viewpoint def SafetyViewpoint{ + frame concern vs:VehicleSafety; + } + part def SafetyEngineer; + concern def VehicleSafety { + doc /* identify system safety features */ + subject; + stakeholder se:SafetyEngineer; + } + } + package ViewDefinitions{ + //public import Views to access rendering method library + public import Views::*; + view def TreeView{ + render asTreeDiagram; + } + view def NestedView; + view def RelationshipView; + view def TableView; + view def PartsTreeView:>TreeView { + filter @SysML::PartUsage; + } + view def PartsInterconnection:>NestedView; + } + package VehicleViews{ + public import ViewpointDefinitions::*; + public import ViewDefinitions::*; + public import VehicleConfigurations::VehicleConfiguration_b::*; + view vehiclePartsTree_Safety:PartsTreeView{ + satisfy requirement sv:SafetyViewpoint; + expose PartsTree::**; + filter @Safety; + } + } + } +} + diff --git a/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleDefinitions.sysml b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleDefinitions.sysml new file mode 100644 index 00000000..17b6a252 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleDefinitions.sysml @@ -0,0 +1,54 @@ +package VehicleDefinitions { + doc + /* + * Example vehicle definitions model. + */ + + private import ScalarValues::*; + private import Quantities::*; + private import MeasurementReferences::*; + private import ISQ::*; + private import SI::*; + + /* PART DEFINITIONS */ + + part def Vehicle { + attribute mass :> ISQ::mass; + } + part def Transmission; + part def AxleAssembly; + part def Axle { + port leftMountingPoint: AxleMountIF; + port rightMountingPoint: AxleMountIF; + } + part def Wheel { + port hub: WheelHubIF; + } + part def Lugbolt { + attribute tighteningTorque :> ISQ::torque; + } + + /* PORT DEFINITIONS */ + + port def DriveIF { + in driveTorque :> ISQ::torque; + } + + port def AxleMountIF { + out transferredTorque :> ISQ::torque; + } + + port def WheelHubIF { + in appliedTorque :> ISQ::torque; + } + + /* INTERFACE DEFINITIONS */ + + interface def Mounting { + doc /* The definition of the interface for mounting a Wheel to an Axle. */ + end axleMount: AxleMountIF; + end hub: WheelHubIF; + + flow axleMount.transferredTorque to hub.appliedTorque; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleIndividuals.sysml b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleIndividuals.sysml new file mode 100644 index 00000000..f51960e1 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleIndividuals.sysml @@ -0,0 +1,115 @@ +package VehicleIndividuals { + private import VehicleUsages::*; + private import Time::DateTime; + private import SI::kg; + + package IndividualDefinitions { + + individual part def Vehicle1 :> Vehicle { + doc + /* + * This is an individual Vehicle with a mass of 1800 kg. + */ + + attribute redefines mass = 1800 [kg]; + } + + individual part def Vehicle2 :> Vehicle { + doc + /* + * This is an individual Vehicle with a mass of 1700 kg. + */ + + attribute redefines mass = 1700 [kg]; + } + + individual part def AxleAssembly1 :> AxleAssembly; + + individual part def Wheel1 :> Wheel; + individual part def Wheel2 :> Wheel; + } + + package IndividualSnapshots { + public import IndividualDefinitions::*; + private import Occurrences::HappensJustBefore; + + attribute t0: DateTime; + attribute t1: DateTime; + + individual part vehicle1 : Vehicle1 { + snapshot vehicle1_t0 { + doc + /* + * This is a snapshot of Vehicle1 at time t0; + */ + + attribute :>> localClock.currentTime = t0; + } + + succession : HappensJustBefore first vehicle1_t0 then vehicle1_t0_t1; + + timeslice vehicle1_t0_t1 { + doc + /* + * This is a time slice of Vehicle1 starting at snapshot vehicle1_t0 + * (time t0) and ending at time t1. + */ + + snapshot :>> done { + attribute :>> localClock.currentTime = t1; + } + } + } + } + + package IndividualConfigurations { + public import IndividualSnapshots::*; + + individual part vehicle1_C2: Vehicle1 :> vehicle_C2, vehicle1 { + doc + /* + * This asserts that for some portion of its lifetime, Vehicle1 conforms + * to the configuration vehicle_C2; + */ + + snapshot vehicle1_C2_t0 :> vehicle1_t0 { + doc + /* + * This is a snapshot of Vehicle1 in configuration vehicle1_C2 at time t0. + */ + + individual axleAssembly1_t0: AxleAssembly1 :>> frontAxleAssembly { + doc + /* + * frontAxleAssembly is a feature of vehicle1_C2. + */ + + individual leftFrontWheel_t0: Wheel1 :>> leftFrontWheel { + doc + /* + * This asserts that Wheel1 is the leftFrontWheel of vehicle_C2_t0 + * (leftFrontWheel is a feature of vehicle_C2::frontAxleAssembly). + */ + } + } + } + + snapshot vehicle1_C2_t1 :> vehicle1_t0_t1.done { + doc + /* + * This is a snapshot of Vehicle1 in configuration vehicle_C2 at time t1. + */ + + individual axleAssembly1_t1: AxleAssembly1 :>> frontAxleAssembly { + individual rightFrontWheel_t1: Wheel1 :>> rightFrontWheel { + doc + /* + * This asserts that Wheel1 is the rightFrontWheel of vehicle_C2_t1. + */ + } + } + } + + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleUsages.sysml b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleUsages.sysml new file mode 100644 index 00000000..14cc69bf --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/Vehicle Example/VehicleUsages.sysml @@ -0,0 +1,96 @@ +package VehicleUsages { + doc + /* + * Example usages of elements from the vehicle definitions model. + */ + + private import SI::N; + private import SI::m; + private import ScalarFunctions::*; + + public import VehicleDefinitions::*; + + /* VALUES */ + T1 = 10.0 [N * m]; + T2 = 20.0 [N * m]; + + /* PARTS */ + part narrowRimWheel: Wheel { + doc /* Narrow-rim wheel configuration with 4 to 5 lugbolts. */ + + part lugbolt: Lugbolt[4..5]; + } + + part wideRimWheel: Wheel { + doc /* Wide-rim wheel configuration with 4 to 6 lugbolts. */ + + part lugbolt: Lugbolt[4..6]; + } + + part vehicle_C1: Vehicle { + doc /* Basic Vehicle configuration showing a part hierarchy. */ + + part frontAxleAssembly: AxleAssembly { + part frontWheel[2] subsets narrowRimWheel { + part redefines lugbolt[4] { + attribute redefines tighteningTorque = T1; + } + } + part frontAxle: Axle; + } + part rearAxleAssembly: AxleAssembly { + part rearWheel[2] subsets wideRimWheel { + part redefines lugbolt[6] { + attribute redefines tighteningTorque = T2; + } + } + part rearAxle: Axle; + } + } + + part vehicle_C2 subsets vehicle_C1 { + doc /* Specialized configuration with part-specific ports. */ + + part redefines frontAxleAssembly { + part leftFrontWheel subsets frontWheel = frontWheel#(1); + part rightFrontWheel subsets frontWheel = frontWheel#(2); + + interface leftFrontMount: Mounting connect + frontAxle.leftMountingPoint to leftFrontWheel.hub; + + interface rightFrontMount: Mounting connect + frontAxle.rightMountingPoint to rightFrontWheel.hub; + } + + part rearAxleAssembly redefines vehicle_C1::rearAxleAssembly { + part leftRearWheel subsets rearWheel = rearWheel#(1); + part rightRearWheel subsets rearWheel = rearWheel#(2); + + interface leftRearMount: Mounting connect + rearAxle.leftMountingPoint to leftRearWheel.hub; + + interface rightRearMount: Mounting connect + rearAxle.rightMountingPoint to rightRearWheel.hub; + } + } + + part vehicle_C3 subsets vehicle_C2 { + doc /* Further specialized configuration with a connection to a deeply-nested port. */ + + + part transmission: Transmission { + port drive: ~DriveIF; + } + + part redefines rearAxleAssembly { + part redefines rearAxle { + port drive: DriveIF; + } + } + + interface driveShaft connect + transDrive ::> transmission.drive to axleDrive ::> rearAxleAssembly.rearAxle.drive { + flow transDrive.driveTorque to axleDrive.driveTorque; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package - Updated.sysml b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package - Updated.sysml new file mode 100644 index 00000000..0360fcc0 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package - Updated.sysml @@ -0,0 +1,92 @@ +package 'Wheel Package - Updated' { + doc + /* + * Example from the SysML 1.6 spec, subclause 8.4.1 Wheel Hub Assembly. + */ + + private import ISQ::*; + + // Quantities + + pressure = force / length^2; + + // Blocks + + part def WheelHubAssembly; + part def WheelAssembly { + inflationPressure :> pressure; + } + + part def Tire { + tireSpecification : ScalarValues::String; + action mountTire; // Should be operation + } + + part def TireBead; + + connection def PressureSeat { + end : TireBead[1]; + end : TireMountingRim[1]; + } + + part def Wheel { + diameter :> length; + width :> length; + } + + connection def BandMount { + end : Wheel[1]; + end : WirelessTirePressureMonitor[1]; + } + + part def WirelessTirePressureMonitor { + action transmitPressure; // Should be operation + } + + part def TireMountingRim; + + part def InflationValve; + + part def BalanceWeight; + + part def LugBoltMountingHole { + lugBoltSize :> length; + } + + part def LugBoltJoint { + torque :> ISQ::torque; + boltTension :> force; + } + + part def Hub; + + part def LugBoltThreadableHole { + lugBoltSize :> length; + threadSize :> length; + } + + // Parts + + part wheelHubAssembly: WheelHubAssembly { + part wheel: WheelAssembly[1] { + part t: Tire[1] { + part bead : TireBead[2]; + } + part w: Wheel[1] { + part rim : TireMountingRim[2]; + part v : InflationValve[1]; + part weight : BalanceWeight[0..6]; + part mountingHoles : LugBoltMountingHole[5]; + } + connection : PressureSeat connect t.bead to w.rim; + } + part lugBoltJoints: LugBoltJoint[5] { + ref mountingHole: LugBoltMountingHole[1] subsets wheel.w.mountingHoles; + ref threadedHole: LugBoltThreadableHole[1] subsets hub.h; + } + part hub: Hub[1] { + part h: LugBoltThreadableHole[5]; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package.sysml b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package.sysml new file mode 100644 index 00000000..6ba0d0e9 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.1 Wheel Hub Assembly/Wheel Package.sysml @@ -0,0 +1,94 @@ +package 'Wheel Package' { + doc + /* + * Example from the SysML 1.6 spec, subclause 8.4.1 Wheel Hub Assembly. + */ + + private import ISQ::*; + + pressure = force / length^2; + + part def WheelHubAssembly { + part wheel: WheelAssembly[1]; + part lugBoltJoints: LugBoltJoint[5] { + ref redefines threadedHole subsets hub.h; + ref redefines mountingHole subsets wheel.w.mountingHoles; + } + part hub: Hub[1]; + } + + part def WheelAssembly { + inflationPressure :> pressure; + + part t: Tire[1] { + part bead redefines Tire::bead; + } + part w: Wheel[1] { + part rim redefines Wheel::rim; + } + + connection : PressureSeat connect t.bead to w.rim; + } + + part def Tire { + tireSpecification : ScalarValues::String; + + part bead : TireBead[2]; + + action mountTire; + } + + part def TireBead; + + connection def PressureSeat { + end : TireBead[1]; + end : TireMountingRim[1]; + } + + part def Wheel { + diameter :> length; + width :> length; + + part rim : TireMountingRim[2]; + part v : InflationValve[1]; + part weight : BalanceWeight[0..6]; + part mountingHoles : LugBoltMountingHole[5]; + } + + connection def BandMount { + end : Wheel[1]; + end : WirelessTirePressureMonitor[1]; + } + + part def WirelessTirePressureMonitor { + action transmitPressure; + } + + part def TireMountingRim; + + part def InflationValve; + + part def BalanceWeight; + + part def LugBoltMountingHole { + lugBoltSize :> length; + } + + part def LugBoltJoint { + torque :> ISQ::torque; + boltTension :> force; + + ref mountingHole: LugBoltMountingHole[1]; + ref threadedHole: LugBoltThreadableHole[1]; + } + + part def Hub { + part h: LugBoltThreadableHole[5]; + } + + part def LugBoltThreadableHole { + lugBoltSize :> length; + threadSize :> length; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition - Updated.sysml b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition - Updated.sysml new file mode 100644 index 00000000..99829a29 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition - Updated.sysml @@ -0,0 +1,68 @@ +package 'Vehicle Decomposition - Updated' { + doc + /* + * Example from the SysML 1.6 spec, subclause 8.4.5 Constraining Decomposition, + * updated for usage-focused approach. + */ + + // Blocks + + part def Vehicle; + + part def 'Chassis Assembly'; + + part def Wheel; + + part def LugBolt; + + part def RollBar; + part def HeavyRollBar :> RollBar; + part def LightRollBar :> RollBar; + + part def Engine; + + part def Cylinder; + + // Parts + + part vehicle : Vehicle { + part chs : 'Chassis Assembly'[1] { + part rb : RollBar[0..1]; + part w : Wheel[4] { + part lb : LugBolt[6..10]; + } + } + part eng: Engine[1] { + part cyl : Cylinder[4..8]; + } + } + + + part 'vehicle model 1' :> vehicle { + part redefines chs { + part redefines rb : LightRollBar[0..1]; + part redefines w { + part redefines lb; + } + } + part redefines eng { + part redefines cyl[4]; + } + + // Constrains total number of lugbolts. + ref lugBolts[24] = chs.w.lb; + } + + part 'vehicle model 2' :> vehicle { + part redefines chs { + part redefines rb[0]; + part redefines w { + // Constrains number of lugbolts per wheel. + part redefines lb[6..7]; + } + } + part redefines eng { + part redefines cyl[6..8]; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition.sysml b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition.sysml new file mode 100644 index 00000000..16a3d0b4 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/8.4.5 Constraining Decomposition/Vehicle Decomposition.sysml @@ -0,0 +1,55 @@ +package 'Vehicle Decomposition' { + doc + /* + * Example from the SysML 1.6 spec, subclause 8.4.5 Constraining Decomposition. + */ + + part def Vehicle { + part chs : 'Chassis Assembly'[1] { + part rb redefines 'Chassis Assembly'::rb; + part redefines w { + part redefines lb; + } + } + part eng : Engine[1] { + part cyl redefines Engine::cyl; + } + + ref cylinderBR[*] = eng.cyl; + ref rollBarBR[*] = chs.rb; + ref lugBoltBR[24..32] = chs.w.lb; + } + + part def 'Chassis Assembly' { + part w : Wheel[4]; + part rb : RollBar[0..1]; + } + + part def Wheel { + part lb : LugBolt[6..10]; + } + + part def LugBolt; + + part def RollBar; + part def HeavyRollBar :> RollBar; + part def LightRollBar :> RollBar; + + part def Engine { + part cyl : Cylinder[4..8]; + } + + part def Cylinder; + + part def 'Vehicle Model 1' :> Vehicle { + ref redefines cylinderBR[4]; + ref redefines rollBarBR : LightRollBar[*]; + ref redefines lugBoltBR[24]; + } + + part def 'Vehicle Model 2' :> Vehicle { + ref redefines cylinderBR[6..8]; + ref redefines rollBarBR[0]; + ref redefines lugBoltBR[24..28]; // 6..7 per wheel + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/examples/v1 Spec Examples/D.4.7.8 Dynamics/HSUVDynamics.sysml b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/D.4.7.8 Dynamics/HSUVDynamics.sysml new file mode 100644 index 00000000..002d8414 --- /dev/null +++ b/test-data/sysml2/official/sysml/examples/v1 Spec Examples/D.4.7.8 Dynamics/HSUVDynamics.sysml @@ -0,0 +1,88 @@ +package HSUVDynamics { + private import ScalarValues::*; + private import SequenceFunctions::size; + private import ControlFunctions::*; + + attribute def Horsepwr :> Real; + attribute def Weight :> Real; + attribute def Accel :> Real; + attribute def Vel :> Real; + attribute def Dist :> Real; + attribute def Time :> Real; + + constraint def PowerEquation { + attribute whlpwr : Horsepwr; + attribute Cd : Real; + attribute Cf : Real; + attribute tw : Weight; + attribute tp : Horsepwr; + attribute v : Vel; + + tp == whlpwr - Cd * v - Cf * tw * v + } + + constraint def PositionEquation { + attribute dt : Time; + attribute v : Vel[0..*] ordered; + attribute x : Dist[0..*] ordered; + + (1..size(x)-1)->forAll {in n : Natural; x#(n + 1) == x#(n) + v#(n) * (5280/3600) * dt} + } + + constraint def VelocityEquation { + attribute dt : Time; + attribute v : Vel[0..*] ordered; + attribute a : Accel; + + (1..size(v)-1)->forAll {in n: Natural; v#(n + 1) == v#(n) + a * 32 * (3600/5280) * dt} + } + + constraint def AccelerationEquation { + attribute tw : Weight; + attribute dt : Time; + attribute tp : Horsepwr; + attribute a : Accel; + + a == (550/32) * tp * dt * tw + } + + constraint def StraightLineVehicleDynamics { + attribute dt : Time; + attribute whlpwr : Horsepwr; + attribute Cd : Real; + attribute Cf: Real; + attribute tw : Weight; + attribute a : Accel; + attribute v : Vel[0..*] ordered; + attribute x : Dist[0..*] ordered; + + constraint pwr : PowerEquation { + attribute redefines whlpwr = StraightLineVehicleDynamics::whlpwr; + attribute redefines Cd = StraightLineVehicleDynamics::Cd; + attribute redefines Cf = StraightLineVehicleDynamics::Cf; + attribute redefines tw = StraightLineVehicleDynamics::tw; + attribute redefines v = vel.v; + attribute redefines tp; + } + + constraint acc : AccelerationEquation { + attribute redefines tp = pwr.tp; + attribute redefines tw = StraightLineVehicleDynamics::tw; + attribute redefines dt = StraightLineVehicleDynamics::dt; + attribute redefines a = StraightLineVehicleDynamics::a; + } + + constraint vel : VelocityEquation { + attribute redefines a = acc.a; + attribute redefines v = StraightLineVehicleDynamics::v; + attribute redefines dt = StraightLineVehicleDynamics::dt; + } + + constraint pos : PositionEquation { + attribute redefines v = vel.v; + attribute redefines x = StraightLineVehicleDynamics::x; + attribute redefines dt = StraightLineVehicleDynamics::dt; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/01. Packages/Comment Example.sysml b/test-data/sysml2/official/sysml/training/01. Packages/Comment Example.sysml new file mode 100644 index 00000000..b55d5f3c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/01. Packages/Comment Example.sysml @@ -0,0 +1,24 @@ +package 'Comment Example' { + /* This is a comment, which is a part of the model, + * annotating (by default) it's owning namespace. */ + + comment Comment1 /* This is a named comment. */ + + comment about Automobile + /* This is an unnamed comment, annotating an + * explicitly specified element. + */ + + part def Automobile; + + alias Car for Automobile { + /* + * This is a comment annotating its owning + * element. + */ + } + + // This is a note. It is in the text, but not part + // of the model. + alias Torque for ISQ::TorqueValue; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/01. Packages/Documentation Example.sysml b/test-data/sysml2/official/sysml/training/01. Packages/Documentation Example.sysml new file mode 100644 index 00000000..61538b08 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/01. Packages/Documentation Example.sysml @@ -0,0 +1,14 @@ +package 'Documentation Example' { + doc /* This is documentation of the owning + * package. + */ + + part def Automobile { + doc Document1 /* This documentation of Automobile. */ + } + + alias Car for Automobile { + doc /* This is documentation of the alias. */ + } + alias Torque for ISQ::TorqueValue; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/01. Packages/Package Example.sysml b/test-data/sysml2/official/sysml/training/01. Packages/Package Example.sysml new file mode 100644 index 00000000..84535a11 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/01. Packages/Package Example.sysml @@ -0,0 +1,9 @@ +package 'Package Example' { + public import ISQ::TorqueValue; + private import ScalarValues::*; + + private part def Automobile; + + public alias Car for Automobile; + alias Torque for ISQ::TorqueValue; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/02. Part Definitions/Part Definition Example.sysml b/test-data/sysml2/official/sysml/training/02. Part Definitions/Part Definition Example.sysml new file mode 100644 index 00000000..5f76994f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/02. Part Definitions/Part Definition Example.sysml @@ -0,0 +1,20 @@ +package 'Part Definition Example' { + private import ScalarValues::*; + + part def Vehicle { + attribute mass : Real; + attribute status : VehicleStatus; + + part eng : Engine; + + ref part driver : Person; + } + + attribute def VehicleStatus { + attribute gearSetting : Integer; + attribute acceleratorPosition : Real; + } + + part def Engine; + part def Person; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/03. Generalization/Generalization Example.sysml b/test-data/sysml2/official/sysml/training/03. Generalization/Generalization Example.sysml new file mode 100644 index 00000000..249083e0 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/03. Generalization/Generalization Example.sysml @@ -0,0 +1,19 @@ +package 'Generalization Example' { + + abstract part def Vehicle; + + part def HumanDrivenVehicle specializes Vehicle { + ref part driver : Person; + } + + part def PoweredVehicle :> Vehicle { + part eng : Engine; + } + + part def HumanDrivenPoweredVehicle :> + HumanDrivenVehicle, PoweredVehicle; + + part def Engine; + part def Person; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/04. Subsetting/Subsetting Example.sysml b/test-data/sysml2/official/sysml/training/04. Subsetting/Subsetting Example.sysml new file mode 100644 index 00000000..31422236 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/04. Subsetting/Subsetting Example.sysml @@ -0,0 +1,15 @@ +package 'Subsetting Example' { + + part def Vehicle { + part parts : VehiclePart[*]; + + part eng : Engine subsets parts; + part trans : Transmission subsets parts; + part wheels : Wheel[4] :> parts; + } + + abstract part def VehiclePart; + part def Engine :> VehiclePart; + part def Transmission :> VehiclePart; + part def Wheel :> VehiclePart; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/05. Redefinition/Redefinition Example.sysml b/test-data/sysml2/official/sysml/training/05. Redefinition/Redefinition Example.sysml new file mode 100644 index 00000000..2b74e0f1 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/05. Redefinition/Redefinition Example.sysml @@ -0,0 +1,24 @@ +package 'Redefinition Example' { + + part def Vehicle { + part eng : Engine; + } + part def SmallVehicle :> Vehicle { + part smallEng : SmallEngine redefines eng; + } + part def BigVehicle :> Vehicle { + part bigEng : BigEngine :>> eng; + } + + part def Engine { + part cyl : Cylinder[4..6]; + } + part def SmallEngine :> Engine { + part redefines cyl[4]; + } + part def BigEngine :> Engine { + part redefines cyl[6]; + } + + part def Cylinder; +} diff --git a/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-1.sysml b/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-1.sysml new file mode 100644 index 00000000..fb796bfe --- /dev/null +++ b/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-1.sysml @@ -0,0 +1,17 @@ +package 'Enumeration Definitions-1' { + private import ScalarValues::Real; + + enum def TrafficLightColor { + enum green; + enum yellow; + enum red; + } + + part def TrafficLight { + attribute currentColor : TrafficLightColor; + } + + part def TrafficLightGo specializes TrafficLight { + attribute redefines currentColor = TrafficLightColor::green; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-2.sysml b/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-2.sysml new file mode 100644 index 00000000..f33775b0 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/06. Enumeration Definitions/Enumeration Definitions-2.sysml @@ -0,0 +1,32 @@ +package 'Enumeration Definitions-2' { + private import ScalarValues::*; + private import 'Enumeration Definitions-1'::*; + + attribute def ClassificationLevel { + attribute code : String; + attribute color : TrafficLightColor; + } + + enum def ClassificationKind specializes ClassificationLevel { + unclassified { + :>> code = "uncl"; + :>> color = TrafficLightColor::green; + } + confidential { + :>> code = "conf"; + :>> color = TrafficLightColor::yellow; + } + secret { + :>> code = "secr"; + :>> color = TrafficLightColor::red; + } + } + + enum def GradePoints :> Real { + A = 4.0; + B = 3.0; + C = 2.0; + D = 1.0; + F = 0.0; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-1.sysml b/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-1.sysml new file mode 100644 index 00000000..89e2d643 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-1.sysml @@ -0,0 +1,29 @@ +package 'Parts Example-1' { + + // Definitions + + part def Vehicle { + part eng : Engine; + } + + part def Engine { + part cyl : Cylinder[4..6]; + } + + part def Cylinder; + + // Usages + + part smallVehicle : Vehicle { + part redefines eng { + part redefines cyl[4]; + } + } + + part bigVehicle : Vehicle { + part redefines eng { + part redefines cyl[6]; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-2.sysml b/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-2.sysml new file mode 100644 index 00000000..05f3eae2 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/07. Parts/Parts Example-2.sysml @@ -0,0 +1,29 @@ +package 'Parts Example-2' { + + // Definitions + + part def Vehicle; + part def Engine; + part def Cylinder; + + // Usages + + part vehicle : Vehicle { + part eng : Engine { + part cyl : Cylinder[4..6]; + } + } + + part smallVehicle :> vehicle { + part redefines eng { + part redefines cyl[4]; + } + } + + part bigVehicle :> vehicle { + part redefines eng { + part redefines cyl[6]; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/08. Items/Items Example.sysml b/test-data/sysml2/official/sysml/training/08. Items/Items Example.sysml new file mode 100644 index 00000000..924c117e --- /dev/null +++ b/test-data/sysml2/official/sysml/training/08. Items/Items Example.sysml @@ -0,0 +1,17 @@ +package 'Items Example' { + private import ScalarValues::*; + + item def Fuel; + item def Person; + + part def Vehicle { + attribute mass : Real; + + ref item driver : Person; + + part fuelTank { + item fuel: Fuel; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/09. Connections/Connections Example.sysml b/test-data/sysml2/official/sysml/training/09. Connections/Connections Example.sysml new file mode 100644 index 00000000..287ff8ef --- /dev/null +++ b/test-data/sysml2/official/sysml/training/09. Connections/Connections Example.sysml @@ -0,0 +1,42 @@ +package 'Connections Example' { + + part def WheelHubAssembly; + part def WheelAssembly; + part def Tire; + part def TireBead; + part def Wheel; + part def TireMountingRim; + part def LugBoltMountingHole; + part def Hub; + part def LugBoltThreadableHole; + part def LugBoltJoint; + + connection def PressureSeat { + end [1] part bead : TireBead; + end [1] part mountingRim : TireMountingRim; + } + + part wheelHubAssembly : WheelHubAssembly { + + part wheel : WheelAssembly[1] { + part t : Tire[1] { + part bead : TireBead[2]; + } + part w: Wheel[1] { + part rim : TireMountingRim[2]; + part mountingHoles : LugBoltMountingHole[5]; + } + connection : PressureSeat + connect bead references t.bead + to mountingRim references w.rim; + } + + part lugBoltJoints : LugBoltJoint[0..5]; + part hub : Hub[1] { + part h : LugBoltThreadableHole[5]; + } + connect [0..1] lugBoltJoints to [1] wheel.w.mountingHoles; + connect [0..1] lugBoltJoints to [1] hub.h; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/10. Ports/Port Conjugation Example.sysml b/test-data/sysml2/official/sysml/training/10. Ports/Port Conjugation Example.sysml new file mode 100644 index 00000000..7310f520 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/10. Ports/Port Conjugation Example.sysml @@ -0,0 +1,20 @@ +package 'Port Conjugation Example' { + + attribute def Temp; + + part def Fuel; + + port def FuelPort { + attribute temperature : Temp; + out item fuelSupply : Fuel; + in item fuelReturn : Fuel; + } + + part def FuelTank { + port fuelTankPort : FuelPort; + } + + part def Engine { + port engineFuelPort : ~FuelPort; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/10. Ports/Port Example.sysml b/test-data/sysml2/official/sysml/training/10. Ports/Port Example.sysml new file mode 100644 index 00000000..503f51ff --- /dev/null +++ b/test-data/sysml2/official/sysml/training/10. Ports/Port Example.sysml @@ -0,0 +1,26 @@ +package 'Port Example' { + + attribute def Temp; + + part def Fuel; + + port def FuelOutPort { + attribute temperature : Temp; + out item fuelSupply : Fuel; + in item fuelReturn : Fuel; + } + + port def FuelInPort { + attribute temperature : Temp; + in item fuelSupply : Fuel; + out item fuelReturn : Fuel; + } + + part def FuelTankAssembly { + port fuelTankPort : FuelOutPort; + } + + part def Engine { + port engineFuelPort : FuelInPort; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Decomposition Example.sysml b/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Decomposition Example.sysml new file mode 100644 index 00000000..394629fc --- /dev/null +++ b/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Decomposition Example.sysml @@ -0,0 +1,23 @@ +package 'Interface Decomposition Example' { + + port def SpigotBank; + port def Spigot; + + port def Faucet; + port def FaucetInlet; + + interface def WaterDelivery { + end [1] port suppliedBy : SpigotBank { + port hot : Spigot; + port cold : Spigot; + } + end [1..*] port deliveredTo : Faucet { + port hot : FaucetInlet; + port cold : FaucetInlet; + } + + connect suppliedBy.hot to deliveredTo.hot; + connect suppliedBy.cold to deliveredTo.cold; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Example.sysml b/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Example.sysml new file mode 100644 index 00000000..a62e41b9 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/11. Interfaces/Interface Example.sysml @@ -0,0 +1,19 @@ +package 'Interface Example' { + private import 'Port Example'::*; + + part def Vehicle; + + interface def FuelInterface { + end supplierPort : FuelOutPort; + end consumerPort : FuelInPort; + } + + part vehicle : Vehicle { + part tankAssy : FuelTankAssembly; + part eng : Engine; + + interface : FuelInterface connect + supplierPort ::> tankAssy.fuelTankPort to + consumerPort ::> eng.engineFuelPort; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-1.sysml b/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-1.sysml new file mode 100644 index 00000000..5b4f3cee --- /dev/null +++ b/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-1.sysml @@ -0,0 +1,29 @@ +package 'Binding Connectors Example-1' { + private import 'Port Example'::*; + + part def Vehicle; + part def FuelPump; + part def FuelTank; + + part vehicle : Vehicle { + part tank : FuelTankAssembly { + port redefines fuelTankPort { + out item redefines fuelSupply; + in item redefines fuelReturn; + } + + bind fuelTankPort.fuelSupply = pump.pumpOut; + bind fuelTankPort.fuelReturn = tank.fuelIn; + + part pump : FuelPump { + out item pumpOut : Fuel; + in item pumpIn : Fuel; + } + + part tank : FuelTank { + out item fuelOut : Fuel; + in item fuelIn : Fuel; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-2.sysml b/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-2.sysml new file mode 100644 index 00000000..ef999e7c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/12. Binding Connectors/Binding Connectors Example-2.sysml @@ -0,0 +1,26 @@ +package 'Binding Connectors Example-2' { + private import 'Port Example'::*; + + part def Vehicle; + part def FuelPump; + part def FuelTank; + + part vehicle : Vehicle { + part tank : FuelTankAssembly { + port redefines fuelTankPort { + out item redefines fuelSupply; + in item redefines fuelReturn; + } + + part pump : FuelPump { + out item pumpOut : Fuel = fuelTankPort.fuelSupply; + in item pumpIn : Fuel; + } + + part tank : FuelTank { + out item fuelOut : Fuel; + in item fuelIn : Fuel = fuelTankPort.fuelReturn; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/13. Flows/Flow Definition Example.sysml b/test-data/sysml2/official/sysml/training/13. Flows/Flow Definition Example.sysml new file mode 100644 index 00000000..eb1d1515 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/13. Flows/Flow Definition Example.sysml @@ -0,0 +1,21 @@ +package 'Flow Definition Example' { + private import 'Port Example'::*; + + part def Vehicle; + + flow def FuelFlow { + ref :>> payload : Fuel; + end port supplierPort : FuelOutPort; + end port consumerPort : FuelInPort; + } + + part vehicle : Vehicle { + part tankAssy : FuelTankAssembly; + part eng : Engine; + + flow : FuelFlow of Fuel + from tankAssy.fuelTankPort.fuelSupply + to eng.engineFuelPort.fuelSupply; + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/13. Flows/Flow Interface Example.sysml b/test-data/sysml2/official/sysml/training/13. Flows/Flow Interface Example.sysml new file mode 100644 index 00000000..4318fcf1 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/13. Flows/Flow Interface Example.sysml @@ -0,0 +1,22 @@ +package 'Flow Interface Example' { + private import 'Port Example'::*; + + part def Vehicle; + + interface def FuelInterface { + end supplierPort : FuelOutPort; + end consumerPort : FuelInPort; + + flow supplierPort.fuelSupply to consumerPort.fuelSupply; + flow consumerPort.fuelReturn to supplierPort.fuelReturn; + } + + part vehicle : Vehicle { + part tankAssy : FuelTankAssembly; + part eng : Engine; + + interface : FuelInterface connect + supplierPort ::> tankAssy.fuelTankPort to + consumerPort ::> eng.engineFuelPort; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/13. Flows/Flow Usage Example.sysml b/test-data/sysml2/official/sysml/training/13. Flows/Flow Usage Example.sysml new file mode 100644 index 00000000..8959cf69 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/13. Flows/Flow Usage Example.sysml @@ -0,0 +1,18 @@ +package 'Flow Usage Example' { + private import 'Port Example'::*; + + part def Vehicle; + + part vehicle : Vehicle { + part tankAssy : FuelTankAssembly; + part eng : Engine; + + flow of Fuel + from tankAssy.fuelTankPort.fuelSupply + to eng.engineFuelPort.fuelSupply; + + flow of Fuel + from eng.engineFuelPort.fuelReturn + to tankAssy.fuelTankPort.fuelReturn; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Definition Example.sysml b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Definition Example.sysml new file mode 100644 index 00000000..0a00dffc --- /dev/null +++ b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Definition Example.sysml @@ -0,0 +1,21 @@ +package 'Action Definition Example' { + item def Scene; + item def Image; + item def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + + action def TakePicture { in scene : Scene; out picture : Picture; + bind focus.scene = scene; + + action focus: Focus { in scene; out image; } + + flow from focus.image to shoot.image; + + action shoot: Shoot { in image; out picture; } + + bind shoot.picture = picture; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Shorthand Example.sysml b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Shorthand Example.sysml new file mode 100644 index 00000000..eb796991 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Shorthand Example.sysml @@ -0,0 +1,26 @@ +package 'Action Shorthand Example' { + item def Scene; + item def Image; + item def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + + action def TakePicture { + in item scene : Scene; + out item picture : Picture; + + action focus: Focus { + in item scene = TakePicture::scene; + out item image; + } + + flow from focus.image to shoot.image; + + then action shoot: Shoot { + in item; + out item picture = TakePicture::picture; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-1.sysml b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-1.sysml new file mode 100644 index 00000000..a9d14c4a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-1.sysml @@ -0,0 +1,26 @@ +package 'Action Succession Example-1' { + item def Scene; + item def Image; + item def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + + action def TakePicture { + in item scene : Scene; + out item picture : Picture; + + bind focus.scene = scene; + + action focus: Focus { in scene; out image; } + + flow from focus.image to shoot.image; + + first focus then shoot; + + action shoot: Shoot { in image; out picture; } + + bind shoot.picture = picture; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-2.sysml b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-2.sysml new file mode 100644 index 00000000..294fe05f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/14. Action Definitions/Action Succession Example-2.sysml @@ -0,0 +1,24 @@ +package 'Action Definition Example' { + item def Scene; + item def Image; + item def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + + action def TakePicture { + in item scene : Scene; + out item picture : Picture; + + bind focus.scene = scene; + + action focus: Focus { in scene; out image; } + + succession flow from focus.image to shoot.image; + + action shoot: Shoot { in image; out picture; } + + bind shoot.picture = picture; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/15. Actions/Action Decomposition.sysml b/test-data/sysml2/official/sysml/training/15. Actions/Action Decomposition.sysml new file mode 100644 index 00000000..3209a6ee --- /dev/null +++ b/test-data/sysml2/official/sysml/training/15. Actions/Action Decomposition.sysml @@ -0,0 +1,27 @@ +package 'Action Decomposition' { + part def Scene; + part def Image; + part def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + action def TakePicture { in scene : Scene; out picture : Picture; } + + action takePicture : TakePicture { + in item scene; + out item picture; + + action focus : Focus { + in item scene = takePicture::scene; + out item image; + } + + flow from focus.image to shoot.image; + + action shoot : Shoot { + in item; + out item picture = takePicture::picture; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-1.sysml b/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-1.sysml new file mode 100644 index 00000000..9b7335ef --- /dev/null +++ b/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-1.sysml @@ -0,0 +1,32 @@ +package 'Conditional Succession Example-1' { + part def Scene; + part def Image { + isWellFocused: ScalarValues::Boolean; + } + part def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + action def TakePicture { in scene : Scene; out picture : Picture; } + + action takePicture : TakePicture { + in item scene; + out item picture; + + action focus : Focus { + in item scene = takePicture::scene; + out item image; + } + + first focus + if focus.image.isWellFocused then shoot; + + flow from focus.image to shoot.image; + + action shoot : Shoot { + in item; + out item picture = takePicture::picture; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-2.sysml b/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-2.sysml new file mode 100644 index 00000000..472bf017 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/16. Conditional Succession/Conditional Succession Example-2.sysml @@ -0,0 +1,31 @@ +package 'Conditional Succession Example-2' { + part def Scene; + part def Image { + isWellFocused: ScalarValues::Boolean; + } + part def Picture; + + action def Focus { in scene : Scene; out image : Image; } + action def Shoot { in image: Image; out picture : Picture; } + action def TakePicture { in scene : Scene; out picture : Picture; } + + action takePicture : TakePicture { + in item scene; + out item picture; + + action focus : Focus { + in item scene = takePicture::scene; + out item image; + } + + if focus.image.isWellFocused then shoot; + + flow from focus.image to shoot.image; + + action shoot : Shoot { + in item image; + out item picture = takePicture::picture; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/17. Control/Camera.sysml b/test-data/sysml2/official/sysml/training/17. Control/Camera.sysml new file mode 100644 index 00000000..ad43eb51 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/17. Control/Camera.sysml @@ -0,0 +1,25 @@ +package Camera { + private import 'Action Decomposition'::*; + + part def Camera; + part def FocusingSubsystem; + part def ImagingSubsystem; + + part camera : Camera { + ref item scene : Scene; + part photos : Picture[*]; + + part autoFocus { + in ref item scene : Scene = camera::scene; + out ref item realImage : Image; + } + + flow autoFocus.realImage to imager.focusedImage; + + part imager { + in item focusedImage : Image; + out item photo : Picture :> photos; + } + + } +} diff --git a/test-data/sysml2/official/sysml/training/17. Control/Control Structures Example.sysml b/test-data/sysml2/official/sysml/training/17. Control/Control Structures Example.sysml new file mode 100644 index 00000000..7f78acb4 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/17. Control/Control Structures Example.sysml @@ -0,0 +1,29 @@ +package 'Control Structures Example' { + private import ScalarValues::*; + + attribute def BatteryCharged; + + part battery; + part powerSystem; + + action def MonitorBattery { out charge : Real; } + action def AddCharge { in charge : Real; } + action def EndCharging; + + action def ChargeBattery { + loop action charging { + action monitor : MonitorBattery { + out charge; + } + + then if monitor.charge < 100 { + action addCharge : AddCharge { + in charge = monitor.charge; + } + } + } until charging.monitor.charge >= 100; + + then action endCharging : EndCharging; + then done; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/17. Control/Decision Example.sysml b/test-data/sysml2/official/sysml/training/17. Control/Decision Example.sysml new file mode 100644 index 00000000..f3b57929 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/17. Control/Decision Example.sysml @@ -0,0 +1,34 @@ +package 'Decision Example' { + private import ScalarValues::*; + + attribute def BatteryCharged; + + part battery; + part powerSystem; + + action def MonitorBattery { out charge : Real; } + action def AddCharge { in charge : Real; } + action def EndCharging; + + action def ChargeBattery { + first start; + + then merge continueCharging; + + then action monitor : MonitorBattery { + out batteryCharge : Real; + } + + then decide; + if monitor.batteryCharge < 100 then addCharge; + if monitor.batteryCharge >= 100 then endCharging; + + action addCharge : AddCharge { + in charge = monitor.batteryCharge; + } + then continueCharging; + + action endCharging : EndCharging; + then done; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/17. Control/Fork Join Example.sysml b/test-data/sysml2/official/sysml/training/17. Control/Fork Join Example.sysml new file mode 100644 index 00000000..74806b41 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/17. Control/Fork Join Example.sysml @@ -0,0 +1,41 @@ +package 'Fork Join Example' { + private import ScalarValues::*; + + attribute def TurnKeyToOn; + attribute def BrakePressure; + + action def MonitorBrakePedal { out pressure : BrakePressure; } + action def MonitorTraction { out modFreq : Real; } + action def Braking { in brakePressure : BrakePressure; in modulationFrequency : Real; } + + action def Brake { + action TurnOn; + + then fork; + then monitorBrakePedal; + then monitorTraction; + then braking; + + action monitorBrakePedal : MonitorBrakePedal { + out brakePressure; + } + then joinNode; + + action monitorTraction : MonitorTraction { + out modulationFrequency; + } + then joinNode; + + flow from monitorBrakePedal.brakePressure to braking.brakePressure; + flow from monitorTraction.modulationFrequency to braking.modulationFrequency; + + action braking : Braking { + in brakePressure; + in modulationFrequency; + } + then joinNode; + + join joinNode; + then done; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/17. Control/Merge Example.sysml b/test-data/sysml2/official/sysml/training/17. Control/Merge Example.sysml new file mode 100644 index 00000000..920e4a5d --- /dev/null +++ b/test-data/sysml2/official/sysml/training/17. Control/Merge Example.sysml @@ -0,0 +1,42 @@ +package 'Merge Example' { + part def Scene; + part def Image; + part def Picture; + + action def Focus { in item scene : Scene; out item image : Image; } + action def Shoot { in item image : Image; out item picture : Picture; } + action def Display { in item picture : Picture; } + action def TakePicture; + + action takePicture : TakePicture { + first start; + + then merge continue; + + then action trigger { + out item scene : Scene; + } + + flow from trigger.scene to focus.scene; + + then action focus : Focus { + in item scene; + out item image; + } + + flow from focus.image to shoot.image; + + then action shoot : Shoot { + in item image ; + out item picture; + } + + flow from shoot.picture to display.picture; + + then action display : Display { + in item picture; + } + + then continue; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/18. Action Performance/Action Performance Example.sysml b/test-data/sysml2/official/sysml/training/18. Action Performance/Action Performance Example.sysml new file mode 100644 index 00000000..db12fdb1 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/18. Action Performance/Action Performance Example.sysml @@ -0,0 +1,21 @@ +package 'Action Performance Example' { + private import 'Action Decomposition'::*; + + part def Camera; + part def AutoFocus; + part def Imager; + + part camera : Camera { + + perform action takePhoto[*] ordered + references takePicture; + + part f : AutoFocus { + perform takePhoto.focus; + } + + part i : Imager { + perform takePhoto.shoot; + } + } +} diff --git a/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-1.sysml b/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-1.sysml new file mode 100644 index 00000000..2bbf1b3a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-1.sysml @@ -0,0 +1,28 @@ +package 'Terminate Actions Example-1' { + private import ScalarValues::Boolean; + + action monitorCriticalActivity; + action criticalActivity; + action waitForTimeOut; + + action def MonitoredActivity { + first start; + + then fork; + then performCriticalActivity; + then waitForTimeOut; + + action performCriticalActivity { + perform monitorCriticalActivity; + + perform criticalActivity; + then terminate; + } + then stop; + + action waitForTimeOut; + then stop; + + action stop terminate; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-2.sysml b/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-2.sysml new file mode 100644 index 00000000..1822ad0e --- /dev/null +++ b/test-data/sysml2/official/sysml/training/19. Terminate Actions/Terminate Actions Example-2.sysml @@ -0,0 +1,20 @@ +package 'Terminate Actions Example-2' { + action def WorkflowProcess; + + part def Processor { + ref action workflowProcess : WorkflowProcess; + + action internalProcess { + // ... + } + } + + action terminateProcessing { + in processor : Processor; + + terminate processor.workflowProcess; + + terminate processor; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/20. Assignment Actions/Assignment Example.sysml b/test-data/sysml2/official/sysml/training/20. Assignment Actions/Assignment Example.sysml new file mode 100644 index 00000000..fafc72b4 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/20. Assignment Actions/Assignment Example.sysml @@ -0,0 +1,41 @@ +package 'For Loop Example' { + private import SequenceFunctions::*; + + action def StraightLineDynamics { + in power : ISQ::PowerValue; + in mass : ISQ::MassValue; + in delta_t : ISQ::TimeValue; + in x_in : ISQ::LengthValue; + in v_in : ISQ::SpeedValue; + out x_out : ISQ::LengthValue; + out v_out : ISQ::SpeedValue; + } + + action def ComputeMotion { + in attribute powerProfile :> ISQ::power[*]; + in attribute vehicleMass :> ISQ::mass; + in attribute initialPosition :> ISQ::length; + in attribute initialSpeed :> ISQ::speed; + in attribute deltaT :> ISQ::time; + out attribute positions :> ISQ::length[*] := ( ); + + private attribute position := initialPosition; + private attribute speed := initialSpeed; + + for vehiclePower in powerProfile { + perform action dynamics : StraightLineDynamics { + in power = vehiclePower; + in mass = vehicleMass; + in delta_t = deltaT; + in x_in = position; + in v_in = speed; + out x_out; + out v_out; + } + then assign position := dynamics.x_out; + then assign speed := dynamics.v_out; + then assign positions := positions->including(position); + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging Example.sysml b/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging Example.sysml new file mode 100644 index 00000000..c9ee543c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging Example.sysml @@ -0,0 +1,33 @@ +package 'Messaging Example' { + item def Scene; + item def Image; + item def Picture; + + attribute def Show { + item picture : Picture; + } + + action def Focus { in item scene : Scene; out item image : Image; } + action def Shoot { in item image : Image; out item picture : Picture; } + action def TakePicture; + + action screen; + + action takePicture : TakePicture { + action trigger accept scene : Scene; + + then action focus : Focus { + in item scene = trigger.scene; + out item image; + } + + flow from focus.image to shoot.image; + + then action shoot : Shoot { + in item image; + out item picture; + } + + then send new Show(shoot.picture) to screen; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging with Ports.sysml b/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging with Ports.sysml new file mode 100644 index 00000000..6b3a1561 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/21. Asynchronous Messaging/Messaging with Ports.sysml @@ -0,0 +1,40 @@ +package 'Messaging Example' { + item def Scene; + item def Image; + item def Picture; + + attribute def Show { + item picture : Picture; + } + + action def Focus { in item scene : Scene; out item image : Image; } + action def Shoot { in item image : Image; out item picture : Picture; } + action def TakePicture; + + part screen { + port displayPort; + } + + part camera { + port viewPort; + port displayPort; + + action takePicture : TakePicture { + action trigger accept scene : Scene via viewPort; + + then action focus : Focus { + in item scene = trigger.scene; + out item image; + } + + flow from focus.image to shoot.image; + + then action shoot : Shoot { + in item image; + out item picture; + } + + then send new Show(shoot.picture) via displayPort; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/22. Opaque Actions/Opaque Action Example.sysml b/test-data/sysml2/official/sysml/training/22. Opaque Actions/Opaque Action Example.sysml new file mode 100644 index 00000000..b6a4f7fd --- /dev/null +++ b/test-data/sysml2/official/sysml/training/22. Opaque Actions/Opaque Action Example.sysml @@ -0,0 +1,19 @@ +package 'Opaque Action Example' { + + part def Sensor { + attribute ready : ScalarValues::Boolean; + } + + action def UpdateSensors { + in sensors : Sensor[*]; + language "Alf" + /* + * for (sensor in sensors) { + * if (sensor.ready) { + * Update(sensor); + * } + * } + */ + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-1.sysml b/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-1.sysml new file mode 100644 index 00000000..7e984198 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-1.sysml @@ -0,0 +1,32 @@ +package 'State Definition Example-1' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + state def VehicleStates { + first start then off; + + state off; + + transition off_to_starting + first off + accept VehicleStartSignal + then starting; + + state starting; + + transition starting_to_on + first starting + accept VehicleOnSignal + then on; + + state on; + + transition on_to_off + first on + accept VehicleOffSignal + then off; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-2.sysml b/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-2.sysml new file mode 100644 index 00000000..27fe08fa --- /dev/null +++ b/test-data/sysml2/official/sysml/training/23. State Definitions/State Definition Example-2.sysml @@ -0,0 +1,23 @@ +package 'State Definition Example-2' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + state def VehicleStates { + first start then off; + + state off; + accept VehicleStartSignal + then starting; + + state starting; + accept VehicleOnSignal + then on; + + state on; + accept VehicleOffSignal + then off; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/24. States/State Actions.sysml b/test-data/sysml2/official/sysml/training/24. States/State Actions.sysml new file mode 100644 index 00000000..e37af4d2 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/24. States/State Actions.sysml @@ -0,0 +1,35 @@ +package 'State Actions' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + part def Vehicle; + + action performSelfTest { in vehicle : Vehicle; } + + state def VehicleStates { in operatingVehicle : Vehicle; } + + state vehicleStates : VehicleStates { + in operatingVehicle : Vehicle; + + first start then off; + + state off; + accept VehicleStartSignal + then starting; + + state starting; + accept VehicleOnSignal + then on; + + state on { + entry performSelfTest{ in vehicle = operatingVehicle; } + do action providePower { /* ... */ } + exit action applyParkingBrake { /* ... */ } + } + accept VehicleOffSignal + then off; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/24. States/State Decomposition-1.sysml b/test-data/sysml2/official/sysml/training/24. States/State Decomposition-1.sysml new file mode 100644 index 00000000..04d39bf4 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/24. States/State Decomposition-1.sysml @@ -0,0 +1,25 @@ +package 'State Decomposition-1' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + state def VehicleStates; + + state vehicleStates : VehicleStates { + first start then off; + + state off; + accept VehicleStartSignal + then starting; + + state starting; + accept VehicleOnSignal + then on; + + state on; + accept VehicleOffSignal + then off; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/24. States/State Decomposition-2.sysml b/test-data/sysml2/official/sysml/training/24. States/State Decomposition-2.sysml new file mode 100644 index 00000000..15ab69dd --- /dev/null +++ b/test-data/sysml2/official/sysml/training/24. States/State Decomposition-2.sysml @@ -0,0 +1,32 @@ +package 'State Decomposition-1' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + state def VehicleStates; + + state vehicleStates : VehicleStates parallel { + + state operationalStates { + first start then off; + + state off; + accept VehicleStartSignal + then starting; + + state starting; + accept VehicleOnSignal + then on; + + state on; + accept VehicleOffSignal + then off; + } + + state healthStates { + /* ... */ + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/25. Transitions/Change and Time Triggers.sysml b/test-data/sysml2/official/sysml/training/25. Transitions/Change and Time Triggers.sysml new file mode 100644 index 00000000..d9f5fcd8 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/25. Transitions/Change and Time Triggers.sysml @@ -0,0 +1,43 @@ +package 'Change and Time Triggers' { + private import ISQ::TemperatureValue; + private import ISQ::DurationValue; + private import Time::TimeInstantValue; + private import SI::h; + + attribute def OverTemp; + + part def Vehicle { + attribute maintenanceTime : TimeInstantValue; + attribute maintenanceInterval : DurationValue; + attribute maxTemperature : TemperatureValue; + } + + part def VehicleController; + + action senseTemperature { out temp : TemperatureValue; } + + state healthStates { + in vehicle : Vehicle; + in controller : VehicleController; + + first start then normal; + do senseTemperature; + + state normal; + accept at vehicle.maintenanceTime + then maintenance; + accept when senseTemperature.temp > vehicle.maxTemperature + do send new OverTemp() to controller + then degraded; + + state maintenance { + entry assign vehicle.maintenanceTime := vehicle.maintenanceTime + vehicle.maintenanceInterval; + } + accept after 48 [h] + then normal; + + state degraded; + accept when senseTemperature.temp <= vehicle.maxTemperature + then normal; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/25. Transitions/Local Clock Example.sysml b/test-data/sysml2/official/sysml/training/25. Transitions/Local Clock Example.sysml new file mode 100644 index 00000000..7f68624e --- /dev/null +++ b/test-data/sysml2/official/sysml/training/25. Transitions/Local Clock Example.sysml @@ -0,0 +1,32 @@ +package 'Local Clock Example' { + private import ScalarValues::String; + + item def Start; + item def Request; + + part def Server { + part :>> localClock = new Time::Clock(); + + attribute today : String; + + port requestPort; + + state ServerBehavior { + first start then off; + + state off; + accept Start via requestPort + then waiting; + + state waiting; + accept request : Request via requestPort + then responding; + accept at new Time::Iso8601DateTime(today + "11:59:00") + then off; + + state responding; + accept after 5 [SI::min] + then waiting; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/25. Transitions/Transition Actions.sysml b/test-data/sysml2/official/sysml/training/25. Transitions/Transition Actions.sysml new file mode 100644 index 00000000..781a570f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/25. Transitions/Transition Actions.sysml @@ -0,0 +1,44 @@ +package 'Transition Actions' { + + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + + attribute def ControllerStartSignal; + + part def Vehicle { + brakePedalDepressed : ScalarValues::Boolean; + } + part def VehicleController; + + action performSelfTest { in vehicle : Vehicle; } + + state def VehicleStates; + + state vehicleStates : VehicleStates { + in operatingVehicle : Vehicle; + in controller : VehicleController; + + first start then off; + + state off; + accept VehicleStartSignal + then starting; + + state starting; + accept VehicleOnSignal + if operatingVehicle.brakePedalDepressed + do send new ControllerStartSignal() to controller + then on; + + state on { + entry performSelfTest{ in vehicle = operatingVehicle; } + do action providePower { /* ... */ } + exit action applyParkingBrake { /* ... */ } + } + accept VehicleOffSignal + then off; + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/26. State Exhibition/State Exhibition Example.sysml b/test-data/sysml2/official/sysml/training/26. State Exhibition/State Exhibition Example.sysml new file mode 100644 index 00000000..1b3ad852 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/26. State Exhibition/State Exhibition Example.sysml @@ -0,0 +1,15 @@ +package 'State Exhibition Example' { + private import 'Transition Actions'::*; + + part vehicle : Vehicle { + + part vehicleController : VehicleController; + + exhibit vehicleStates { + in operatingVehicle = vehicle; + in controller = vehicleController; + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Event Occurrence Example.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Event Occurrence Example.sysml new file mode 100644 index 00000000..1687e3ee --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Event Occurrence Example.sysml @@ -0,0 +1,29 @@ +package 'Event Occurrence Example' { + part def Driver; + part def CruiseController; + part def Speedometer; + part def Engine; + part def Vehicle; + + part driver : Driver { + event occurrence setSpeedSent; + } + + part vehicle : Vehicle { + + part cruiseController : CruiseController { + event occurrence setSpeedReceived; + then event occurrence sensedSpeedReceived; + then event occurrence fuelCommandSent; + } + + part speedometer : Speedometer { + event occurrence sensedSpeedSent; + } + + part engine : Engine { + event occurrence fuelCommandReceived; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-1.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-1.sysml new file mode 100644 index 00000000..ad0775d7 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-1.sysml @@ -0,0 +1,23 @@ +package 'Interaction Example-1' { + public import 'Event Occurrence Example'::*; + + item def SetSpeed; + item def SensedSpeed; + item def FuelCommand; + + occurrence def CruiseControlInteraction { + ref part :>> driver; + ref part :>> vehicle; + + message setSpeedMessage of SetSpeed + from driver.setSpeedSent to vehicle.cruiseController.setSpeedReceived; + + message sensedSpeedMessage of SensedSpeed + from vehicle.speedometer.sensedSpeedSent to vehicle.cruiseController.sensedSpeedReceived; + + message fuelCommandMessage of FuelCommand + from vehicle.cruiseController.fuelCommandSent to vehicle.engine.fuelCommandReceived; + + first setSpeedMessage then sensedSpeedMessage; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-2.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-2.sysml new file mode 100644 index 00000000..877b1d8f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Example-2.sysml @@ -0,0 +1,34 @@ +package 'Interaction Example-2' { + private import 'Event Occurrence Example'::*; + + item def SetSpeed; + item def SensedSpeed; + item def FuelCommand; + + occurrence def CruiseControlInteraction { + + ref part driver : Driver { + event setSpeedMessage.sourceEvent; + } + + ref part vehicle : Vehicle { + part cruiseController : CruiseController { + event setSpeedMessage.targetEvent; + then event sensedSpeedMessage.targetEvent; + then event fuelCommandMessage.sourceEvent; + } + + part speedometer : Speedometer { + event sensedSpeedMessage.sourceEvent; + } + + part engine : Engine { + event fuelCommandMessage.targetEvent; + } + } + + message setSpeedMessage of SetSpeed; + then message sensedSpeedMessage of SensedSpeed; + message fuelCommandMessage of FuelCommand; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-1.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-1.sysml new file mode 100644 index 00000000..2bc4eba3 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-1.sysml @@ -0,0 +1,55 @@ +package 'Interaction Realization-1' { + private import 'Interaction Example-1'::*; + + part driver_a : Driver { + action driverBehavior { + action sendSetSpeed send new SetSpeed() to vehicle_a; + } + } + + part vehicle_a : Vehicle { + part cruiseController_a : CruiseController { + action controllerBehavior { + action receiveSetSpeed accept SetSpeed via vehicle_a; + then action receiveSensedSpeed accept SensedSpeed via cruiseController_a; + then action sendFuelCommand send new FuelCommand() to engine_a; + } + } + + part speedometer_a : Speedometer { + action speedometerBehavior { + action sendSensedSpeed send new SensedSpeed() to cruiseController_a; + } + } + + part engine_a : Engine { + action engineBehavior { + action receiveFuelCommand accept FuelCommand via engine_a; + } + } + } + + occurrence cruiseControlInteraction_a : CruiseControlInteraction { + part :>> driver :>> driver_a { + event driverBehavior.sendSetSpeed[1] :>> setSpeedSent; + } + + part :>> vehicle :>> vehicle_a { + part :>> cruiseController :>> cruiseController_a { + event controllerBehavior.receiveSetSpeed[1] :>> setSpeedReceived; + event controllerBehavior.receiveSensedSpeed[1] :>> sensedSpeedReceived; + event controllerBehavior.sendFuelCommand[1] :>> fuelCommandSent; + } + part :>> speedometer :>> speedometer_a { + event speedometerBehavior.sendSensedSpeed[1] :>> sensedSpeedSent; + } + part :>> engine :>> engine_a { + event engineBehavior.receiveFuelCommand[1] :>> fuelCommandReceived; + } + } + + message :>> setSpeedMessage = driver_a.driverBehavior.sendSetSpeed.sentMessage; + message :>> sensedSpeedMessage = vehicle_a.speedometer_a.speedometerBehavior.sendSensedSpeed.sentMessage; + message :>> fuelCommandMessage = vehicle_a.cruiseController_a.controllerBehavior.sendFuelCommand.sentMessage; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-2.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-2.sysml new file mode 100644 index 00000000..dc83c5a5 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Interaction Realization-2.sysml @@ -0,0 +1,82 @@ +package 'Interaction Realization-2' { + private import 'Interaction Example-1'::*; + + part driver_b : Driver { + port setSpeedPort { + out setSpeed : SetSpeed; + } + } + + interface driverToVehicleInterface connect driver_b.setSpeedPort to vehicle_b.setSpeedPort { + flow setSpeedFlow of SetSpeed + from driver_b.setSpeedPort.setSpeed to vehicle_b.setSpeedPort.setSpeed; + } + + part vehicle_b : Vehicle { + port setSpeedPort { + in setSpeed : SetSpeed; + } + + bind setSpeedPort = cruiseController_b.setSpeedPort; + + part cruiseController_b : CruiseController { + port setSpeedPort { + in setSpeed : SetSpeed; + } + port sensedSpeedPort { + in sensedSpeed : SensedSpeed; + } + port fuelCommandPort { + out fuelCommand : FuelCommand; + } + } + + flow sensedSpeedFlow of SensedSpeed + from speedometer_b.sensedSpeedPort.sensedSpeed to cruiseController_b.sensedSpeedPort.sensedSpeed; + + part speedometer_b : Speedometer { + port sensedSpeedPort { + out sensedSpeed : SensedSpeed; + } + } + + flow fuelCommandFlow of FuelCommand + from cruiseController_b.fuelCommandPort.fuelCommand to engine_b.fuelCommandPort.fuelCommand; + + part engine_b : Engine { + port fuelCommandPort { + in fuelCommand : FuelCommand; + } + } + } + + occurrence cruiseControlInteraction_b : CruiseControlInteraction { + part :>> driver :>> driver_b { + port :>> setSpeedPort { + event driver::setSpeedSent; + } + } + + part :>> vehicle :>> vehicle_b { + part :>> cruiseController :>> cruiseController_b { + port :>> setSpeedPort { + event cruiseController::setSpeedReceived; + } + } + part :>> speedometer :>> speedometer_b { + port :>> sensedSpeedPort { + event speedometer::sensedSpeedSent; + } + } + part :>> engine :>> engine_b { + port :>> fuelCommandPort { + event engine::fuelCommandReceived; + } + } + } + + message :>> setSpeedMessage = driverToVehicleInterface.setSpeedFlow; + message :>> sensedSpeedMessage = vehicle_b.sensedSpeedFlow; + message :>> fuelCommandMessage = vehicle_b.fuelCommandFlow; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Message Payload Example.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Message Payload Example.sysml new file mode 100644 index 00000000..8bf70101 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Message Payload Example.sysml @@ -0,0 +1,36 @@ +package 'Message Payload Example' { + private import 'Event Occurrence Example'::*; + + item def SetSpeed; + item def SensedSpeed; + item def FuelCommand { + attribute fuelFlow : ScalarValues::Real; + } + + part def EngineController; + + part vehicle1 :> vehicle { + part engineController : EngineController { + event occurrence fuelCommandReceived; + then event occurrence fuelCommandForwarded; + } + } + + occurrence def CruiseControlInteraction { + ref part :>> driver; + ref part vehicle :>> vehicle1; + + message setSpeedMessage of SetSpeed + from driver.setSpeedSent to vehicle.cruiseController.setSpeedReceived; + + then message sensedSpeedMessage of SensedSpeed + from vehicle.speedometer.sensedSpeedSent to vehicle.cruiseController.sensedSpeedReceived; + + then message fuelCommandMessage of fuelCommand : FuelCommand + from vehicle.cruiseController.fuelCommandSent to vehicle.engineController.fuelCommandReceived; + + then message fuelCommandForwardingMessage of fuelCommand : FuelCommand = fuelCommandMessage.fuelCommand + from vehicle.engineController.fuelCommandForwarded to vehicle.engine.fuelCommandReceived; + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/27. Occurrences/Time Slice and Snapshot Example.sysml b/test-data/sysml2/official/sysml/training/27. Occurrences/Time Slice and Snapshot Example.sysml new file mode 100644 index 00000000..fb541ab8 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/27. Occurrences/Time Slice and Snapshot Example.sysml @@ -0,0 +1,27 @@ +package 'Time Slice and Snapshot Example' { + + attribute def Date; + item def Person; + + part def Vehicle { + timeslice assembly; + + first assembly then delivery; + + snapshot delivery { + attribute deliveryDate : Date; + } + + then timeslice ownership[0..*] ordered { + snapshot sale = start; + + ref item owner : Person[1]; + + timeslice driven[0..*] { + ref item driver : Person[1]; + } + } + + snapshot junked = done; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Roles-1.sysml b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Roles-1.sysml new file mode 100644 index 00000000..a5db93ad --- /dev/null +++ b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Roles-1.sysml @@ -0,0 +1,22 @@ +package 'Individuals and Roles' { + private import 'Part Definition Example'::*; + + part def Wheel; + + individual part def Vehicle_1 :> Vehicle { + part leftFrontWheel : Wheel; + part rightFrontWheel : Wheel; + } + + individual part def Wheel_1 :> Wheel; + + individual part vehicle_1 : Vehicle_1 { + snapshot part vehicle_1_t0 { + snapshot leftFrontWheel_t0 : Wheel_1 :>> leftFrontWheel; + } + + then snapshot part vehicle_1_t1 { + snapshot rightFrontWheel_t1 : Wheel_1 :>> rightFrontWheel; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Snapshots Example.sysml b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Snapshots Example.sysml new file mode 100644 index 00000000..9a1a9156 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Snapshots Example.sysml @@ -0,0 +1,24 @@ +package 'Individuals and Snapshots Example' { + public import 'Part Definition Example'::*; + + individual part def Vehicle_1 :> Vehicle { + + snapshot part vehicle_1_t0 { + :>> mass = 2000.0; + :>> status { + :>> gearSetting = 0; + :>> acceleratorPosition = 0.0; + } + } + + snapshot part vehicle_1_t1 { + :>> mass = 1500.0; + :>> status { + :>> gearSetting = 2; + :>> acceleratorPosition = 0.5; + } + } + + first vehicle_1_t0 then vehicle_1_t1; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Time Slices.sysml b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Time Slices.sysml new file mode 100644 index 00000000..f16c8a65 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/28. Individuals/Individuals and Time Slices.sysml @@ -0,0 +1,26 @@ +package 'Individuals and Time Slices' { + private import 'Individuals and Snapshots Example'::*; + + individual item def Alice :> Person; + individual item def Bob :> Person; + + individual : Vehicle_1 { + + timeslice aliceDriving { + ref individual item :>> driver : Alice; + + snapshot :>> start { + :>> mass = 2000.0; + } + + snapshot :>> done { + :>> mass = 1500.0; + } + } + + then timeslice bobDriving { + ref individual item :>> driver : Bob; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 1.sysml b/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 1.sysml new file mode 100644 index 00000000..4b2f889d --- /dev/null +++ b/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 1.sysml @@ -0,0 +1,38 @@ +package 'Car Mass Rollup Example 1' { + private import ScalarValues::*; + private import MassRollup1::*; + + part def CarPart :> MassedThing { + attribute serialNumber: String; + } + + part car: CarPart :> compositeThing { + attribute vin :>> serialNumber; + + part carParts: CarPart[*] :>> subcomponents; + + part engine :> simpleThing, carParts { + //... + } + + part transmission :> simpleThing, carParts { + //... + } + } + + // Example usage + + private import SI::kg; + part c :> car { + attribute :>> simpleMass = 1000[kg]; + part :>> engine { + attribute :>> simpleMass = 100[kg]; + } + + part redefines transmission { + attribute :>> simpleMass = 50[kg]; + } + } + + // c::totalMass --> 1150.0[kg] +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 2.sysml b/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 2.sysml new file mode 100644 index 00000000..c3f4ded9 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/29. Expressions/Car Mass Rollup Example 2.sysml @@ -0,0 +1,38 @@ +package 'Car Mass Rollup 1' { + private import ScalarValues::*; + private import MassRollup2::*; + + part def CarPart :> MassedThing { + attribute serialNumber: String; + } + + part car: CarPart :> compositeThing { + attribute vin :>> serialNumber; + + part carParts: CarPart[*] :>> subcomponents; + + part engine :> carParts { + //... + } + + part transmission :> carParts { + //... + } + } + + // Example usage + + private import SI::kg; + part c :> car { + attribute :>> simpleMass = 1000[kg]; + part :>> engine { + attribute :>> simpleMass = 100[kg]; + } + + part redefines transmission { + attribute :>> simpleMass = 50[kg]; + } + } + + // c::totalMass --> 1150.0[kg] +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup1.sysml b/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup1.sysml new file mode 100644 index 00000000..ef470076 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup1.sysml @@ -0,0 +1,19 @@ +package MassRollup1 { + private import NumericalFunctions::*; + + part def MassedThing { + attribute simpleMass :> ISQ::mass; + attribute totalMass :> ISQ::mass; + } + + part simpleThing : MassedThing { + attribute :>> totalMass = simpleMass; + } + + part compositeThing : MassedThing { + part subcomponents: MassedThing[*]; + attribute :>> totalMass = + simpleMass + sum(subcomponents.totalMass); + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup2.sysml b/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup2.sysml new file mode 100644 index 00000000..8866d064 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/29. Expressions/MassRollup2.sysml @@ -0,0 +1,21 @@ +package MassRollup2 { + private import NumericalFunctions::*; + + part def MassedThing { + attribute simpleMass :> ISQ::mass; + attribute totalMass :> ISQ::mass default simpleMass; + } + + part compositeThing : MassedThing { + part subcomponents: MassedThing[*]; + attribute :>> totalMass default + simpleMass + sum(subcomponents.totalMass); + } + + part filteredMassThing :> compositeThing { + attribute minMass :> ISQ::mass; + attribute :>> totalMass = + simpleMass + sum(subcomponents.totalMass.?{in p:>ISQ::mass; p >= minMass}); + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Definitions.sysml b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Definitions.sysml new file mode 100644 index 00000000..20b80263 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Definitions.sysml @@ -0,0 +1,23 @@ +package 'Calculation Definitions' { + private import ScalarValues::Real; + private import ISQ::*; + + calc def Power { in whlpwr : PowerValue; in Cd : Real; in Cf : Real; in tm : MassValue; in v : SpeedValue; + attribute drag = Cd * v; + attribute friction = Cf * tm * v; + + return : PowerValue = whlpwr - drag - friction; + } + + calc def Acceleration { in tp: PowerValue; in tm : MassValue; in v : SpeedValue; + return : AccelerationValue = tp / (tm * v); + } + + calc def Velocity { in dt : TimeValue; in v0 : SpeedValue; in a : AccelerationValue; + return : SpeedValue = v0 + a * dt; + } + + calc def Position { in dt : TimeValue; in x0 : LengthValue; in v : SpeedValue; + return : LengthValue = x0 + v * dt; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-1.sysml b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-1.sysml new file mode 100644 index 00000000..43012847 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-1.sysml @@ -0,0 +1,42 @@ +package 'Calculation Usages-1' { + private import ScalarValues::Real; + private import ISQ::*; + private import 'Calculation Definitions'::*; + + part def VehicleDynamics { + attribute C_d : Real; + attribute C_f : Real; + attribute wheelPower : PowerValue; + attribute mass : MassValue; + + action straightLineDynamics { + in delta_t : TimeValue; + in v_in : SpeedValue; + in x_in : LengthValue; + out v_out : SpeedValue = vel.v; + out x_out : LengthValue = pos.x; + + calc acc : Acceleration { + in tp = Power(wheelPower, C_d, C_f, mass, v_in); + in tm = mass; + in v = v_in; + return a; + } + + calc vel : Velocity { + in dt = delta_t; + in v0 = v_in; + in a = acc.a; + return v; + } + + calc pos : Position { + in dt = delta_t; + in x0 = x_in; + in v0 = vel.v; + return x; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-2.sysml b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-2.sysml new file mode 100644 index 00000000..88928ad2 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/30. Calculations/Calculation Usages-2.sysml @@ -0,0 +1,29 @@ +package 'Calculation Usages-2' { + private import ScalarValues::Real; + private import ISQ::*; + private import 'Calculation Definitions'::*; + + attribute def DynamicState { + attribute v: SpeedValue; + attribute x: LengthValue; + } + + part def VehicleDynamics { + attribute C_d : Real; + attribute C_f : Real; + attribute wheelPower : PowerValue; + attribute mass : MassValue; + + calc updateState { + in delta_t : TimeValue; + in currState : DynamicState; + attribute totalPower : PowerValue = Power(wheelPower, C_d, C_f, mass, currState.v); + + return attribute newState : DynamicState { + :>> v = Velocity(delta_t, currState.v, Acceleration(totalPower, mass, currState.v)); + :>> x = Position(delta_t, currState.x, currState.v); + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Analytical Constraints.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Analytical Constraints.sysml new file mode 100644 index 00000000..95362ec4 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Analytical Constraints.sysml @@ -0,0 +1,43 @@ +package 'Analytical Constraints' { + private import ISQ::*; + private import 'Calculation Definitions'::*; + + constraint def StraightLineDynamicsEquations { + in p : PowerValue; + in m : MassValue; + in dt : TimeValue; + in x_i : LengthValue; + in v_i : SpeedValue; + in x_f : LengthValue; + in v_f : SpeedValue; + in a : AccelerationValue; + + attribute v_avg : SpeedValue = (v_i + v_f)/2; + + a == Acceleration(p, m, v_avg) and + v_f == Velocity(dt, v_i, a) and + x_f == Position(dt, x_i, v_avg) + } + + action def StraightLineDynamics { + in power : PowerValue; + in mass : MassValue; + in delta_t : TimeValue; + in x_in : LengthValue; + in v_in : SpeedValue; + out x_out : LengthValue; + out v_out : SpeedValue; + out a_out : AccelerationValue; + + assert constraint dynamics : StraightLineDynamicsEquations { + in p = power; + in m = mass; + in dt = delta_t; + in x_i = x_in; + in v_i = v_in; + in x_f = x_out; + in v_f = v_out; + in a = a_out; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-1.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-1.sysml new file mode 100644 index 00000000..bd4d202c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-1.sysml @@ -0,0 +1,32 @@ +package 'Constraint Assertions-1' { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + part def Engine; + part def Transmission; + + constraint def MassConstraint { + in partMasses : MassValue[0..*]; + in massLimit : MassValue; + + sum(partMasses) <= massLimit + } + + part def Vehicle { + assert constraint massConstraint : MassConstraint { + in partMasses = (chassisMass, engine.mass, transmission.mass); + in massLimit = 2500[kg]; + } + + attribute chassisMass : MassValue; + + part engine : Engine { + attribute mass : MassValue; + } + + part transmission : Engine { + attribute mass : MassValue; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-2.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-2.sysml new file mode 100644 index 00000000..e18b2f62 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Constraint Assertions-2.sysml @@ -0,0 +1,37 @@ +package 'Constraint Assertions-2' { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + part def Engine; + part def Transmission; + + constraint def MassConstraint { + in partMasses : MassValue[0..*]; + in massLimit : MassValue; + } + + constraint massConstraint : MassConstraint { + in partMasses : MassValue[0..*]; + in massLimit : MassValue; + + sum(partMasses) <= massLimit + } + + part def Vehicle { + assert massConstraint { + in partMasses = (chassisMass, engine.mass, transmission.mass); + in massLimit = 2500[kg]; + } + + attribute chassisMass : MassValue; + + part engine : Engine { + attribute mass : MassValue; + } + + part transmission : Engine { + attribute mass : MassValue; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-1.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-1.sysml new file mode 100644 index 00000000..002f162c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-1.sysml @@ -0,0 +1,32 @@ +package 'Constraints Example-1' { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + part def Engine; + part def Transmission; + + constraint def MassConstraint { + in partMasses : MassValue[0..*]; + in massLimit : MassValue; + + sum(partMasses) <= massLimit + } + + part def Vehicle { + constraint massConstraint : MassConstraint { + in partMasses = (chassisMass, engine.mass, transmission.mass); + in massLimit = 2500[kg]; + } + + attribute chassisMass : MassValue; + + part engine : Engine { + attribute mass : MassValue; + } + + part transmission : Engine { + attribute mass : MassValue; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-2.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-2.sysml new file mode 100644 index 00000000..4024d62d --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Constraints Example-2.sysml @@ -0,0 +1,32 @@ +package 'Constraints Example-2' { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + part def Engine; + part def Transmission; + + constraint def MassConstraint { + attribute partMasses : MassValue[0..*]; + attribute massLimit : MassValue; + + sum(partMasses) <= massLimit + } + + part def Vehicle { + constraint massConstraint : MassConstraint { + redefines partMasses = (chassisMass, engine.mass, transmission.mass); + redefines massLimit = 2500[kg]; + } + + attribute chassisMass : MassValue; + + part engine : Engine { + attribute mass : MassValue; + } + + part transmission : Engine { + attribute mass : MassValue; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Derivation Constraints.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Derivation Constraints.sysml new file mode 100644 index 00000000..edec360a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Derivation Constraints.sysml @@ -0,0 +1,25 @@ +package 'Derivation Constraints' { + private import SI::*; + private import 'Constraints Example-1'::*; + + part vehicle1 : Vehicle { + attribute totalMass : MassValue; + assert constraint {totalMass == chassisMass + engine.mass + transmission.mass} + } + + part vehicle2 : Vehicle { + attribute totalMass : MassValue = chassisMass + engine.mass + transmission.mass; + } + + constraint def Dynamics { + in mass: MassValue; + in initialSpeed : SpeedValue; + in finalSpeed : SpeedValue; + in deltaT : TimeValue; + in force : ForceValue; + + force * deltaT == mass * (finalSpeed - initialSpeed) and + mass > 0[kg] + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/31. Constraints/Time Constraints.sysml b/test-data/sysml2/official/sysml/training/31. Constraints/Time Constraints.sysml new file mode 100644 index 00000000..8b70b8b4 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/31. Constraints/Time Constraints.sysml @@ -0,0 +1,37 @@ +package 'Time Constraints' { + private import ISQ::TemperatureValue; + private import ISQ::DurationValue; + private import Time::TimeInstantValue; + private import Time::TimeOf; + private import Time::DurationOf; + private import SI::h; + private import SI::s; + + attribute def MaintenanceDone; + + part def Vehicle { + attribute maintenanceTime : TimeInstantValue; + attribute maintenanceInterval : DurationValue; + attribute maxTemperature : TemperatureValue; + } + + state healthStates { + in vehicle : Vehicle; + + entry; then normal; + + state normal; + accept at vehicle.maintenanceTime + then maintenance; + + state maintenance { + assert constraint { TimeOf(maintenance) > vehicle.maintenanceTime } + assert constraint { TimeOf(maintenance) - TimeOf(normal.done) < 2 [s] } + entry assign vehicle.maintenanceTime := vehicle.maintenanceTime + vehicle.maintenanceInterval; + } + accept MaintenanceDone + then normal; + + constraint { DurationOf(maintenance) <= 48 [h] } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Definitions.sysml b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Definitions.sysml new file mode 100644 index 00000000..717ef217 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Definitions.sysml @@ -0,0 +1,42 @@ +package 'Requirement Definitions' { + private import ISQ::*; + private import SI::*; + + requirement def MassLimitationRequirement { + doc /* The actual mass shall be less than or equal to the required mass. */ + + attribute massActual: MassValue; + attribute massReqd: MassValue; + + require constraint { massActual <= massReqd } + } + + part def Vehicle { + attribute dryMass: MassValue; + attribute fuelMass: MassValue; + attribute fuelFullMass: MassValue; + } + + requirement def <'1'> VehicleMassLimitationRequirement :> MassLimitationRequirement { + doc /* The total mass of a vehicle shall be less than or equal to the required mass. */ + + subject vehicle : Vehicle; + + attribute redefines massActual = vehicle.dryMass + vehicle.fuelMass; + + assume constraint { vehicle.fuelMass > 0[kg] } + } + + port def ClutchPort; + action def GenerateTorque; + + requirement def <'2'> DrivePowerInterface { + doc /* The engine shall transfer its generated torque to the transmission via the clutch interface. */ + subject clutchPort: ClutchPort; + } + + requirement def <'3'> TorqueGeneration { + doc /* The engine shall generate torque as a function of RPM as shown in Table 1. */ + subject generateTorque: GenerateTorque; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Groups.sysml b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Groups.sysml new file mode 100644 index 00000000..bafb9c8e --- /dev/null +++ b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Groups.sysml @@ -0,0 +1,33 @@ +package 'Requirement Groups' { + private import 'Requirement Definitions'::*; + private import 'Requirement Usages'::*; + + part def Engine { + port clutchPort: ClutchPort; + perform action generateTorque: GenerateTorque; + } + + requirement vehicleSpecification { + doc /* Overall vehicle requirements group */ + + subject vehicle : Vehicle; + + require fullVehicleMassLimit; + require emptyVehicleMassLimit; + } + + requirement engineSpecification { + doc /* Engine power requirements group */ + + subject engine : Engine; + + requirement drivePowerInterface : DrivePowerInterface { + subject = engine.clutchPort; + } + + requirement torqueGeneration : TorqueGeneration { + subject = engine.generateTorque; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Satisfaction.sysml b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Satisfaction.sysml new file mode 100644 index 00000000..aa9836c2 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Satisfaction.sysml @@ -0,0 +1,27 @@ +package 'Requirement Satisfaction' { + private import 'Requirement Definitions'::*; + private import 'Requirement Groups'::*; + + action 'provide power' { + action 'generate torque' { } + } + + part vehicle_c1 : Vehicle { + perform 'provide power'; + + part engine_v1: Engine { + port :>> clutchPort; + perform 'provide power'.'generate torque' :>> generateTorque; + } + } + + part 'Vehicle c1 Design Context' { + + ref vehicle_design :> vehicle_c1; + + satisfy vehicleSpecification by vehicle_design; + satisfy engineSpecification by vehicle_design.engine_v1; + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Usages.sysml b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Usages.sysml new file mode 100644 index 00000000..20be3d47 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/32. Requirements/Requirement Usages.sysml @@ -0,0 +1,25 @@ +package 'Requirement Usages' { + private import SI::*; + private import 'Requirement Definitions'::*; + + requirement <'1.1'> fullVehicleMassLimit : VehicleMassLimitationRequirement { + subject vehicle : Vehicle; + attribute :>> massReqd = 2000[kg]; + + assume constraint { + doc /* Full tank is full. */ + vehicle.fuelMass == vehicle.fuelFullMass + } + } + + requirement <'1.2'> emptyVehicleMassLimit : VehicleMassLimitationRequirement { + subject vehicle : Vehicle; + attribute :>> massReqd = 1500[kg]; + + assume constraint { + doc /* Full tank is empty. */ + vehicle.fuelMass == 0[kg] + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Definition Example.sysml b/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Definition Example.sysml new file mode 100644 index 00000000..60eddb7a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Definition Example.sysml @@ -0,0 +1,86 @@ +package 'Analysis Case Definition Example' { + private import ScalarValues::Real; + private import 'Calculation Definitions'::*; + private import 'Analytical Constraints'::*; + private import USCustomaryUnits::*; + private import SequenceFunctions::size; + private import Quantities::ScalarQuantityValue; + private import ControlFunctions::*; + private import ScalarValues::Positive; + + attribute def DistancePerVolumeValue :> ScalarQuantityValue; + + part def Vehicle { + attribute mass : MassValue; + attribute cargoMass : MassValue; + + attribute wheelDiameter : LengthValue; + attribute driveTrainEfficiency : Real; + + attribute fuelEconomy_city : DistancePerVolumeValue; + attribute fuelEconomy_highway : DistancePerVolumeValue; + } + + attribute def WayPoint { + time : TimeValue; + position : LengthValue; + speed : SpeedValue; + } + + analysis def FuelEconomyAnalysis { + subject vehicle : Vehicle; + objective fuelEconomyAnalysisObjective { + /* + * The objective of this analysis is to determine whether the + * subject vehicle can satisfy the fuel economy requirement. + */ + + assume constraint { + vehicle.wheelDiameter == 33 ['in'] & + vehicle.driveTrainEfficiency == 0.4 + } + + require constraint { + fuelEconomyResult > 30 [mi / gal] + } + } + + in attribute scenario : WayPoint[*]; + + action solveForPower { + out power : PowerValue[*]; + out acceleration : AccelerationValue[*]; + + /* + * Solve for the required engine power as a function of time + * to support the scenario. + */ + assert constraint { + (1..size(scenario)-1)->forAll {in i: Positive; + StraightLineDynamicsEquations ( + power#(i), + vehicle.mass, + scenario.time#(i+1) - scenario.time#(i), + scenario.position#(i), + scenario.speed#(i), + scenario.position#(i+1), + scenario.speed#(i+1), + acceleration#(i+1) + ) + } + } + } + + then action solveForFuelConsumption { + in power : PowerValue[*] = solveForPower.power; + out fuelEconomy : DistancePerVolumeValue; + + /* + * Solve the engine equations to determine how much fuel is + * consumed. + */ + } + + return fuelEconomyResult : DistancePerVolumeValue = solveForFuelConsumption.fuelEconomy; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Usage Example.sysml b/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Usage Example.sysml new file mode 100644 index 00000000..062a6e06 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/33. Analysis/Analysis Case Usage Example.sysml @@ -0,0 +1,33 @@ +package 'Analysis Case Usage Example' { + private import 'Analysis Case Definition Example'::*; + + part vehicleFuelEconomyAnalysisContext { + requirement vehicleFuelEconomyRequirements { + subject vehicle : Vehicle; + // ... + } + + attribute cityScenario : WayPoint[*] = ( //* ... */ ); + attribute highwayScenario : WayPoint[*] = ( //* ... */ ); + + analysis cityAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle_c1; + in scenario = cityScenario; + } + + analysis highwayAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle_c1; + in scenario = highwayScenario; + } + + part vehicle_c1 : Vehicle { + // ... + + attribute :>> fuelEconomy_city = cityAnalysis.fuelEconomyResult; + attribute :>> fuelEconomy_highway = highwayAnalysis.fuelEconomyResult; + } + + satisfy vehicleFuelEconomyRequirements by vehicle_c1; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/33. Analysis/Trade Study Analysis Example.sysml b/test-data/sysml2/official/sysml/training/33. Analysis/Trade Study Analysis Example.sysml new file mode 100644 index 00000000..62c91e74 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/33. Analysis/Trade Study Analysis Example.sysml @@ -0,0 +1,43 @@ +package 'Trade Study Analysis Example' { + private import ScalarValues::Real; + private import TradeStudies::*; + + part def Engine; + part engine4cyl : Engine; + part engine6cyl : Engine; + + calc def PowerRollup { in engine : Engine; return : ISQ::PowerValue; } + calc def MassRollup { in engine : Engine; return : ISQ::MassValue; } + calc def EfficiencyRollup { in engine : Engine; return : Real; } + calc def CostRollup { in engine : Engine; return : Real; } + + calc def EngineEvaluation { + in power : ISQ::PowerValue; + in mass : ISQ::MassValue; + in efficiency : Real; + in cost : Real; + return evaluation : Real; + // Compute evaluation... + } + + analysis engineTradeStudy : TradeStudy { + subject : Engine = (engine4cyl, engine6cyl); + objective : MaximizeObjective; + + calc :>> evaluationFunction { + in part anEngine :>> alternative : Engine; + + calc powerRollup: PowerRollup { in engine = anEngine; return power; } + calc massRollup: MassRollup { in engine = anEngine; return mass; } + calc efficiencyRollup: EfficiencyRollup { in engine = anEngine; return efficiency; } + calc costRollup: CostRollup { in engine = anEngine; return cost; } + + return :>> result : Real = EngineEvaluation( + powerRollup.power, massRollup.mass, efficiencyRollup.efficiency, costRollup.cost + ); + } + + return part :>> selectedAlternative : Engine; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Definition Example.sysml b/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Definition Example.sysml new file mode 100644 index 00000000..105a231a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Definition Example.sysml @@ -0,0 +1,47 @@ +package 'Verification Case Definition Example' { + + part def Vehicle { + attribute mass :> ISQ::mass; + } + + requirement vehicleMassRequirement { + subject vehicle : Vehicle; + in massActual :> ISQ::mass; + doc /* The vehicle mass shall be less than or equal to 2500 kg. */ + + require constraint { + massActual == vehicle.mass and + massActual <= 2500[SI::kg] + } + } + + verification def VehicleMassTest { + private import VerificationCases::*; + + subject testVehicle : Vehicle; + objective vehicleMassVerificationObjective { + // The subject of the verify is automatically bound to 'testVehicle' here. + verify vehicleMassRequirement; + } + + action collectData { + in part testVehicle : Vehicle = VehicleMassTest::testVehicle; + out massMeasured :> ISQ::mass; + } + + action processData { + in massMeasured :> ISQ::mass = collectData.massMeasured; + out massProcessed :> ISQ::mass; + } + + action evaluateData { + in massProcessed :> ISQ::mass = processData.massProcessed; + out verdict : VerdictKind = + // Check that 'testVehicle' statisfies 'vehicleMassRequirement' if its mass equals 'massProcessed'. + PassIf(vehicleMassRequirement(vehicle = testVehicle, massActual = massProcessed)); + } + + return verdict : VerdictKind = evaluateData.verdict; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Usage Example.sysml b/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Usage Example.sysml new file mode 100644 index 00000000..8f439879 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/34. Verification/Verification Case Usage Example.sysml @@ -0,0 +1,52 @@ +package 'Verification Case Usage Example' { + private import 'Verification Case Definition Example'::*; + + part def MassVerificationSystem; + part def Scale; + + part vehicleTestConfig : Vehicle { + // ... + } + + verification vehicleMassTest : VehicleMassTest { + subject testVehicle :> vehicleTestConfig; + } + + part massVerificationSystem : MassVerificationSystem { + perform vehicleMassTest; + + part scale : Scale { + perform vehicleMassTest.collectData { + in part :>> testVehicle; + + // In reality, this would be some more involved process. + measurement = testVehicle.mass; + + out :>> massMeasured = measurement; + } + } + } + + individual def TestSystem :> MassVerificationSystem; + + individual def TestVehicle1 :> Vehicle; + individual def TestVehicle2 :> Vehicle; + + individual testSystem : TestSystem :> massVerificationSystem { + timeslice test1 { + perform action :>> vehicleMassTest { + in individual :>> testVehicle : TestVehicle1 { + :>> mass = 2500[SI::kg]; + } + } + } + + then timeslice test2 { + perform action :>> vehicleMassTest { + in individual :>> testVehicle : TestVehicle2 { + :>> mass = 3000[SI::kg]; + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Definition Example.sysml b/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Definition Example.sysml new file mode 100644 index 00000000..785e6fbb --- /dev/null +++ b/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Definition Example.sysml @@ -0,0 +1,34 @@ +package 'Use Case Definition Example' { + + part def Vehicle; + part def Person; + part def Environment; + part def 'Fuel Station'; + + use case def 'Provide Transportation' { + subject vehicle : Vehicle; + + actor driver : Person; + actor passengers : Person[0..4]; + actor environment : Environment; + + objective { + doc + /* Transport driver and passengers from starting location + * to ending location. + */ + } + } + + use case def 'Enter Vehicle' { + subject vehicle : Vehicle; + actor driver : Person; + actor passengers : Person[0..4]; + } + + use case def 'Exit Vehicle' { + subject vehicle : Vehicle; + actor driver : Person; + actor passengers : Person[0..4]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Usage Example.sysml b/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Usage Example.sysml new file mode 100644 index 00000000..19b07dd7 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/35. Use Cases/Use Case Usage Example.sysml @@ -0,0 +1,43 @@ +package 'Use Case Usage Example' { + + private import 'Use Case Definition Example'::*; + + part def 'Fuel Station'; + + use case 'provide transportation' : 'Provide Transportation' { + subject vehicle; + + first start; + + then include use case 'enter vehicle' : 'Enter Vehicle' { + subject vehicle; + actor driver = 'provide transportation'::driver; + actor passengers = 'provide transportation'::passengers; + } + + then use case 'drive vehicle' { + subject vehicle; + actor driver = 'provide transportation'::driver; + actor environment = 'provide transportation'::environment; + + include 'add fuel'[0..*] { + subject vehicle; + actor fueler = driver; + } + } + + then include use case 'exit vehicle' : 'Exit Vehicle' { + subject vehicle; + actor driver = 'provide transportation'::driver; + actor passengers = 'provide transportation'::passengers; + } + + then done; + } + + use case 'add fuel' { + subject vehicle : Vehicle; + actor fueler : Person; + actor 'fuel station' : 'Fuel Station'; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/36. Variability/Variation Configuration.sysml b/test-data/sysml2/official/sysml/training/36. Variability/Variation Configuration.sysml new file mode 100644 index 00000000..34e688f8 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/36. Variability/Variation Configuration.sysml @@ -0,0 +1,14 @@ +package 'Variation Configuration' { + private import 'Variation Usages'::*; + + part vehicle4Cyl :> vehicleFamily { + part redefines engine = engine::'4cylEngine'; + part redefines transmission = transmission::manualTransmission; + } + + part vehicle6Cyl :> vehicleFamily { + part redefines engine = engine::'6cylEngine'; + part redefines transmission = transmission::manualTransmission; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/36. Variability/Variation Definitions.sysml b/test-data/sysml2/official/sysml/training/36. Variability/Variation Definitions.sysml new file mode 100644 index 00000000..6cfed57e --- /dev/null +++ b/test-data/sysml2/official/sysml/training/36. Variability/Variation Definitions.sysml @@ -0,0 +1,35 @@ +package 'Variation Definitions' { + private import ScalarValues::Real; + private import SI::mm; + + attribute def Diameter :> ISQ::LengthValue; + + part def Cylinder { + attribute diameter : Diameter[1]; + } + + part def Engine { + part cylinder : Cylinder[2..*]; + } + + part '4cylEngine' : Engine { + part redefines cylinder[4]; + } + + part '6cylEngine' : Engine { + part redefines cylinder[6]; + } + + // Variability model + + variation attribute def DiameterChoices :> Diameter { + variant attribute diameterSmall = 70[mm]; + variant attribute diameterLarge = 100[mm]; + } + + variation part def EngineChoices :> Engine { + variant '4cylEngine'; + variant '6cylEngine'; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/36. Variability/Variation Usages.sysml b/test-data/sysml2/official/sysml/training/36. Variability/Variation Usages.sysml new file mode 100644 index 00000000..96b42274 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/36. Variability/Variation Usages.sysml @@ -0,0 +1,25 @@ +package 'Variation Usages' { + private import 'Variation Definitions'::*; + + part def Vehicle; + part def Transmission; + part manualTransmission; + part automaticTransmission; + + abstract part vehicleFamily : Vehicle { + part engine : EngineChoices[1]; + + variation part transmission : Transmission[1] { + variant manualTransmission; + variant automaticTransmission; + } + + assert constraint { + (engine == engine::'4cylEngine' and + transmission == transmission::manualTransmission) xor + (engine == engine::'6cylEngine' and + transmission == transmission::automaticTransmission) + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/37. Dependencies/Dependency Example.sysml b/test-data/sysml2/official/sysml/training/37. Dependencies/Dependency Example.sysml new file mode 100644 index 00000000..32a93d1a --- /dev/null +++ b/test-data/sysml2/official/sysml/training/37. Dependencies/Dependency Example.sysml @@ -0,0 +1,27 @@ +package 'Dependency Example' { + + part 'System Assembly' { + part 'Computer Subsystem' { + // ... + } + + part 'Storage Subsystem' { + // ... + } + } + + package 'Software Design' { + item def MessageSchema { + // ... + } + item def DataSchema { + // ... + } + } + + dependency from 'System Assembly'::'Computer Subsystem' to 'Software Design'; + + dependency Schemata + from 'System Assembly'::'Storage Subsystem' + to 'Software Design'::MessageSchema, 'Software Design'::DataSchema; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Definition Example.sysml b/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Definition Example.sysml new file mode 100644 index 00000000..b10344f5 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Definition Example.sysml @@ -0,0 +1,38 @@ +package 'Allocation Definition Example' { + package LogicalModel { + action def ProvidePower; + action def GenerateTorque; + + part def LogicalElement; + part def TorqueGenerator :> LogicalElement; + + action providePower : ProvidePower { + action generateTorque : GenerateTorque; + } + + part torqueGenerator : TorqueGenerator { + perform providePower.generateTorque; + } + + } + + package PhysicalModel { + private import LogicalModel::*; + + part def PhysicalElement; + part def PowerTrain :> PhysicalElement; + + part powerTrain : PowerTrain { + part engine { + perform providePower.generateTorque; + } + } + + allocation def LogicalToPhysical { + end logical : LogicalElement; + end physical : PhysicalElement; + } + + allocation torqueGenAlloc : LogicalToPhysical allocate torqueGenerator to powerTrain; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Usage Example.sysml b/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Usage Example.sysml new file mode 100644 index 00000000..4f44d44c --- /dev/null +++ b/test-data/sysml2/official/sysml/training/38. Allocation/Allocation Usage Example.sysml @@ -0,0 +1,34 @@ +package 'Allocation Usage Example' { + package LogicalModel { + action def ProvidePower; + action def GenerateTorque; + + part def TorqueGenerator; + + action providePower : ProvidePower { + action generateTorque : GenerateTorque; + } + + part torqueGenerator : TorqueGenerator { + perform providePower.generateTorque; + } + } + + package PhysicalModel { + private import LogicalModel::*; + + part def PowerTrain; + part def Engine; + + part powerTrain : PowerTrain { + part engine : Engine { + perform providePower.generateTorque; + } + } + + allocate torqueGenerator to powerTrain { + allocate torqueGenerator.generateTorque to powerTrain.engine.generateTorque; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-1.sysml b/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-1.sysml new file mode 100644 index 00000000..f89f23bd --- /dev/null +++ b/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-1.sysml @@ -0,0 +1,32 @@ +package 'Metadata Example-1' { + + metadata def SafetyFeature; + metadata def SecurityFeature { + :> annotatedElement : SysML::PartDefinition; + :> annotatedElement : SysML::PartUsage; + } + + metadata SafetyFeature about + vehicle::interior::seatBelt, + vehicle::interior::driverAirBag, + vehicle::bodyAssy::bumper; + + metadata SecurityFeature about + vehicle::interior::alarm, + vehicle::bodyAssy::keylessEntry; + + part vehicle { + part interior { + part alarm; + part seatBelt[2]; + part frontSeat[2]; + part driverAirBag; + } + part bodyAssy { + part body; + part bumper; + part keylessEntry; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-2.sysml b/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-2.sysml new file mode 100644 index 00000000..842acb3f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/39. Metadata/Metadata Example-2.sysml @@ -0,0 +1,20 @@ +package 'Metadata Example-2' { + + action computeDynamics { + private import AnalysisTooling::*; + + metadata ToolExecution { + toolName = "ModelCenter"; + uri = "aserv://localhost/Vehicle/Equation1"; + } + + in dt : ISQ::TimeValue { @ToolVariable { name = "deltaT"; } } + in a : ISQ::AccelerationValue { @ToolVariable { name = "mass"; } } + in v_in : ISQ::SpeedValue { @ToolVariable { name = "v0"; } } + in x_in : ISQ::LengthValue { @ToolVariable { name = "x0"; } } + + out v_out : ISQ::SpeedValue { @ToolVariable { name = "v"; } } + out x_out : ISQ::LengthValue { @ToolVariable { name = "x"; } } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-1.sysml b/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-1.sysml new file mode 100644 index 00000000..34b1f36f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-1.sysml @@ -0,0 +1,37 @@ +package 'Filtering Example-1' { + private import ScalarValues::Boolean; + + metadata def Safety { + attribute isMandatory : Boolean; + } + + part vehicle { + part interior { + part alarm; + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + part bodyAssy { + part body; + part bumper {@Safety{isMandatory = true;}} + part keylessEntry; + } + part wheelAssy { + part wheel[2]; + part antilockBrakes[2] {@Safety{isMandatory = false;}} + } + } + + package 'Safety Features' { + /* Parts that contribute to safety. */ + public import vehicle::**; + filter @Safety; + } + + package 'Mandatory Safety Features' { + /* Parts that contribute to safety AND are mandatory. */ + public import vehicle::**; + filter @Safety and (as Safety).isMandatory; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-2.sysml b/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-2.sysml new file mode 100644 index 00000000..08f2d8d5 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/40. Filtering/Filtering Example-2.sysml @@ -0,0 +1,35 @@ +package 'Filtering Example-2' { + private import ScalarValues::Boolean; + + metadata def Safety { + attribute isMandatory : Boolean; + } + + part vehicle { + part interior { + part alarm; + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + part bodyAssy { + part body; + part bumper {@Safety{isMandatory = true;}} + part keylessEntry; + } + part wheelAssy { + part wheel[2]; + part antilockBrakes[2] {@Safety{isMandatory = false;}} + } + } + + package 'Safety Features' { + /* Parts that contribute to safety. */ + public import vehicle::**[@Safety]; + } + + package 'Mandatory Safety Features' { + /* Parts that contribute to safety AND are mandatory. */ + public import vehicle::**[@Safety and (as Safety).isMandatory]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/41. Language Extension/Model Library Example.sysml b/test-data/sysml2/official/sysml/training/41. Language Extension/Model Library Example.sysml new file mode 100644 index 00000000..1c7e841f --- /dev/null +++ b/test-data/sysml2/official/sysml/training/41. Language Extension/Model Library Example.sysml @@ -0,0 +1,35 @@ +library package 'Model Library Example' { + private import ScalarValues::Real; + private import RiskMetadata::Level; + + abstract occurrence def Situation; + + abstract occurrence situations : Situation[*] nonunique; + + abstract occurrence def Cause { + attribute probability : Real; + } + + abstract occurrence causes : Cause[*] nonunique :> situations; + + abstract occurrence def Failure { + attribute severity : Level; + } + + abstract occurrence failures : Failure[*] nonunique :> situations; + + abstract connection def Causation :> Occurrences::HappensBefore { + end [*] ref cause : Situation; + end [*] ref effect : Situation; + } + + abstract connection causations : Causation[*] nonunique; + + item def Scenario { + occurrence :>> situations; + occurrence :>> causes :> situations; + occurrence :>> failures :> situations; + } + + item scenarios : Scenario[*] nonunique; +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/41. Language Extension/Semantic Metadata Example.sysml b/test-data/sysml2/official/sysml/training/41. Language Extension/Semantic Metadata Example.sysml new file mode 100644 index 00000000..863b7d22 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/41. Language Extension/Semantic Metadata Example.sysml @@ -0,0 +1,25 @@ +library package 'Semantic Metadata Example' { + private import 'Model Library Example'::*; + private import Metaobjects::SemanticMetadata; + + metadata def situation :> SemanticMetadata { + :>> baseType = situations meta SysML::Usage; + } + + metadata def cause :> SemanticMetadata { + :>> baseType = causes meta SysML::Usage; + } + + metadata def failure :> SemanticMetadata { + :>> baseType = failures meta SysML::Usage; + } + + metadata def causation :> SemanticMetadata { + :>> baseType = causations meta SysML::Usage; + } + + metadata def scenario :> SemanticMetadata { + :>> baseType = scenarios meta SysML::Usage; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/41. Language Extension/User Keyword Example.sysml b/test-data/sysml2/official/sysml/training/41. Language Extension/User Keyword Example.sysml new file mode 100644 index 00000000..b9f0af9d --- /dev/null +++ b/test-data/sysml2/official/sysml/training/41. Language Extension/User Keyword Example.sysml @@ -0,0 +1,32 @@ +package 'User Keyword Example' { + private import ScalarValues::Real; + private import 'Semantic Metadata Example'::*; + private import RiskMetadata::LevelEnum; + + part def Device { + part battery { + attribute power : Real; + } + } + + #scenario def DeviceFailure { + ref device : Device; + attribute minPower : Real; + + #cause 'battery old' { + :>> probability = 0.01; + } + + #causation connect 'battery old' to 'power low'; + + #situation 'power low' { + constraint { device.battery.power < minPower } + } + + #causation connect 'power low' to 'device shutoff'; + + #failure 'device shutoff' { + :>> severity = LevelEnum::high; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/42. Views/Viewpoint Example.sysml b/test-data/sysml2/official/sysml/training/42. Views/Viewpoint Example.sysml new file mode 100644 index 00000000..b1091082 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/42. Views/Viewpoint Example.sysml @@ -0,0 +1,38 @@ +package 'Viewpoint Example' { + part def 'Systems Engineer'; + part def 'IV&V'; + + concern 'system breakdown' { + doc /* + * To ensure that a system covers all its required capabilities, + * it is necessary to understand how it is broken down into + * subsystems and components that provide those capabilities. + */ + subject; + stakeholder se : 'Systems Engineer'; + stakeholder ivv : 'IV&V'; + } + + concern 'modularity' { + doc /* + * There should be well defined interfaces between the parts of + * a system that allow each part to be understood individually, + * as well as being part of the whole system. + */ + subject; + stakeholder se : 'Systems Engineer'; + } + + viewpoint 'system structure perspective' { + frame 'system breakdown'; + frame 'modularity'; + + require constraint { + doc /* + * A system structure view shall show the hierarchical + * part decomposition of a system, starting with a + * specified root part. + */ + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/training/42. Views/Views Example.sysml b/test-data/sysml2/official/sysml/training/42. Views/Views Example.sysml new file mode 100644 index 00000000..c13cb1d7 --- /dev/null +++ b/test-data/sysml2/official/sysml/training/42. Views/Views Example.sysml @@ -0,0 +1,35 @@ +package 'Views Example' { + private import Views::*; + private import 'Viewpoint Example'::*; + private import 'Filtering Example-2'::*; + + view def 'Part Structure View' { + satisfy 'system structure perspective'; + filter @SysML::PartUsage; + } + + view 'vehicle structure view' : 'Part Structure View' { + expose vehicle::**; + render asTreeDiagram; + } + + rendering asTextualNotationTable :> asElementTable { + view :>> columnView[1] { + render asTextualNotation; + } + } + + view 'vehicle tabular views' { + + view 'safety features view' : 'Part Structure View' { + expose vehicle::**[@Safety]; + render asTextualNotationTable; + } + + view 'non-safety features view' : 'Part Structure View' { + expose vehicle::**[not (@Safety)]; + render asTextualNotationTable; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/01-Parts Tree/1a-Parts Tree.sysml b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1a-Parts Tree.sysml new file mode 100644 index 00000000..dd5bd686 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1a-Parts Tree.sysml @@ -0,0 +1,125 @@ +package '1a-Parts Tree' { + private import SI::kg; + + package Definitions { + part def Vehicle { + attribute mass :> ISQ::mass { + doc + /* + * The 'mass' attribute property is declared here to be a + * specialization (subset) of the general 'mass' quantity + * from the 'ISQ' (International System of Quantities) + * library model. + */ + } + } + part def AxleAssembly; + part def Axle { + attribute mass :> ISQ::mass; + } + part def FrontAxle :> Axle { + attribute steeringAngle: ScalarValues::Real; + } + part def Wheel; + } + + package Usages { + private import Definitions::* { + /* + * A "private" private import makes the imported names private to the + * imported package. + */ + } + + part vehicle1: Vehicle { + /* + * 'vehicle1' is a package-owned part of type Vehicle. + */ + + attribute mass redefines Vehicle::mass = 1750 [kg] { + /* + * This redefines the 'mass' attribute property from 'Vehicle' to + * give it a fixed attribute. + */ + } + + part frontAxleAssembly: AxleAssembly { + /* + * 'frontAxleAssembly' is a nested part of part 'vehicle1'. + * It is a composite part of the containing part. + * + * (And similarly for 'rearAxleAssembly'.) + */ + + part frontAxle: Axle; + + part frontWheel: Wheel[2] ordered { + /* + * 'frontWheel' is a nested part of type 'Wheel' with + * multiplicity "2". This means that this axle assembly + * must have exactly two wheels. However, there is still + * only one 'frontWheel' part. The part is "ordered", + * so that the first wheel can be distinguished from the + * second. + */ + } + } + + part rearAxleAssembly: AxleAssembly { + part rearAxle: Axle; + part rearWheel: Wheel[2] ordered; + } + + } + + part vehicle1_c1: Vehicle { + /* + * 'vehicle1_c1' is a modified copy of 'vehicle1'. There is no + * connection between this copy and the original version in the + * model. + */ + + attribute mass redefines Vehicle::mass = 2000 [kg] { + /* + * The mass attribute has been modified. + */ + } + + part frontAxleAssembly: AxleAssembly { + + part frontAxle: FrontAxle { + /* + * The part 'frontAxle' has been modified to have type 'FrontAxle'. + */ + } + + part frontWheel: Wheel[2] ordered { + /* + * The parts 'frontWheel_1' and 'frontWheel_2' have been added + * as subsets of 'frontWheel'. These are separate parts from + * 'frontWheel', but essentially provide alternate names for + * each of the two wheels, as given by their defining expressions. + */ + } + part frontWheel_1 subsets frontWheel = frontWheel#(1); + part frontWheel_2 subsets frontWheel = frontWheel#(2); + } + + part rearAxleAssembly: AxleAssembly { + /* + * 'rearAxleAssembly' has also been modified to add subsetting parts + * for 'rearWheel'. + */ + + part rearAxle: Axle; + + part rearWheel: Wheel[2] ordered; + part rearWheel_1 subsets rearWheel = rearWheel#(1); + part rearWheel_2 subsets rearWheel = rearWheel#(2); + } + + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/01-Parts Tree/1c-Parts Tree Redefinition.sysml b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1c-Parts Tree Redefinition.sysml new file mode 100644 index 00000000..c9c35f72 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1c-Parts Tree Redefinition.sysml @@ -0,0 +1,86 @@ +package '1c-Parts Tree Redefinition' { + private import SI::kg; + + package Definitions { + part def Vehicle { + attribute mass :> ISQ::mass; + } + part def AxleAssembly; + part def Axle { + attribute mass :> ISQ::mass; + } + part def FrontAxle :> Axle { + attribute steeringAngle: ScalarValues::Real; + } + part def Wheel; + } + + package Usages { + private import Definitions::*; + + part vehicle1: Vehicle { + attribute mass redefines Vehicle::mass default = 1750 [kg] { + doc + /* + * The mass attribute is redefined to give it a default value. + */ + } + + part frontAxleAssembly: AxleAssembly { + part frontAxle: Axle; + part frontWheel: Wheel[2] ordered; + } + part rearAxleAssembly: AxleAssembly { + part rearAxle: Axle; + part rearWheel: Wheel[2] ordered; + } + } + + part vehicle1_c1 :> vehicle1 { + /* + * 'vehicle1_c1' is a specialization of 'vehicle1' (technically + * a subset). It inherits all the parts of 'vehicle1' and + * only needs to specify additional or redefined parts. + */ + + attribute mass redefines vehicle1::mass = 2000 [kg] { + /* + * The mass is further redefined to override the default value + * with a bound value for 'vehicle_c1'. + */ + } + + part frontAxleAssembly_c1 redefines frontAxleAssembly { + part frontAxle_c1: FrontAxle redefines frontAxle { + /* + * 'frontAxle_c1' redefines 'frontAxleAssembly'::'frontAxle' + * to give it a new name and the specialized type + * 'FrontAxle'. + */ + } + + /* + * 'frontWheel' is inherited from 'vehicle1'::'frontAxleAssembly', + * allowing it to be used in the following part declarations. + */ + + part frontWheel_1 subsets frontWheel = frontWheel#(1); + part frontWheel_2 subsets frontWheel = frontWheel#(2); + } + + part rearAxleAssembly_c1 redefines rearAxleAssembly { + part rearAxle_c1 redefines rearAxle { + /* + * 'rearAxle_c1' redefines 'rearAxleAssembly'::'rearAxle' + * to give it a new name. It inherits the type 'Axle' + * from the redefined part. + */ + } + + part rearWheel_1 subsets rearWheel = rearWheel#(1); + part rearWheel_2 subsets rearWheel = rearWheel#(2); + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/01-Parts Tree/1d-Parts Tree with Reference.sysml b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1d-Parts Tree with Reference.sysml new file mode 100644 index 00000000..8eca0e37 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/01-Parts Tree/1d-Parts Tree with Reference.sysml @@ -0,0 +1,51 @@ +package '1d-Parts Tree with Reference' { + + package Definitions { + part def Vehicle; + part def Trailer; + part def TrailerHitch; + part def HitchBall; + part def TrailerCoupler; + } + + package Usages { + private import Definitions::*; + + part vehicle_trailer_system { + + part vehicle1_c1: Vehicle { + ref hitchBall : HitchBall { + /* + * 'vehicle1_c1'::'hitchBall' is a reference property that + * references a hitch ball that is not part of this vehicle. + * If 'vehicle1_c1' is removed or destroyed, this does not + * effect the hitchBall referenced here. + */ + } + } + + bind vehicle1_c1.hitchBall = trailerHitch.hitchBall { + /* + * This is a binding connector between the 'hitchBall' in 'vehicle1_c1' + * and the 'hitchBall' in 'trailerHitch'. + */ + } + + part trailerHitch: TrailerHitch { + part hitchBall: HitchBall; + part trailerCoupler: TrailerCoupler; + } + + part trailer1: Trailer { + ref trailerCoupler : TrailerCoupler = trailerHitch.trailerCoupler { + /* + * This is a shorthand for a binding connector between the + * 'trailerCoupler' here and the 'trailerCoupler' in 'trailerHitch'. + * The binding connector is now contained within the 'trailer1' + * part, though, rather than being at the system level. + */ + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2a-Parts Interconnection.sysml b/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2a-Parts Interconnection.sysml new file mode 100644 index 00000000..57538dc9 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2a-Parts Interconnection.sysml @@ -0,0 +1,206 @@ +package '2a-Parts Interconnection' { + public import Definitions::*; + public import Usages::*; + + package Definitions { + // Port Definitions + + port def FuelCmdPort; + + port def DrivePwrPort; + port def ClutchPort; + + port def ShaftPort_a; + port def ShaftPort_b; + port def ShaftPort_c; + port def ShaftPort_d; + + port def DiffPort; + port def AxlePort; + port def AxleToWheelPort; + port def WheelToAxlePort; + port def WheelToRoadPort; + + port def VehicleToRoadPort { + /* + * A port definition can have nested ports. + */ + + port wheelToRoadPort: WheelToRoadPort[2]; + } + + // Blocks + + part def VehicleA { + port fuelCmdPort: FuelCmdPort; + port vehicleToRoadPort: VehicleToRoadPort; + } + + part def AxleAssembly; + part def RearAxleAssembly :> AxleAssembly { + port shaftPort_d: ShaftPort_d; + } + + part def Axle; + part def RearAxle :> Axle; + + part def HalfAxle { + port axleToDiffPort: AxlePort; + port axleToWheelPort: AxleToWheelPort; + } + + part def Engine { + port fuelCmdPort: FuelCmdPort; + port drivePwrPort: DrivePwrPort; + } + + part def Transmission { + port clutchPort: ClutchPort; + port shaftPort_a: ShaftPort_a; + } + + part def Driveshaft { + port shaftPort_b: ShaftPort_b; + port shaftPort_c: ShaftPort_c; + } + + part def Differential { + /* + * Ports do not have to be defined on part defs. + * They can be added directly to their usages. + */ + } + part def Wheel; + + // Interface Definitions + + interface def EngineToTransmissionInterface { + /* + * The ends of an interface definition are always ports. + */ + + end drivePwrPort: DrivePwrPort; + end clutchPort: ClutchPort; + } + + interface def DriveshaftInterface { + end shaftPort_a: ShaftPort_a; + end shaftPort_d: ShaftPort_d; + + ref driveshaft: Driveshaft { + /* + * 'driveshaft' is a reference to the driveshaft that will + * act as the "interface medium" for this interface. + */ + } + + connect shaftPort_a to driveshaft.shaftPort_b { + /* + * The two ends of 'DriveShaftInterface' are always connected + * via the referenced 'driveshaft'. + */ + } + connect driveshaft.shaftPort_c to shaftPort_d; + } + + } + + package Usages { + + part vehicle1_c1: VehicleA { + + bind fuelCmdPort = engine.fuelCmdPort; + + part engine: Engine; + + interface :EngineToTransmissionInterface + connect engine.drivePwrPort to transmission.clutchPort { + /* + * A usage of an interface definition connects two ports relative to + * a containing context. + */ + } + + part transmission: Transmission; + + part driveshaft: Driveshaft { + /* + * This 'driveshaft' is the part of 'vehicle1_c1' that will act as the + * interface medium in the following 'DriveshaftInterface' usage. + */ + } + + interface :DriveshaftInterface + connect transmission.shaftPort_a to rearAxleAssembly.shaftPort_d { + ref :>> driveshaft = vehicle1_c1.driveshaft { + /* + * The reference property from 'DriveshaftInterface' is redefined + * in order to bind it to the appropriate part of 'vehicle1_c1'. + */ + } + } + + part rearAxleAssembly: RearAxleAssembly { + bind shaftPort_d = differential.shaftPort_d; + + part differential: Differential { + port shaftPort_d: ShaftPort_d { + /* + * If the part def has no ports, then they can be defined directly in + * a usage of the part def. + */ + } + port leftDiffPort: DiffPort; + port rightDiffPort: DiffPort; + } + + interface differential.leftDiffPort to rearAxle.leftHalfAxle.axleToDiffPort { + /* + * A connection can be to a port that is arbitrarily deeply nested, on either end. + */ + } + interface differential.rightDiffPort to rearAxle.rightHalfAxle.axleToDiffPort; + + part rearAxle: RearAxle { + part leftHalfAxle: HalfAxle; + part rightHalfAxle: HalfAxle; + } + + connect rearAxle.leftHalfAxle.axleToWheelPort to leftWheel.wheelToAxlePort; + connect rearAxle.rightHalfAxle.axleToWheelPort to rightWheel.wheelToAxlePort; + + part rearWheel: Wheel[2] ordered; + + /* The two rear wheels of 'rearAxleAssembly' must be given + * their own names in order to be referenced in connections. + * + * (":>" is a shorthand here for "subsets".) + */ + part leftWheel :> rearWheel = rearWheel#(1) { + port wheelToAxlePort: WheelToAxlePort; + port wheelToRoadPort: WheelToRoadPort; + } + + part rightWheel :> rearWheel = rearWheel#(2) { + port wheelToAxlePort: WheelToAxlePort; + port wheelToRoadPort: WheelToRoadPort; + } + + } + + bind rearAxleAssembly.leftWheel.wheelToRoadPort = + vehicleToRoadPort.leftWheelToRoadPort; + + bind rearAxleAssembly.rightWheel.wheelToRoadPort = + vehicleToRoadPort.rightWheelToRoadPort; + + port vehicleToRoadPort redefines VehicleA::vehicleToRoadPort { + port leftWheelToRoadPort :> wheelToRoadPort = wheelToRoadPort#(1); + port rightWheelToRoadPort :> wheelToRoadPort = wheelToRoadPort#(2); + } + + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2c-Parts Interconnection-Multiple Decompositions.sysml b/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2c-Parts Interconnection-Multiple Decompositions.sysml new file mode 100644 index 00000000..0df216e1 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/02-Parts Interconnection/2c-Parts Interconnection-Multiple Decompositions.sysml @@ -0,0 +1,90 @@ +package '2c-Parts Interconnection-Multiple Decompositions' { + + part def A1; + + part def B11 { + port pe; + } + part def B12 { + port pf; + } + part def B21 { + port pg; + } + part def B22 { + port ph; + } + + part def C1 { + port pa; + port pb; + } + part def C2 { + port pc; + } + part def C3 { + port pd; + } + part def C4; + + part a11: A1 { + doc + /* + * Decomposition 1 - Subsystems b11, b12 + */ + + part b11: B11 { + part c1: C1; + part c2: C2; + + connect c1.pa to c2.pc; + + port :>> pe = c1.pb { + doc + /* + * This combines the definition of a port with a binding + * connector. (It is the same notation used to bind a + * attribute to a attribute property or a reference to a reference + * property.) + */ + } + } + + part b12: B12 { + part c3: C3; + part c4: C4; + + port :>> pf = c3.pd; + } + + connect b11.pe to b12.pf; + } + + part a12: A1 { + doc + /* + * Decomposition 2 - Assemblies b21, b22 + */ + + part b21: B21 { + /* + * The c-level entities are already composite parts within + * a11, so they cannot also be composite parts within a12. + */ + + ref c1: C1 = a11.b11.c1; + ref c3: C3 = a11.b12.c3; + + connect c1.pb to c3.pd; + + port :>> pg = c1.pa; + } + + part b22: B22 { + ref c2: C2 = a11.b11.c2; + ref c4: C4 = a11.b12.c4; + + port :>> ph = c2.pc; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-1.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-1.sysml new file mode 100644 index 00000000..093218f3 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-1.sysml @@ -0,0 +1,137 @@ +package '3a-Function-based Behavior-1' { + public import Definitions::*; + public import Usages::*; + + package Definitions { + alias Torque for ISQ::TorqueValue { + /* + * The 'TorqueValue' type is aliased as 'Torque'. + */ + } + + attribute def FuelCmd; + + /* + * There is no special construct for modeling "signals". Data to be + * transmitted asynchronously can simply be modeled using attribute defs. + */ + + attribute def EngineStart; + attribute def EngineOff; + + /* + * Black box definitions for actions include their inputs and outputs. + */ + + action def 'Generate Torque' { in fuelCmd: FuelCmd; out engineTorque: Torque; } + action def 'Amplify Torque' { in engineTorque: Torque; out transmissionTorque: Torque; } + action def 'Transfer Torque' { in transmissionTorque: Torque; out driveshaftTorque: Torque; } + action def 'Distribute Torque' { in driveShaftTorque: Torque; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + action def 'Provide Power' { in fuelCmd: FuelCmd; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + } + + package Usages { + + action 'provide power': 'Provide Power'{ + in fuelCmd: FuelCmd; + out wheelTorque1: Torque; + out wheelTorque2: Torque; + + // ITEM FLOW PART + + bind 'generate torque'.fuelCmd = fuelCmd { + /* + * This is a binding connector, just as was used to + * model delegation between ports. + */ + } + + action 'generate torque': 'Generate Torque' { + /* + * An action usage inherits parameters from its definition. + * They act as its "pins". + */ + } + + flow 'generate torque'.engineTorque + to 'amplify torque'.engineTorque { + /* + * A flow is a connection between two actions that streams items from + * an output parameter of one action to an input parameter of the other. + * Note that streaming is a property of the connection, not the + * actions or their parameters. + */ + } + + action 'amplify torque': 'Amplify Torque'; + + flow 'amplify torque'.transmissionTorque + to 'transfer torque'.transmissionTorque; + + action 'transfer torque': 'Transfer Torque'; + + flow 'transfer torque'.driveshaftTorque + to 'distribute torque'.driveShaftTorque; + + action 'distribute torque': 'Distribute Torque'; + + bind wheelTorque1 = 'distribute torque'.wheelTorque1; + bind wheelTorque2 = 'distribute torque'.wheelTorque2; + + // CONTROL FLOW PART + + first start then continue { + /* + * A first is an assertion that one thing must occur + * before another, acting like a "control flow". 'start' is + * the start snapshot of the action, which acts like an + * "initial node". + */ + } + + merge continue { + /* + * A merge node is necessary to prevent a loop of successions + * from being unsatisfiable. + */ + } + first continue then engineStarted; + + action engineStarted accept engineStart: EngineStart { + /* + * An accept action accepts an incoming transfer of some item + * from outside an action, in this case the "signal" 'EngineStart'. + * Note that 'engineStarted' is the name of the action, while + * 'engineStart' is the name of the received signal attribute. + */ + } + first engineStarted then engineStopped; + + action engineStopped accept engineOff: EngineOff; + first engineStopped then continue; + + /* + * These successions act to "enable" the torque-related actions. + * Each action on the right can only be performed following the + * completion of a performance of 'engineStarted'. + */ + first engineStarted then 'generate torque'; + first engineStarted then 'amplify torque'; + first engineStarted then 'transfer torque'; + first engineStarted then 'distribute torque'; + + /* + * These successions act to "disable" the torque-related actions. + * The performance of the actions on the left cannot continue + * once there is a performance of 'engineStopped'. + */ + first 'generate torque' then engineStopped; + first 'amplify torque' then engineStopped; + first 'transfer torque' then engineStopped; + first 'distribute torque' then engineStopped; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-2.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-2.sysml new file mode 100644 index 00000000..2d56d905 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-2.sysml @@ -0,0 +1,85 @@ +package '3a-Function-based Behavior-2' { + public import Definitions::*; + public import Usages::*; + + package Definitions { + alias Torque for ISQ::TorqueValue; + + // ATTRIBUTE DEFINITIONS + + attribute def FuelCmd; + + attribute def EngineStart; + attribute def EngineOff; + + // ACTION DEFINITIONS + + action def 'Generate Torque' { in fuelCmd: FuelCmd; out engineTorque: Torque; } + action def 'Amplify Torque' { in engineTorque: Torque; out transmissionTorque: Torque; } + action def 'Transfer Torque' { in transmissionTorque: Torque; out driveshaftTorque: Torque; } + action def 'Distribute Torque' { in driveShaftTorque: Torque; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + action def 'Provide Power' { in fuelCmd: FuelCmd; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + } + + package Usages { + + action 'provide power': 'Provide Power'{ + in fuelCmd: FuelCmd; + out wheelTorque1: Torque; + out wheelTorque2: Torque; + + // ITEM FLOW PART + + action 'generate torque': 'Generate Torque'{ + /* + * The binding connector shorthand can be used on action parameters. + */ + in fuelCmd = 'provide power'::fuelCmd; + } + + flow 'generate torque'.engineTorque + to 'amplify torque'.engineTorque; + + action 'amplify torque': 'Amplify Torque'; + + flow 'amplify torque'.transmissionTorque + to 'transfer torque'.transmissionTorque; + + action 'transfer torque': 'Transfer Torque'; + + flow 'transfer torque'.driveshaftTorque + to 'distribute torque'.driveShaftTorque; + + action 'distribute torque': 'Distribute Torque'; + + // CONTROL FLOW PART + + /* + * The following uses a shorthand for a sequence of successions. + * The source of the first first is given by "first start", + * and the target of each succeeding first is indicated by + * using the "then" keyword. + */ + first start; + then merge continue; + then action engineStarted accept engineStart: EngineStart; + then action engineStopped accept engineOff: EngineOff; + then continue; + + /* Enable torque generation. */ + first engineStarted then 'generate torque'; + first engineStarted then 'amplify torque'; + first engineStarted then 'transfer torque'; + first engineStarted then 'distribute torque'; + + /* Disable torque generation. */ + first 'generate torque' then engineStopped; + first 'amplify torque' then engineStopped; + first 'transfer torque' then engineStopped; + first 'distribute torque' then engineStopped; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-3.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-3.sysml new file mode 100644 index 00000000..6727e929 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3a-Function-based Behavior-3.sysml @@ -0,0 +1,73 @@ +package '3a-Function-based Behavior-5' { + public import Definitions::*; + public import Usages::*; + + package Definitions { + alias Torque for ISQ::TorqueValue; + + // ATTRIBUTE DEFINITIONS + + attribute def FuelCmd; + + attribute def EngineStart; + attribute def EngineOff; + + // ACTION DEFINITIONS + + action def 'Generate Torque' { in fuelCmd: FuelCmd; out engineTorque: Torque; } + action def 'Amplify Torque' { in engineTorque: Torque; out transmissionTorque: Torque; } + action def 'Transfer Torque' { in transmissionTorque: Torque; out driveshaftTorque: Torque; } + action def 'Distribute Torque' { in driveShaftTorque: Torque; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + action def 'Provide Power' { in fuelCmd: FuelCmd; out wheelTorque1: Torque; out wheelTorque2: Torque; } + + } + + package Usages { + + action 'provide power': 'Provide Power' { + // PARAMETERS + + in fuelCmd: FuelCmd; + out wheelTorque1: Torque; + out wheelTorque2: Torque; + + loop { + accept engineStart : EngineStart; + then action { + action 'generate torque': 'Generate Torque' { + in fuelCmd = 'provide power'::fuelCmd; + out engineTorque: Torque; + } + + flow 'generate torque'.engineTorque + to 'amplify torque'.engineTorque; + + action 'amplify torque': 'Amplify Torque' { + in engineTorque: Torque; + out transmissionTorque: Torque; + } + + flow 'amplify torque'.transmissionTorque + to 'transfer torque'.transmissionTorque; + + action 'transfer torque': 'Transfer Torque' { + in transmissionTorque: Torque; + out driveshaftTorque: Torque; + } + + flow 'transfer torque'.driveshaftTorque + to 'distribute torque'.driveshaftTorque; + + action 'distribute torque': 'Distribute Torque' { + in driveshaftTorque: Torque; + out wheelTorque1: Torque; + out wheelTorque2: Torque; + } + } + then action accept engineOff : EngineOff; + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-1.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-1.sysml new file mode 100644 index 00000000..06bce112 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-1.sysml @@ -0,0 +1,51 @@ +package '3c-Function-based Behavior-structure mod-1' { + + part def Vehicle; + part def VehicleFrame; + + part def HitchBall; + part def TrailerCoupler; + + part def Trailer; + part def TrailerFrame; + + connection def TrailerHitch { + end hitch : HitchBall; + end coupler : TrailerCoupler; + } + + part 'vehicle-trailer system' { + + part vehicle : Vehicle { + part vehicleFrame : VehicleFrame { + part hitch : HitchBall; + } + } + + connection trailerHitch : TrailerHitch[0..1] + connect vehicle.vehicleFrame.hitch to trailer.trailerFrame.coupler; + + part trailer : Trailer { + part trailerFrame : TrailerFrame { + part coupler : TrailerCoupler; + } + } + + action { + // Create a link and assign it as the TrailerHitch connection. + // Link participants are determined from inherited ends. + action 'connect trailer to vehicle' + assign 'vehicle-trailer system'.trailerHitch := new TrailerHitch(); + + // Destroy the link object. + then action 'destroy connection of trailer to vehicle' : + OccurrenceFunctions::destroy { + inout occ = 'vehicle-trailer system'.trailerHitch; + } + + // Remove the link from the TrailerHitch connection. + then action 'disconnect trailer from vehicle' + assign 'vehicle-trailer system'.trailerHitch := null; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-2.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-2.sysml new file mode 100644 index 00000000..f84b7ad4 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-2.sysml @@ -0,0 +1,49 @@ +package '3c-Function-based Behavior-structure mod-2' { + + part def Vehicle; + part def VehicleFrame; + + part def HitchBall; + part def TrailerCoupler; + + part def Trailer; + part def TrailerFrame; + + connection def TrailerHitch { + end hitch : HitchBall; + end coupler : TrailerCoupler; + } + + part 'vehicle-trailer system' { + + part vehicle : Vehicle { + part vehicleFrame : VehicleFrame { + part hitch : HitchBall; + } + } + + connection trailerHitch : TrailerHitch[0..1] + connect vehicle.vehicleFrame.hitch to trailer.trailerFrame.coupler; + + part trailer : Trailer { + part trailerFrame : TrailerFrame { + part coupler : TrailerCoupler; + } + } + + perform action { + action 'connect trailer to vehicle' { + // Assert that exactly one connection exists during the + // performance of this action. + abstract ref :>> trailerHitch[1]; + } + then action 'disconnect trailer from vehicle' { + // Assert that exactly no connection exists during the + // performance of this action. + abstract ref :>> trailerHitch[0]; + } + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-3.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-3.sysml new file mode 100644 index 00000000..4c123d49 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3c-Function-based Behavior-structure mod-3.sysml @@ -0,0 +1,33 @@ +package '3c-Function-based Behavior-structure mod-3' { + + part def Vehicle; + part def VehicleFrame; + part def HitchBall; + part def Trailer; + part def TrailerFrame; + part def TrailerCoupler; + + part vehicle : Vehicle { + part vehicleFrame : VehicleFrame { + part hitch : HitchBall; + } + } + + part trailer : Trailer { + part trailerFrame : TrailerFrame { + part coupler : TrailerCoupler { + ref part hitch : HitchBall; + } + } + } + + action { + // Insert the vehicle HitchBall into the TrailerCoupler. + action 'connect trailer to vehicle' + assign trailer.trailerFrame.coupler.hitch := vehicle.vehicleFrame.hitch; + + // Remove the HitchBall from the TrailerCoupler. + then action 'disconnect trailer from vehicle' + assign trailer.trailerFrame.coupler.hitch := null; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3d-Function-based Behavior-item.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3d-Function-based Behavior-item.sysml new file mode 100644 index 00000000..e645edff --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3d-Function-based Behavior-item.sysml @@ -0,0 +1,83 @@ +package '3d-Function-based Behavior-item' { + private import ScalarValues::Real; + public import Definitions::*; + public import Usages::*; + + package Definitions { + + item def Fuel; + + port def FuelPort { + out item fuel: Fuel; + } + + part def Pump { + port fuelInPort : ~FuelPort; + port fuelOutPort : FuelPort; + } + + part def StorageTank { + port fuelOutPort : FuelPort; + } + + part def FuelTank { + port fuelInPort : ~FuelPort; + } + + part def Vehicle { + port fuelInPort : ~FuelPort; + } + + action def PumpFuel { + in fuelIn : Fuel; + out fuelOut : Fuel; + } + + } + + package Usages { + + part context { + + /* Storage Element */ + part storageTank : StorageTank; + + flow of fuel : Fuel + from storageTank.fuelOutPort.fuel to pump.fuelInPort.fuel { + /* + * Note: Explicitly notating that the flow is "of fuel : Fuel" is optional. + */ + } + + part pump : Pump { + perform action pumpFuel : PumpFuel { + in fuelIn = fuelInPort.fuel; + out fuelOut = fuelOutPort.fuel; + } + } + + flow of fuel : Fuel + from pump.fuelOutPort.fuel to vehicle.fuelInPort.fuel; + + part vehicle : Vehicle { + flow fuelInPort.fuel to fuelTank.fuel { + /* + * Note: The semantics of flowing to a "stored item" is tentative. + */ + } + + /* Storage Element */ + part fuelTank : FuelTank { + attribute volumeMax : Real; + attribute fuelLevel : Real = fuel.volume / volumeMax; + + /* Stored Item */ + item fuel : Fuel { + attribute volume : Real; + /* isConserved = true */ + } + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3e-Function-based Behavior-item.sysml b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3e-Function-based Behavior-item.sysml new file mode 100644 index 00000000..c4f96820 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/03-Function-based Behavior/3e-Function-based Behavior-item.sysml @@ -0,0 +1,64 @@ +package '3e-Function-based Behavior-item' { + public import Definitions::*; + + package Definitions { + + item def VehicleAssembly; + item def AssembledVehicle :> VehicleAssembly; + + part def Vehicle :> AssembledVehicle; + part def Transmission; + part def Engine; + + } + + package Usages { + + part AssemblyLine { + + perform action 'assemble vehicle' { + + action 'assemble transmission into vehicle' { + in item 'vehicle assy without transmission or engine' : VehicleAssembly; + in item transmission : Transmission { + /* Note: A part can be treated as an item. */ + } + + out item 'vehicle assy without engine' : VehicleAssembly = 'vehicle assy without transmission or engine' { + part transmission : Transmission = 'assemble transmission into vehicle'.transmission { + /* Note: An item can become a part of something else. */ + } + } + } + + flow 'assemble transmission into vehicle'.'vehicle assy without engine' + to 'assemble engine into vehicle'.'vehicle assy without engine'; + + action 'assemble engine into vehicle' { + in item 'vehicle assy without engine' : VehicleAssembly { + part transmission : Transmission; + } + in item engine : Engine; + + out item assembledVehicle : AssembledVehicle = 'vehicle assy without engine' { + part engine : Engine = 'assemble engine into vehicle'.engine; + } + } + } + + bind 'assemble vehicle'.'assemble engine into vehicle'.assembledVehicle = vehicle; + + part vehicle : Vehicle { + /* + * Note: An in item one context can become a part in an other. + */ + + part transmission: Transmission; + part engine: Engine; + + perform action providePower; + } + + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/04-Functional Allocation/4a-Functional Allocation.sysml b/test-data/sysml2/official/sysml/validation/04-Functional Allocation/4a-Functional Allocation.sysml new file mode 100644 index 00000000..d9d32ac6 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/04-Functional Allocation/4a-Functional Allocation.sysml @@ -0,0 +1,110 @@ +package '4a-Functional Allocation' { + private import '2a-Parts Interconnection'::*; + private import '3a-Function-based Behavior-1'::*; + private import '3a-Function-based Behavior-1'::'provide power'::*; + + part vehicle1_c1_functional_allocation :> vehicle1_c1 { + // Note: The definitions of the port types in '2a-Parts Interconnection' do not include + // flow properties. + port :>> fuelCmdPort { + in fuelCmd: FuelCmd; + } + + perform 'provide power' { + doc + /* + * This allocates the action '3a-Function-based Behavior-1'::'provide power' as an enacted + * performance of 'vehicle_c1_functional_allocation'. + */ + + // This assigns the fuelCmdPort to provide the input to 'provide power'. + in fuelCmd = fuelCmdPort.fuelCmd; + } + + //* + // The above is semantically equivalent to: + + ref action 'provide power' (in fuelCmd = fuelCmdPort::fuelCmd) + :> '3a-Function-based Behavior'::'provide power', performedActions; + + // For a composite enacted performance within the vehicle, replace the above with: + + action 'provide power' (in fuelCmd = fuelCmdPort::fuelCmd) + :> '3a-Function-based Behavior'::'provide power'; + */ + + part :>> engine { + port :>> fuelCmdPort { + in fuelCmd: FuelCmd; + } + + perform 'provide power'.'generate torque' { + /* + * This allocates one of the sub-steps of 'provide power' to a sub-part of vehicle_c1. + */ + + in fuelCmd = fuelCmdPort.fuelCmd; + out engineTorque = drivePwrPort.engineTorque; + } + + port :>> drivePwrPort { + out engineTorque: Torque; + } + } + + part :>> transmission { + port :>> clutchPort { + in attribute engineTorque: Torque; + } + + perform 'provide power'.'amplify torque' { + in engineTorque = clutchPort.engineTorque; + out transmissionTorque = shaftPort_a.transmissionTorque; + } + + port :>> shaftPort_a { + out transmissionTorque: Torque; + } + } + + part :>> driveshaft { + port :>> shaftPort_b { + in transmissionTorque: Torque; + } + + perform 'provide power'.'transfer torque' { + in transmissionTorque = shaftPort_b.transmissionTorque; + out driveshaftTorque = shaftPort_c.driveshaftTorque; + } + + port :>> shaftPort_c { + out driveshaftTorque: Torque; + } + } + + part :>> rearAxleAssembly { + port :>> shaftPort_d { + in driveshaftTorque: Torque; + } + + perform 'provide power'.'distribute torque' { + in driveshaftTorque = shaftPort_d.driveshaftTorque; + out wheelTorque1 = rearAxle.leftHalfAxle.axleToWheelPort.wheelTorque; + out wheelTorque2 = rearAxle.rightHalfAxle.axleToWheelPort.wheelTorque; + } + + part :>> rearAxle { + part :>> leftHalfAxle { + port :>> axleToWheelPort { + out wheelTorque: Torque; + } + } + part :>> rightHalfAxle { + port :>> axleToWheelPort { + out wheelTorque: Torque; + } + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1.sysml b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1.sysml new file mode 100644 index 00000000..eb90ffe6 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1.sysml @@ -0,0 +1,236 @@ +package '5-State-based Behavior-1' { + private import ScalarValues::*; + private import ISQ::*; + private import '3a-Function-based Behavior-1'::*; + + package Definitions { + part def VehicleA { + /* + * The following declare that 'VehicleA' performs a + * 'provide power' action and exhibits some 'vehicle states', + * without giving details about these behaviors. + */ + perform action 'provide power': 'Provide Power'; + exhibit state 'vehicle states': 'Vehicle States'; + } + + part def VehicleController { + exhibit state 'controller states': 'Controller States'; + } + + /* + * Black box specifications for state definitions may also have + * input and output parameters, like activities, though none + * are used here. + */ + + state def 'Vehicle States'; + state def 'Controller States'; + + action def 'Perform Self Test'; + action def 'Apply Parking Brake'; + action def 'Sense Temperature' { out temp: TemperatureValue; } + + attribute def 'Vehicle Start Signal'; + attribute def 'Vehicle On Signal'; + attribute def 'Vehicle Off Signal'; + + attribute def 'Start Signal'; + attribute def 'Off Signal'; + attribute def 'Over Temp'; + attribute def 'Return to Normal'; + } + + package Usages { + private import Definitions::*; + + /* + * These actions are used enabled in the state usage + * 'vehicle states', in addition to 'provide power'. + */ + + action 'perform self test': 'Perform Self Test'; + action 'apply parking brake': 'Apply Parking Brake'; + action 'sense temperature': 'Sense Temperature'; + + state 'vehicle states': 'Vehicle States' parallel { + /* + * This is a usage of the state definition 'Vehicle States'. + * Note that it depends specifically on on the part 'vehicle1_c1'. + */ + + ref vehicle : VehicleA; + + state 'operational states' { + doc + /* + * The state definition for this usage is implicit. + */ + + entry action initial { + doc + /* + * This empty entry action acts like a start pseudo state. + */ + } + + transition initial then off; + + state off; + + transition 'off-starting' + first off + accept 'Vehicle Start Signal' + if vehicle1_c1.'brake pedal depressed' + do send new 'Start Signal'() to vehicle1_c1.vehicleController + then starting { + /* + * The transition definition for a transition usage is always implicit. + * "accept" marks the trigger, "if" the guard and "do" the effect. + * + * The notation "new 'Start Signal'()" constructs a specific instance of the + * 'Start Signal' attribute def to be sent to the 'vehicleController'. If the + * attribute def had properties, their values would be given as arguments + * inside the parentheses. + */ + } + + state starting; + + transition 'starting-on' + first starting + accept 'Vehicle On Signal' + then on; + + state on { + /* + * A state may have a "entry" action that is performed on entry into + * the state, a "do" action that is performed while in the state + * and an "exit" action that is performed on exit from the state. + */ + + entry 'perform self test'; + do 'provide power'; + exit 'apply parking brake'; + } + + transition 'on-off' + first on + accept 'Vehicle Off Signal' + then off; + } + + state 'health states' { + /* + * 'health states' is concurrent with 'operational states', because the + * containing state usage is "parallel". + */ + + entry action initial; + do 'sense temperature' { out temp; + /* + * State-behavior actions may have input and output parameters. + */ + } + + transition initial then normal; + + state normal; + + transition 'normal-maintenance' + first normal + accept at vehicle1_c1.maintenanceTime + then maintenance; + + transition 'normal-degraded' + first normal + accept when 'sense temperature'.temp > vehicle1_c1.Tmax + do send new 'Over Temp'() to vehicle1_c1.vehicleController + then degraded; + + state maintenance; + + transition 'maintenance-normal' + first maintenance + accept 'Return to Normal' + then normal; + + state degraded; + + transition 'degraded-normal' + first degraded + accept 'Return to Normal' + then normal; + } + } + + state 'controller states': 'Controller States' parallel { + state 'operational controller states' { + entry action initial; + + transition initial then off; + + state off; + + transition 'off-on' + first off + accept 'Start Signal' + then on; + + state on; + + transition 'on-off' + first on + accept 'Off Signal' + then off; + } + } + + part vehicle1_c1: VehicleA { + port fuelCmdPort { + in fuelCmd: FuelCmd; + } + + /* + * These attribute properties are used in the specification for + * 'vehicle states'. + */ + attribute 'brake pedal depressed': Boolean; + attribute maintenanceTime: Time::DateTime; + attribute Tmax: TemperatureValue; + + perform 'provide power' :>> VehicleA::'provide power' { + /* + * In the context of the 'vehicle1_c1' part, the 'provide power' action + * that is enabled in 'vehicle states' gets its input from the 'fuelCmdPort'. + */ + + in fuelCmd = fuelCmdPort.fuelCmd; + } + + exhibit 'vehicle states' :>> VehicleA::'vehicle states' { + /* + * This allocates the state usage 'vehicle states' as the detailed + * state-based behavior for 'vehicle1_c1' that fills in the generic + * declaration in 'VehicleA'. + */ + } + + //* + // The above is semantically equivalent to: + + ref state 'vehicle states' :> Usages::'vehicle states', exhibitedStates + :>> VehicleA::'vehicle states'; + + // For a composite state performance within the vehicle, replace the above with: + + state 'vehicle states' :>> Usages::'vehicle states', VehicleA::'vehicle states'; + */ + + part vehicleController: VehicleController { + exhibit 'controller states' :>> VehicleController::'controller states'; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml new file mode 100644 index 00000000..68a7d765 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml @@ -0,0 +1,238 @@ +package '5-State-based Behavior-1a' { + private import ScalarValues::*; + private import ISQ::*; + + package Definitions { + part def VehicleA { + /* + * The following declare that 'VehicleA' performs a + * 'provide power' action and exhibits some 'vehicle states', + * without giving details about these behaviors. + */ + perform action 'provide power': 'Provide Power'; + exhibit state 'vehicle states': 'Vehicle States'; + } + + part def VehicleController { + exhibit state 'controller states': 'Controller States'; + } + + /* + * Black box specifications for state definitions may also have + * input and output parameters, like activities, though none + * are used here. + */ + + state def 'Vehicle States'; + state def 'Controller States'; + + action def 'Provide Power'; + action def 'Perform Self Test'; + action def 'Apply Parking Brake'; + action def 'Sense Temperature' { out temp: TemperatureValue; } + + attribute def FuelCmd; + + attribute def 'Vehicle Start Signal'; + attribute def 'Vehicle On Signal'; + attribute def 'Vehicle Off Signal'; + + attribute def 'Start Signal'; + attribute def 'Off Signal'; + attribute def 'Over Temp'; + attribute def 'Return to Normal'; + } + + package Usages { + private import Definitions::*; + + /* + * These actions are used enabled in the state usage + * 'vehicle states', in addition to 'provide power'. + */ + + action 'provide power': 'Provide Power'; + action 'perform self test': 'Perform Self Test'; + action 'apply parking brake': 'Apply Parking Brake'; + action 'sense temperature': 'Sense Temperature'; + + state 'vehicle states': 'Vehicle States' parallel { + /* + * This is a usage of the state definition 'Vehicle States'. + * Note that it depends specifically on on the part 'vehicle1_c1'. + */ + + state 'operational states' { + doc + /* + * The state definition for this usage is implicit. + */ + + entry action initial { + doc + /* + * This empty entry action acts like a start pseudo state. + */ + } + + transition initial then off; + + state off; + + transition 'off-starting' + first off + accept 'Vehicle Start Signal' + if vehicle1_c1.'brake pedal depressed' + do send new 'Start Signal'() to vehicle1_c1.vehicleController + then starting { + /* + * The transition definition for a transition usage is always implicit. + * "accept" marks the trigger, "if" the guard and "do" the effect. + * + * The notation "'new Start Signal'()" constructs a specific instance of the + * 'Start Signal' attribute def to be sent to the 'vehicleController'. If the + * attribute def had properties, their values would be given as arguments + * inside the parentheses. + */ + } + + state starting; + + transition 'starting-on' + first starting + accept 'Vehicle On Signal' + then on; + + state on { + /* + * A state may have a "entry" action that is performed on entry into + * the state, a "do" action that is performed while in the state + * and an "exit" action that is performed on exit from the state. + */ + + entry 'perform self test'; + do 'provide power'; + exit 'apply parking brake'; + } + + transition 'on-off' + first on + accept 'Vehicle Off Signal' + then off; + } + + state 'health states' { + /* + * 'health states' is concurrent with 'operational states', because the + * containing state usage is "parallel". + */ + + entry action initial; + do 'sense temperature' { out temp; + /* + * State-behavior actions may have input and output parameters. + */ + } + + transition initial then normal; + + state normal; + + transition 'normal-maintenance' + first normal + accept at vehicle1_c1.maintenanceTime + then maintenance; + + transition 'normal-degraded' + first normal + accept when 'sense temperature'.temp > vehicle1_c1.Tmax + do send new 'Over Temp'() to vehicle1_c1.vehicleController + then degraded; + + state maintenance; + + transition 'maintenance-normal' + first maintenance + accept 'Return to Normal' + then normal; + + state degraded; + + transition 'degraded-normal' + first degraded + accept 'Return to Normal' + then normal; + } + } + + state 'controller states': 'Controller States' parallel { + state 'operational controller states' { + entry action initial; + + transition initial then off; + + state off; + + transition 'off-on' + first off + accept 'Start Signal' + then on; + + state on; + + transition 'on-off' + first on + accept 'Off Signal' + then off; + } + } + + part vehicle1_c1: VehicleA { + port fuelCmdPort { + in fuelCmd: FuelCmd; + } + + /* + * These attribute properties are used in the specification for + * 'vehicle states'. + */ + attribute 'brake pedal depressed': Boolean; + attribute maintenanceTime: Time::DateTime; + attribute Tmax: TemperatureValue; + + perform 'provide power' :>> VehicleA::'provide power' { + doc + /* + * In the context of the 'vehicle1_c1' part, the 'provide power' action + * that is enabled in 'vehicle states' gets its input from the 'fuelCmdPort'. + */ + + in fuelCmd = fuelCmdPort.fuelCmd; + } + + exhibit 'vehicle states' :>> VehicleA::'vehicle states' { + /* + * This allocates the state usage 'vehicle states' as the detailed + * state-based behavior for 'vehicle1_c1' that fills in the generic + * declaration in 'VehicleA'. + */ + } + + //* + // The above is semantically equivalent to: + + ref state 'vehicle states' :> Usages::'vehicle states', exhibitedStates + :>> VehicleA::'vehicle states'; + + // For a composite state performance within the vehicle, replace the above with: + + state 'vehicle states' :>> Usages::'vehicle states', VehicleA::'vehicle states'; + */ + + part vehicleController: VehicleController { + exhibit 'controller states' :>> VehicleController::'controller states'; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-2.sysml b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-2.sysml new file mode 100644 index 00000000..0871db00 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/05-State-based Behavior/5-State-based Behavior-2.sysml @@ -0,0 +1,128 @@ +package '5-State-based Behavior-2' { + private import ScalarValues::*; + private import ISQ::*; + private import '3a-Function-based Behavior-1'::*; + + package Definitions { + part def VehicleA { + perform action 'provide power': 'Provide Power'; + exhibit state 'vehicle states': 'Vehicle States'; + } + + part def VehicleController { + exhibit state 'controller states': 'Controller States'; + } + + state def 'Vehicle States'; + state def 'Controller States'; + + action def 'Perform Self Test'; + action def 'Apply Parking Brake'; + action def 'Sense Temperature' { out temp: TemperatureValue; } + + attribute def 'Vehicle Start Signal'; + attribute def 'Vehicle On Signal'; + attribute def 'Vehicle Off Signal'; + + attribute def 'Start Signal'; + attribute def 'Off Signal'; + attribute def 'Over Temp'; + attribute def 'Return to Normal'; + } + + package Usages { + private import Definitions::*; + + action 'perform self test': 'Perform Self Test'; + action 'apply parking brake': 'Apply Parking Brake'; + action 'sense temperature': 'Sense Temperature'; + + state 'vehicle states': 'Vehicle States' parallel { + + state 'operational states' { + entry; then off; + + /* + * The following uses a shorthand for a transition whose source + * is the immediately preceding state. + */ + state off; + accept 'Vehicle Start Signal' + if vehicle1_c1.'brake pedal depressed' + do send new 'Start Signal'() to vehicle1_c1.vehicleController + then starting; + + state starting; + accept 'Vehicle On Signal' + then on; + + state on { + entry 'perform self test'; + do 'provide power'; + exit 'apply parking brake'; + } + accept 'Vehicle Off Signal' + then off; + } + + state 'health states' { + entry; then normal; + do 'sense temperature' { out temp; } + + /* + * The shorthand can be used for multiple transitions after + * a single state. + */ + state normal; + accept at vehicle1_c1.maintenanceTime + then maintenance; + accept when 'sense temperature'.temp > vehicle1_c1.Tmax + do send new 'Over Temp'() to vehicle1_c1.vehicleController + then degraded; + + state maintenance; + accept 'Return to Normal' + then normal; + + state degraded; + accept 'Return to Normal' + then normal; + } + } + + state 'controller states': 'Controller States' parallel { + state 'operational controller states' { + entry; then off; + + state off; + accept 'Start Signal' + then on; + + state on; + accept 'Off Signal' + then off; + } + } + + part vehicle1_c1: VehicleA { + port fuelCmdPort { + in fuelCmd: FuelCmd; + } + + attribute 'brake pedal depressed': Boolean; + attribute maintenanceTime: Time::DateTime; + attribute Tmax: TemperatureValue; + + perform 'provide power' :>> VehicleA::'provide power' { + in fuelCmd = fuelCmdPort.fuelCmd; + } + + exhibit 'vehicle states' :>> VehicleA::'vehicle states'; + + part vehicleController: VehicleController { + exhibit 'controller states' :>> VehicleController::'controller states'; + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/06-Individual and Snapshots/6-Individual and Snapshots.sysml b/test-data/sysml2/official/sysml/validation/06-Individual and Snapshots/6-Individual and Snapshots.sysml new file mode 100644 index 00000000..2a4eadbd --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/06-Individual and Snapshots/6-Individual and Snapshots.sysml @@ -0,0 +1,167 @@ +package '6-Individual and Snapshots' { + private import ScalarValues::Real; + private import Time::DateTime; + private import ISQ::*; + + package 'Part Definitions' { + part def 'Temporal-Spatial Reference' { + attribute referenceTime : DateTime; + attribute referenceCoordinateSystem; + } + + /* + * Note that space and time coordinatization have not + * been fully specified yet. + */ + + part def VehicleRoadContext { + attribute t : TimeValue; + } + + part def VehicleA { + attribute mass : MassValue; + attribute position : Real; + attribute velocity : Real; + attribute acceleration : Real; + exhibit state vehicleStates { + entry; then on; + state on; + then off; + state off; + } + } + + part def Road { + attribute angle : Real; + attribute surfaceFriction : Real; + } + } + + package 'Individual Definitions' { + private import 'Part Definitions'::*; + + /* + * An individual definition restricts the instances of a part def to + * those that are portions of the same life ("identity"). + */ + + individual def 'Temporal-Spatial Reference_ID1' :> 'Temporal-Spatial Reference'; + individual def VehicleRoadContext_ID1 :> VehicleRoadContext; + individual def VehicleA_ID1 :> VehicleA; + individual def Road_ID1 :> Road; + + } + + package Values { + attribute t0 : TimeValue; + attribute t1 : TimeValue; + attribute tn : TimeValue; + + attribute m : MassValue; + + attribute p0 : Real; + attribute p1 : Real; + attribute pn : Real; + + attribute v0 : Real; + attribute v1 : Real; + attribute vn : Real; + + attribute a0 : Real; + attribute a1 : Real; + attribute an : Real; + + attribute theta0 : Real; + attribute theta1 : Real; + attribute thetan : Real; + + attribute sf0 : Real; + attribute sf1 : Real; + attribute sfn : Real; + } + + package 'Individuals and Snapshots' { + private import 'Individual Definitions'::*; + private import Values::*; + + individual reference : 'Temporal-Spatial Reference_ID1' { + /* + * An individual usage must be typed by an individual definition, + * representing the condition of that individual during some or all + * of its life. + */ + + snapshot context_t0 : VehicleRoadContext_ID1 { + :>> t = t0 { + /* + * This is a concise notation for showing the redefinition + * of a attribute property. + */ + } + + snapshot vehicle_ID1_t0 : VehicleA_ID1 { + /* + * A snapshot is a kind of individual usage restricted to + * a single instant of time. + */ + + :>> mass = m; + :>> position = p0; + :>> velocity = v0; + :>> acceleration = a0; + + exhibit vehicleStates.on { + /* + * This asserts that the snapshot exhibits the referenced + * state, which means that the vehicle must me in the state + * at the time of the snapshot. + */ + } + } + + snapshot road_ID1_t0 : Road_ID1 { + :>> angle = theta0; + :>> surfaceFriction = sf0; + } + } + + snapshot context_t1 : VehicleRoadContext_ID1 { + :>> t = t1; + + snapshot vehicle_ID1_t1 : VehicleA_ID1 { + :>> mass = m; + :>> position = p1; + :>> velocity = v1; + :>> acceleration = a1; + + exhibit vehicleStates.on; + } + + snapshot road_ID1_t1 : Road_ID1 { + :>> angle = theta1; + :>> surfaceFriction = sf1; + } + } + + // ... + + snapshot context_tn : VehicleRoadContext_ID1 { + :>> t = tn; + + snapshot vehicle_ID1_tn : VehicleA_ID1 { + :>> mass = m; + :>> position = pn; + :>> velocity = vn; + :>> acceleration = an; + + exhibit vehicleStates.off; + } + + snapshot road_ID1_tn : Road_ID1 { + :>> angle = theta1; + :>> surfaceFriction = sfn; + } + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a-Variant Configuration - General Concept.sysml b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a-Variant Configuration - General Concept.sysml new file mode 100644 index 00000000..69fd8878 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a-Variant Configuration - General Concept.sysml @@ -0,0 +1,53 @@ +package '7a-Variant Configuration - General Concept' { + + part def Vehicle; + + part part1; + part part2; + part part3; + part part4; + part part5; + part part6; + + abstract part anyVehicleConfig : Vehicle { + + variation part subsystemA { + variant part subsystem1 { + part :>> part1; + part :>> part2; + } + variant part subsystem2 { + part :>> part2; + part :>> part3; + } + } + + variation part subsystemB { + variant part subsystem3 { + part :>> part4; + part :>> part5; + } + variant part subsystem4 { + part :>> part5; + part :>> part6; + } + } + + assert constraint { + subsystemA != subsystemA::subsystem2 | + subsystemB == subsystemB::subsystem3 + } + + } + + part vehicleConfigA :> anyVehicleConfig { + part :>> subsystemA = subsystemA::subsystem1; + part :>> subsystemB = subsystemB::subsystem3; + } + + part VehicleConfigB :> anyVehicleConfig { + part :>> subsystemA = subsystemA::subsystem2; + part :>> subsystemB = subsystemB::subsystem3; + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a1-Variant Configuration - General Concept-a.sysml b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a1-Variant Configuration - General Concept-a.sysml new file mode 100644 index 00000000..244bc461 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7a1-Variant Configuration - General Concept-a.sysml @@ -0,0 +1,79 @@ +package '7a1-Variant Configuration - General Concept-a' { + + action doX; + action doY; + + part part1; + part part2; + part part3 { + port p1; + } + part part4; + part part5 { + port p2; + variation perform action doXorY { + variant perform doX; + variant perform doY; + } + } + part part6; + + abstract part def SubsystemA { + abstract part :>> part3[0..1]; + } + + abstract part def SubsystemB { + abstract part :>> part5[1]; + } + + part anyVehicleConfig { + + variation part subsystemA : SubsystemA { + variant part subsystem1 : SubsystemA { + part :>> part1[1]; + part :>> part2[1]; + } + variant part subsystem2 : SubsystemA { + part :>> part2[1]; + part :>> part3[1]; + } + } + + variation part subsystemB : SubsystemB { + variant part subsystem3 : SubsystemB { + part :>> part4[1]; + part :>> part5[1]; + } + variant part subsystem4 : SubsystemB { + part :>> part5[1]; + part :>> part6[1]; + } + } + + connect [0..1] subsystemA.part3.p1 to [1] subsystemB.part5.p2; + + assert constraint { + subsystemA != subsystemA::subsystem2 | + subsystemB == subsystemB::subsystem3 + } + + } + + part vehicleConfigA :> anyVehicleConfig { + part :>> subsystemA = subsystemA::subsystem1; + part :>> subsystemB = subsystemB::subsystem3 { + part :>> part5 { + perform action :>> doXorY = doX; + } + } + } + + part VehicleConfigB :> anyVehicleConfig { + part :>> subsystemA = subsystemA::subsystem2; + part :>> subsystemB = subsystemB::subsystem4 { + part :>> part5 { + perform action :>> doXorY = doY; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7b-Variant Configurations.sysml b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7b-Variant Configurations.sysml new file mode 100644 index 00000000..3c66a6d1 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/07-Variant Configuration/7b-Variant Configurations.sysml @@ -0,0 +1,140 @@ +package '7b-Variant Configurations' { + private import RequirementsModel::*; + private import DesignModel::*; + private import VariantDefinitions::*; + private import ControlFunctions::forAll; + + package RequirementsModel { + requirement def EnginePerformanceRequirement; + requirement highPerformanceRequirement : EnginePerformanceRequirement; + requirement normalPerformanceRequirement : EnginePerformanceRequirement; + } + + package DesignModel { + part def Vehicle; + part def Engine; + part def Transmission; + part def Clutch; + part def Driveshaft; + part def RearAxleAssembly; + part def Wheel; + + port def FuelCmdPort; + port def ClutchPort; + port def ShaftPort_b; + port def ShaftPort_c; + port def ShaftPort_d; + port def VehicleToRoadPort; + port def WheelToRoadPort; + + part vehicle : Vehicle { + port fuelCmdPort; + + bind fuelCmdPort = engine.fuelCmdPort; + + part engine : Engine[1] { + port fuelCmdPort : FuelCmdPort; + } + + part transmission : Transmission[1] { + part clutch: Clutch[1] { + port clutchPort : ClutchPort; + } + } + + part driveshaft : Driveshaft[1] { + port shaftPort_b : ShaftPort_b; + port shaftPort_c : ShaftPort_c; + } + + part rearAxleAssembly : RearAxleAssembly { + part rearWheels : Wheel[2] { + port wheelToRoadPort : WheelToRoadPort; + } + } + + port vehicleToRoadPort : VehicleToRoadPort { + port wheelToRoadPort : WheelToRoadPort[2]; + } + } + } + + package VariantDefinitions { + part def '4CylEngine' :> Engine; + part def '6CylEngine' :> Engine; + + part def ManualTransmission :> Transmission; + part def AutomaticTransmission :> Transmission; + + part def ManualClutch :> Clutch; + part def AutomaticClutch :> Clutch; + + port def ManualClutchPort :> ClutchPort; + port def AutomaticClutchPort :> ClutchPort; + + part def NarrowRimWheel :> Wheel; + part def WideRimWheel :> Wheel; + } + + package VariabilityModel { + part anyVehicleConfig :> vehicle { + + variation requirement engineRqtChoice : EnginePerformanceRequirement { + variant highPerformanceRequirement; + variant normalPerformanceRequirement; + } + + variation part engineChoice :>> engine { + variant part '4cylEngine' : '4CylEngine'; + variant part '6cylEngine' : '6CylEngine'; + } + + satisfy engineRqtChoice by engineChoice; + + assert constraint 'engine choice constraint' { + if engineRqtChoice == engineRqtChoice::highPerformanceRequirement? + engineChoice == engineChoice::'6cylEngine' + else + engineChoice == engineChoice::'4cylEngine' + } + + variation part transmissionChoice :>> transmission { + variant part manualTransmission : ManualTransmission { + part :>> clutch : ManualClutch { + port :>> clutchPort : ManualClutchPort; + } + } + variant part automaticTransmission : AutomaticTransmission { + part :>> clutch : AutomaticClutch { + port :>> clutchPort : AutomaticClutchPort; + } + } + } + + assert constraint 'engine-transmission selection constraint' { + (engineChoice == engineChoice::'4cylEngine' and transmissionChoice == transmissionChoice::manualTransmission) xor + (engineChoice == engineChoice::'6cylEngine' and transmissionChoice == transmissionChoice::automaticTransmission) + } + + part :>> rearAxleAssembly { + variation part rearWheelChoice :>> rearWheels { + variant part narrowRimWheel : NarrowRimWheel; + variant part wideRimWheel : WideRimWheel; + } + + assert constraint 'engine-wheel selection constraint' { + (engineChoice == engineChoice::'4cylEngine' and + rearWheelChoice->forAll {in ref w; w == rearWheelChoice::narrowRimWheel}) xor + (engineChoice == engineChoice::'6cylEngine' and + rearWheelChoice->forAll {in ref w; w == rearWheelChoice::wideRimWheel}) + } + } + + } + + variation part vehicleChoice :> anyVehicleConfig { + variant part vehicle_c1; + variant part vehicle_c2; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/08-Requirements/8-Requirements.sysml b/test-data/sysml2/official/sysml/validation/08-Requirements/8-Requirements.sysml new file mode 100644 index 00000000..36964242 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/08-Requirements/8-Requirements.sysml @@ -0,0 +1,205 @@ +package '8-Requirements' { + private import ScalarValues::Real; + private import ISQ::*; + private import SI::*; + public import 'Vehicle Usages'::*; + public import 'Vehicle Requirements'::*; + + package 'Vehicle Definitions' { + part def Vehicle { + attribute mass: MassValue; + attribute fuelLevel: Real; + attribute fuelTankCapacity: Real; + } + + part def Engine { + port drivePwrPort: DrivePwrPort; + perform action 'generate torque': 'Generate Torque'; + } + + part def Transmission { + port clutchPort: ClutchPort; + } + + port def DrivePwrPort; + port def ClutchPort; + + interface def EngineToTransmissionInterface { + end drivePwrPort: DrivePwrPort; + end clutchPort: ClutchPort; + } + + action def 'Generate Torque'; + } + + package 'Vehicle Usages' { + public import 'Vehicle Definitions'::*; + + action 'provide power' { + action 'generate torque' { /* ... */ } + //... + } + + part vehicle1_c1: Vehicle { + attribute :>> mass = 2000 [kg]; + perform 'provide power'; + + part engine_v1: Engine { + port :>> drivePwrPort; + perform 'provide power'.'generate torque' :>> 'generate torque'; + } + + part transmission: Transmission { + port :>> clutchPort; + } + + interface engineToTransmission: EngineToTransmissionInterface + connect engine_v1.drivePwrPort to transmission.clutchPort; + } + + part vehicle1_c2: Vehicle { + attribute :>> mass = 2500 [kg]; + } + } + + package 'Vehicle Requirements' { + public import 'Vehicle Definitions'::*; + + requirement def <'1'> MassLimitationRequirement { + /* + * The optional requirement ID of this requirement ('1') is given after the keyword "id" (using name syntax). + * Every requirement is parameterized by a "subject". The "subject" of this requirement is implicitly "Anything". + */ + + // The requirement text is given by the documentation in the requirement def body. + doc /* The actual mass shall be less than or equal to the required mass. */ + + attribute massActual: MassValue; + attribute massReqd: MassValue; + + require constraint { + /* + * A constraint can be used to formalize a requirement. + */ + massActual <= massReqd + } + } + + requirement def <'2'> ReliabilityRequirement; + + requirement <'1.1'> vehicleMass1: MassLimitationRequirement { + doc /* The vehicle mass shall be less than or equal to 2000 kg when the fuel tank is full. */ + + subject vehicle : Vehicle { + /* + * The subject of this requirement is redefined to be a "Vehicle". + */ + } + + attribute :>> massActual: MassValue = vehicle.mass { + /* + * This redefinition binds the vehicle mass to the actual mass. + */ + } + + attribute :>> massReqd = 2000 [kg] { + /* + * This redefinition sets the required mass to 2000 kg. + */ + } + + assume constraint fuelConstraint { + /* + * A constraint can also be used to specify an assumption. + */ + + doc /* full fuel tank */ + vehicle.fuelLevel >= vehicle.fuelTankCapacity + } + } + + requirement <'2.1'> vehicleMass2: MassLimitationRequirement { + doc /* The vehicle mass shall be less than or equal to 2500 kg when the fuel tank is empty. */ + + subject vehicle : Vehicle; + + attribute :>> massActual: MassValue = vehicle.mass; + attribute :>> massReqd = 2500 [kg]; + + assume constraint fuelConstraint { + doc /* empty fuel tank */ + vehicle.fuelLevel == 0.0 + } + } + + requirement <'2.2'> vehicleReliability2: ReliabilityRequirement { + subject vehicle : Vehicle; + } + + requirement <'3.1'> drivePowerInterface { + doc /* The engine shall transfer its generated torque to the transmission via the clutch interface. */ + subject drivePwrPort: DrivePwrPort; + } + + requirement <'3.2'> torqueGeneration { + doc /* The engine shall generate torque as a function of RPM as shown in Table 1. */ + subject generateTorque: 'Generate Torque'; + } + + } + + part 'vehicle1_c1 Specification Context' { + private import 'vehicle1-c1 Specification'::*; + private import 'engine-v1 Specification'::*; + + requirement 'vehicle1-c1 Specification' { + doc + /* + * This models a "requirement group" as a requirement that references other requirements. + */ + + subject vehicle : Vehicle; + requirement references vehicleMass1 { + /* + * This is a reference to a requirement defined outside the group. + * By default, the subject of the requirement is bound to that of the group. + */ + } + // ... + } + + requirement 'engine-v1 Specification' { + subject engine : Engine; + /* + * Here the subjects of the referenced requirements are defined to be specific properties of the + * subject of the group. + */ + require torqueGeneration { + in :>> generateTorque = engine.'generate torque'; + } + require drivePowerInterface { + in :>> drivePwrPort = engine.drivePwrPort; + } + } + + satisfy 'vehicle1-c1 Specification' by vehicle1_c1 { + /* + * This asserts that if the assumptions of 'vehicle1-c1 Specification' are true with 'vehicle_c1' as + * the subject, then the required constraints are also true. + */ + } + satisfy 'engine-v1 Specification' by vehicle1_c1.engine_v1; + } + + part 'vehicle1_c2 Specification Context' { + private import 'vehicle1-c2 Specification'::*; + + requirement 'vehicle1-c2 Specification' { + subject vehicle : Vehicle; + require vehicleMass2; + require vehicleReliability2; + } + + satisfy 'vehicle1-c2 Specification' by vehicle1_c2; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/09-Verification/9-Verification-simplified.sysml b/test-data/sysml2/official/sysml/validation/09-Verification/9-Verification-simplified.sysml new file mode 100644 index 00000000..ee39a3dc --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/09-Verification/9-Verification-simplified.sysml @@ -0,0 +1,115 @@ +package '9-Verification-simplified' { + private import VerificationCases::*; + private import Definitions::*; + + package Definitions { + + requirement def <'2'> MassRequirement { + attribute massActual :> ISQ::mass; + attribute massReqd :> ISQ::mass; + + doc /* The actual mass shall be less than or equal to the required mass limit. */ + + require constraint { massActual <= massReqd } + } + + part def Vehicle { + attribute mass :> ISQ::mass; + } + + part def MassVerificationSystem; + part def Scale; + part def TestOperator; + + individual def TestVehicle1 :> Vehicle; + individual def TestVehicle2 :> Vehicle; + + individual def TestSystem :> MassVerificationSystem; + + verification def MassTest { + objective massVerificationObjective { + verify requirement massRequirement : MassRequirement; + } + } + + } + + package Usages { + + requirement <'2.1'> vehicleMassRequirement : MassRequirement { + subject vehicle : Vehicle; + doc /* The vehicle mass shall be less than or equal to 2500 kg. */ + + :>> massActual = vehicle.mass; + :>> massReqd = 2500 [SI::kg]; + } + + part vehicle1_c2 : Vehicle { + // ... + } + + verification vehicleMassTest : MassTest { + subject testVehicle : Vehicle; + objective vehicleMassVerificationObjective { + // The subject of the verify is automatically bound to 'testVehicle' here. + verify vehicleMassRequirement :>> massRequirement; + } + + action collectData { + in part testVehicle : Vehicle = vehicleMassTest.testVehicle; + out massMeasured :> ISQ::mass; + } + + action processData { + in massMeasured :> ISQ::mass = collectData.massMeasured; + out massProcessed :> ISQ::mass; + } + + action evaluateData { + in massProcessed :> ISQ::mass = processData.massProcessed; + out verdict : VerdictKind = + // Check that 'testVehicle' statisfies 'vehicleMassRequirement' if its mass equals 'massProcessed'. + PassIf(vehicleMassRequirement(vehicle = new testVehicle(mass = massProcessed))); + } + + return verdict : VerdictKind = evaluateData.verdict; + } + + part massVerificationSystem : MassVerificationSystem { + perform vehicleMassTest { + in part :>> testVehicle = vehicleUnderTest; + } + + ref part vehicleUnderTest : Vehicle; + + part testOperator : TestOperator; + + part scale : Scale { + perform vehicleMassTest.collectData { + in part :>> testVehicle; + + // In reality, this would be some more involved process. + measurement = testVehicle.mass; + + out :>> massMeasured = measurement; + } + } + } + + individual testSystem : TestSystem :> massVerificationSystem { + timeslice test1 { + ref individual :>> vehicleUnderTest : TestVehicle1 :> vehicle1_c2 { + :>> mass = 2500 [SI::kg]; + } + } + + then timeslice test2 { + ref individual :>> vehicleUnderTest : TestVehicle2 :> vehicle1_c2 { + :>> mass = 2500 [SI::kg]; + } + } + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10a-Analysis.sysml b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10a-Analysis.sysml new file mode 100644 index 00000000..4cf249f0 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10a-Analysis.sysml @@ -0,0 +1,76 @@ +package '10a-Analysis' { + private import ISQ::*; + private import SI::*; + private import NumericalFunctions::*; + + package VehicleDesignModel { + part def Vehicle { + mass : MassValue; + } + + part vehicle { + :>> mass : MassValue = sum(( + vehicle.engine.mass, + vehicle.transmission.mass, + vehicle.frontAxleAssembly.mass, + vehicle.rearAxleAssembly.mass + )); + + part engine { + mass : MassValue; + } + + part transmission { + mass : MassValue; + } + + part frontAxleAssembly { + mass : MassValue; + } + + part rearAxleAssembly { + mass : MassValue; + } + } + } + + package VehicleAnalysisModel { + private import VehicleDesignModel::Vehicle; + + requirement def MassAnalysisObjective { + subject mass : MassValue; + doc /* ... */ + } + + analysis def MassAnalysisCase { + subject vehicle : Vehicle; + objective : MassAnalysisObjective { + subject = MassAnalysisCase::result; + } + + // Result + vehicle.mass + } + + analysis def AnalysisPlan { + subject vehicle : Vehicle; + objective { + doc /* ... */ + } + + analysis massAnalysisCase : MassAnalysisCase { + /* + * By default, the subject of a nested analysis case bound to that + * of its containing analysis case or analysis case definition. + */ + return mass; + } + } + + part massAnalysisContext { + analysis analysisPlan : AnalysisPlan { + subject vehicle = VehicleDesignModel::vehicle; + } + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10b-Trade-off Among Alternative Configurations.sysml b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10b-Trade-off Among Alternative Configurations.sysml new file mode 100644 index 00000000..a66a61d3 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10b-Trade-off Among Alternative Configurations.sysml @@ -0,0 +1,97 @@ +package '10b-Trade-off Among Alternative Configurations' { + private import ScalarValues::Real; + private import TradeStudies::*; + private import Definitions::*; + private import Usages::*; + + package Definitions { + + part def Vehicle; + + part def Engine { + power : ISQ::PowerValue; + mass : ISQ::MassValue; + efficiency : Real; + reliability : Real; + cost : Real; + } + + part def Piston; + part def Cylinder; + part def ConnectingRod; + part def CrankShaft; + + part def '4CylCrankShaft' :> CrankShaft; + part def '6CylCrankShaft' :> CrankShaft; + + } + + package Usages { + + part engine : Engine { + part cyl[*] : Cylinder { + part p[1] : Piston; + part rod[1] : ConnectingRod; + } + + part cs : CrankShaft; + } + + variation part engineChoice :> engine { + variant part '4cylEngine' { + part :>> cyl[4]; + part :>> cs : '4CylCrankShaft'; + } + + variant part '6cylEngine' { + part :>> cyl[6]; + part :>> cs : '6CylCrankShaft'; + } + } + + part vehicle : Vehicle { + part engine[1] :> engineChoice = engineChoice::'6cylEngine' { + assert constraint engineSelectionRational { + doc /* Selected the best engine based on the 'engineTradeStudy'. */ + engine == Analysis::engineTradeStudy.selectedAlternative + } + } + + } + } + + package Analysis { + + calc def EngineEvaluation { + doc /* Evaluation function with criteria power, mass, efficency and cost. */ + in power : ISQ::PowerValue; + in mass : ISQ::MassValue; + in efficiency : Real; + in cost : Real; + return evaluation : Real; + // Compute evaluation... + } + + analysis engineTradeStudy : TradeStudy { + subject : Engine[1..*] = all engineChoice; + objective : MaximizeObjective; + + calc :>> evaluationFunction { + in part anEngine :>> alternative : Engine; + + calc powerRollup { in engine = anEngine; return power:>ISQ::power; } + calc massRollup { in engine = anEngine; return mass:>ISQ::mass; } + calc efficiencyRollup { in engine = anEngine; return efficiency: Real; } + calc costRollup { in engine = anEngine; return cost: Real; } + + return :>> result : Real = EngineEvaluation( + powerRollup.power, massRollup.mass, efficiencyRollup.efficiency, costRollup.cost + ); + } + + return part :>> selectedAlternative : Engine; + } + + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml new file mode 100644 index 00000000..a60b8629 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml @@ -0,0 +1,168 @@ +package '10c-Fuel Economy Analysis' { + private import ScalarValues::*; + private import Quantities::*; + private import MeasurementReferences::*; + private import ISQ::*; + private import USCustomaryUnits::*; + + attribute distancePerVolume : ScalarQuantityValue = length / volume; + attribute gallon : MeasurementUnit = 231.0 * 'in'^3; + + package FuelEconomyRequirementsModel { + + requirement def FuelEconomyRequirement { + attribute actualFuelEconomy :> distancePerVolume; + attribute requiredFuelEconomy :> distancePerVolume; + + require constraint { actualFuelEconomy >= requiredFuelEconomy } + } + + requirement cityFuelEconomyRequirement : FuelEconomyRequirement { + :>> requiredFuelEconomy = 25 [mi/gallon]; + } + + requirement highwayFuelEconomyRequirement : FuelEconomyRequirement { + :>> requiredFuelEconomy = 30 [mi/gallon]; + } + + } + + package VehicleDesignModel { + + part def Vehicle { + attribute fuelEconomy_city :> distancePerVolume; + attribute fuelEconomy_highway :> distancePerVolume; + + attribute cargoWeight : MassValue; + } + + part def Engine; + part def Transmission; + + part vehicle1_c1 : Vehicle { + part engine : Engine; + part transmission : Transmission { + exhibit state transmissionState { + entry; then '1stGear'; + state '1stGear'; + then '2ndGear'; + state '2ndGear'; + then '3rdGear'; + state '3rdGear'; + then '4thGear'; + state '4thGear'; + } + } + } + + } + + package FuelEconomyAnalysisModel { + private import VehicleDesignModel::*; + private import FuelEconomyRequirementsModel::*; + + attribute def ScenarioState { + position : LengthValue; + velocity : SpeedValue; + acceleration : AccelerationValue; + inclineAngle : AngularMeasureValue; + } + + abstract calc def NominalScenario { + in t : TimeValue; + return : ScenarioState; + } + calc cityScenario : NominalScenario; + calc highwayScenario : NominalScenario; + + analysis def FuelEconomyAnalysis { + subject vehicle : Vehicle; + in calc scenario : NominalScenario; + in requirement fuelEconomyRequirement : FuelEconomyRequirement; + return calculatedFuelEconomy : ScalarQuantityValue; + + objective fuelEconomyAnalysisObjective { + doc /* + * The objective of this analysis is to determine whether the + * current vehicle design configuration can satisfy the fuel + * economy requirement. + */ + + assume constraint { + doc /* wheelDiameter == 33 inches + * drive train efficiency == 0.4 + */ + } + + require fuelEconomyRequirement { + :>> actualFuelEconomy = calculatedFuelEconomy; + } + } + + action dynamicsAnalysis { + /* + * Solve for the required engine power as a function of time + * to support the nominal scenarios. + * + * Note: Vehicle force = power/speed + * Note: EngineRPM * EngineGearRatio/WheelRPM = constant + */ + } + + action fuelConsumptionAnalysis { + /* + * Solve the engine equations to determine how much fuel is + * consumed. The engine RPM is a function of the speed of the + * vehicle and the gear state. + */ + } + } + + requirement vehicleFuelEconomyRequirementsGroup { + subject vehicle : Vehicle; + requirement vehicleFuelEconomyRequirement_city :> cityFuelEconomyRequirement { + doc /* The vehicle shall provide a fuel economy that is greater than or equal to + * 25 miles per gallon for the nominal city driving scenarios. + */ + + :>> actualFuelEconomy = vehicle.fuelEconomy_city; + + assume constraint { vehicle.cargoWeight == 1000 [lb] } + } + + requirement vehicleFuelEconomyRequirement_highway :> highwayFuelEconomyRequirement { + doc /* The vehicle shall provide a fuel economy that is greater than or equal to + * 30 miles per gallon for the nominal highway driving scenarios. + */ + + :>> actualFuelEconomy = vehicle.fuelEconomy_highway; + + assume constraint { vehicle.cargoWeight == 1000 [lb] } + } + + } + + part analysisContext { + + analysis cityFuelEconomyAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle1_c1; + in calc scenario = cityScenario; + in requirement fuelEconomyRequirement = cityFuelEconomyRequirement; + } + + analysis highwayFuelEconomyAnalysis : FuelEconomyAnalysis { + subject vehicle = vehicle1_c1; + in calc scenario = highwayScenario; + in requirement fuelEconomyRequirement = highwayFuelEconomyRequirement; + } + + part vehicle1_c1_analysized :> vehicle1_c1 { + :>> fuelEconomy_city = cityFuelEconomyAnalysis.calculatedFuelEconomy; + :>> fuelEconomy_highway = highwayFuelEconomyAnalysis.calculatedFuelEconomy; + } + + satisfy vehicleFuelEconomyRequirementsGroup by vehicle1_c1_analysized; + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10d-Dynamics Analysis.sysml b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10d-Dynamics Analysis.sysml new file mode 100644 index 00000000..ab531dcc --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/10-Analysis and Trades/10d-Dynamics Analysis.sysml @@ -0,0 +1,80 @@ +package '10d-Dynamics Analysis' { + private import ISQ::*; + + package VehicleModel { + + part def Vehicle { + attribute mass :> ISQ::mass; + } + + } + + package DynamicsModel { + + calc def Acceleration { + in p : PowerValue; + in m : MassValue; + in v : SpeedValue; + return : AccelerationValue = p / (m * v); + } + + calc def Velocity { + in v0 : SpeedValue; + in a : AccelerationValue; + in dt : TimeValue; + return : SpeedValue = v0 + a * dt; + } + + calc def Position { + in x0 : LengthValue; + in v : SpeedValue; + in dt : TimeValue; + return : LengthValue = x0 + v * dt; + } + + action def StraightLineDynamics { + in power : PowerValue; + in mass : MassValue; + in delta_t : TimeValue; + in x_in : LengthValue; + in v_in : SpeedValue; + out x_out : LengthValue = Position(x_in, v_in, delta_t); + out v_out : SpeedValue = Velocity(v_in, a_out, delta_t); + out a_out : AccelerationValue = Acceleration(power, mass, v_in); + } + } + + package AnalysisModel { + private import VehicleModel::*; + private import DynamicsModel::*; + private import SampledFunctions::*; + private import ScalarValues::Natural; + private import SequenceFunctions::*; + + analysis def DynamicsAnalysis { + subject vehicle : Vehicle; + in attribute powerProfile :> ISQ::power[*]; + in attribute initialPosition :> ISQ::length; + in attribute initialSpeed :> ISQ::speed; + in attribute deltaT :> ISQ::time; + return attribute accelerationProfile :> ISQ::acceleration[*] := (); + + private attribute position := initialPosition; + private attribute speed := initialSpeed; + + for i in 1..powerProfile->size()-1 { + perform action dynamics : StraightLineDynamics { + in power = powerProfile#(i); + in mass = vehicle.mass; + in delta_t = deltaT; + in x_in = position; + in v_in = speed; + } + then assign position := dynamics.x_out; + then assign speed := dynamics.v_out; + then assign accelerationProfile := accelerationProfile->including(dynamics.a_out); + } + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11a-View-Viewpoint.sysml b/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11a-View-Viewpoint.sysml new file mode 100644 index 00000000..887949b5 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11a-View-Viewpoint.sysml @@ -0,0 +1,57 @@ +package '11a-View-Viewpoint' { + + package SystemModel { + private import SI::*; + + part def Vehicle; + part def AxleAssembly; + part def Axle; + part def Wheel; + + part vehicle : Vehicle { + attribute mass :> ISQ::mass = 2500[SI::kg]; + part frontAxleAssembly : AxleAssembly[1] { + attribute mass :> ISQ::mass = 150[kg]; + part frontWheel : Wheel[2]; + part frontAxle : Axle[1] { + attribute mass; + attribute steeringAngle; + } + } + part rearAxleAssembly : AxleAssembly[1] { + attribute mass :> ISQ::mass = 250[kg]; + part rearWheel : Wheel[2]; + part rearAxle : Axle[1] { + attribute mass; + } + } + } + + } + + package ViewModel { + private import Views::*; + + part 'systems engineer'; + + concern 'system breakdown' { + subject; + stakeholder :>> 'systems engineer'; + } + + viewpoint 'system structure perspective' { + frame 'system breakdown'; + } + + view 'system structure generation' { + satisfy 'system structure perspective'; + expose SystemModel::vehicle::**[@SysML::PartUsage]; + render asElementTable { + view :>> columnView[1] { + render asTextualNotation; + } + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11b-Safety and Security Feature Views.sysml b/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11b-Safety and Security Feature Views.sysml new file mode 100644 index 00000000..7a96c4ae --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/11-View and Viewpoint/11b-Safety and Security Feature Views.sysml @@ -0,0 +1,66 @@ +private import Views::*; // private import library package, not internal Views package! +package '11b-Safety and Security Feaure Views' { + private import ScalarValues::*; + + package AnnotationDefinitions { + metadata def Safety { + attribute isMandatory : Boolean; + } + metadata def Security; + } + + package PartsTree { + public import AnnotationDefinitions::*; + part vehicle { + part interior { + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + part bodyAssy { + part body; + part bumper {@Safety{isMandatory = true;}} + part keylessEntry {@Security;} + } + part wheelAssy { + part wheel[2]; + part antilockBrakes[2] {@Safety{isMandatory = false;}} + } + } + } + + package ViewDefinitions { + public import AnnotationDefinitions::*; + view def SafetyFeatureView { + /* Parts that contribute to safety. */ + filter @Safety; + render asTreeDiagram; + } + + view def SafetyOrSecurityFeatureView { + /* Parts that contribute to safety OR security. */ + filter @Safety | @Security; + } + } + + package Views { + private import ViewDefinitions::*; + private import PartsTree::vehicle; + + view vehicleSafetyFeatureView : SafetyFeatureView { + expose vehicle; + } + + view vehicleMandatorySafetyFeatureView :> vehicleSafetyFeatureView { + expose vehicle::*::**; + filter @Safety and (as Safety).isMandatory; + } + + view vehicleMandatorySafetyFeatureViewStandalone { + expose vehicle::**[@Safety and (as Safety).isMandatory]; + render asElementTable; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12a-Dependency.sysml b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12a-Dependency.sysml new file mode 100644 index 00000000..9d7491a8 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12a-Dependency.sysml @@ -0,0 +1,16 @@ +package '12a-Dependency' { + + package 'Application Layer'; + package 'Service Layer'; + package 'Data Layer'; + + dependency Use from 'Application Layer' to 'Service Layer'; + dependency from 'Service Layer' to 'Data Layer'; + + attribute x; + attribute y; + attribute z; + + dependency z to x, y; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation-1.sysml b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation-1.sysml new file mode 100644 index 00000000..3e996b0a --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation-1.sysml @@ -0,0 +1,56 @@ +package '12b-Allocation-1' { + private import SI::*; + private import RequirementModel::*; + private import LogicalModel::*; + private import PhysicalModel::*; + + package RequirementModel { + requirement torqueGeneration { + subject generator: TorqueGenerator; + require constraint { + generator.generateTorque.torque > 0.0 [N*m] + } + } + } + + package LogicalModel { + action def GenerateTorque { out torque :> ISQ::torque; } + + part def LogicalElement; + part def TorqueGenerator :> LogicalElement { + perform action generateTorque : GenerateTorque; + } + + action providePower { + action generateTorque : GenerateTorque; + } + + part torqueGenerator : TorqueGenerator { + perform providePower.generateTorque :>> generateTorque; + } + + satisfy torqueGeneration by torqueGenerator; + } + + package PhysicalModel { + part def PhysicalElement; + part def PowerTrain :> PhysicalElement; + + part powerTrain : PowerTrain { + part engine { + perform providePower.generateTorque; + } + } + } + + allocation def LogicalToPhysical { + end logical : LogicalElement; + end physical : PhysicalElement; + } + + allocation torqueGenAlloc : LogicalToPhysical + allocate logical ::> torqueGenerator to physical ::> powerTrain { + + allocate torqueGenerator.generateTorque to powerTrain.engine.generateTorque; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation.sysml b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation.sysml new file mode 100644 index 00000000..69c2ef89 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/12-Dependency Relationships/12b-Allocation.sysml @@ -0,0 +1,26 @@ +package '12b-Allocation' { + private import LogicalModel::*; + private import PhysicalModel::*; + + package LogicalModel { + action providePower { + action generateTorque; + } + + part torqueGenerator { + perform providePower.generateTorque; + } + } + + package PhysicalModel { + part powerTrain { + part engine { + perform providePower.generateTorque; + } + } + } + + allocate torqueGenerator to powerTrain { + allocate torqueGenerator.generateTorque to powerTrain.engine.generateTorque; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/13-Model Containment/13a-Model Containment.sysml b/test-data/sysml2/official/sysml/validation/13-Model Containment/13a-Model Containment.sysml new file mode 100644 index 00000000..15ae77fa --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/13-Model Containment/13a-Model Containment.sysml @@ -0,0 +1,62 @@ +package '13a-Model Containment' { + private import '2a-Parts Interconnection'::*; + private import '8-Requirements'::*; + + requirement BodyAndInteriorRequirements { + public import MassLimitationRequirement; + } + + requirement PowerTrainRequirements; + + package 'Vehicle Model' { + doc + /* + * This package is used to represent a top-level "model". + * There is no specific syntax for identifying a package + * used in this way. + */ + + + package 'Vehicle1-Configuration' { + alias 'Sport Sedan' for vehicle1_c1; + + public import 'vehicle1_c1 Specification Context'::'vehicle1-c1 Specification'; + } + + package 'Vehicle Reference Model' { + doc + /* + * This package is used to represent a "model library". + * There is no specific syntax for identifying a package + * used in this way. + */ + + public import VehicleA; + public import VehicleSubsystems; + + //* + // The following would transitively import all the + // members of the VehicleSubsystems package, rather + // then importing the package itself. + + public import VehicleSubsystems::*; + */ + } + + package VehicleSubsystems { + public import 'Body&Interior'; + public import 'PowerTrain'; + } + + package 'Body&Interior' { + public import BodyAndInteriorRequirements; + } + + package PowerTrain { + public import Engine; + public import Transmission; + public import PowerTrainRequirements; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-1.sysml b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-1.sysml new file mode 100644 index 00000000..e23c7c86 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-1.sysml @@ -0,0 +1,56 @@ +package '13b-Safety and Security Features Element Group-1' { + private import ScalarValues::*; + private import AnnotationDefinitions::*; + private import PartsTree::*; + + package AnnotationDefinitions { + metadata def Safety { + attribute isMandatory : Boolean; + } + metadata def Security; + } + + package PartsTree { + part vehicle { + part interior { + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + part bodyAssy { + part body; + part bumper {@Safety{isMandatory = true;}} + part keylessEntry {@Security;} + } + part wheelAssy { + part wheel[2]; + part antilockBrakes[2] {@Safety{isMandatory = false;}} + } + } + } + + package 'Safety Features' { + /* Parts that contribute to safety. */ + public import vehicle::**; + filter @Safety; + } + + package 'Security Features' { + /* Parts that contribute to security. */ + public import vehicle::**; + filter @Security; + } + + package 'Safety & Security Features' { + /* Parts that contribute to safety OR security. */ + public import vehicle::**; + filter @Safety or @Security; + } + + package 'Mandatory Safety Features' { + /* Parts that contribute to safety AND are mandatory. */ + public import vehicle::**; + filter @Safety and (as Safety).isMandatory; + } +} diff --git a/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-2.sysml b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-2.sysml new file mode 100644 index 00000000..ff8f4e08 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group-2.sysml @@ -0,0 +1,52 @@ +package '13b-Safety and Security Features Element Group-2' { + private import ScalarValues::*; + private import AnnotationDefinitions::*; + private import PartsTree::*; + + package AnnotationDefinitions { + metadata def Safety { + attribute isMandatory : Boolean; + } + metadata def Security; + } + + package PartsTree { + part vehicle { + part interior { + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + part bodyAssy { + part body; + part bumper {@Safety{isMandatory = true;}} + part keylessEntry {@Security;} + } + part wheelAssy { + part wheel[2]; + part antilockBrakes[2] {@Safety{isMandatory = false;}} + } + } + } + + package 'Safety Features' { + /* Parts that contribute to safety. */ + public import vehicle::**[@Safety]; + } + + package 'Security Features' { + /* Parts that contribute to security. */ + public import vehicle::**[@Security]; + } + + package 'Safety & Security Features' { + /* Parts that contribute to safety OR security. */ + public import vehicle::**[@Safety or @Security]; + } + + package 'Mandatory Saftey Features' { + /* Parts that contribute to safety AND are mandatory. */ + public import vehicle::**[@Safety and (as Safety).isMandatory]; + } +} diff --git a/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group.sysml b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group.sysml new file mode 100644 index 00000000..231f9e7d --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/13-Model Containment/13b-Safety and Security Features Element Group.sysml @@ -0,0 +1,40 @@ +package '13b-Safety and Security Features Element Group' { + + part vehicle1_c1 { + part interior { + part alarm; + part seatBelt[2]; + part frontSeat[2]; + part driverAirBag; + } + part bodyAssy { + part body; + part bumper; + part keylessEntry; + } + } + + package 'Safety Features' { + /* Parts that contribute to safety. */ + + public import vehicle1_c1::interior::seatBelt; + public import vehicle1_c1::interior::driverAirBag; + public import vehicle1_c1::bodyAssy::bumper; + } + + package 'Security Features' { + /* Parts that contribute to security. */ + + public import vehicle1_c1::interior::alarm; + public import vehicle1_c1::bodyAssy::keylessEntry; + } + + package 'Safety & Security Features' { + /* Parts that contribute to safety AND + * parts that contribute to security. + */ + + public import 'Safety Features'::*; + public import 'Security Features'::*; + } +} diff --git a/test-data/sysml2/official/sysml/validation/14-Language Extensions/14a-Language Extensions.sysml b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14a-Language Extensions.sysml new file mode 100644 index 00000000..0a7ec109 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14a-Language Extensions.sysml @@ -0,0 +1,31 @@ +package '14a-Language Extensions' { + private import 'User Defined Extensions'::*; + + package 'User Defined Extensions' { + + enum def ClassificationLevel { + uncl; + conf; + secret; + } + + metadata def Classified { + ref :>> annotatedElement : SysML::PartUsage; + attribute classificationLevel : ClassificationLevel[1]; + } + } + + part part_X { + metadata Classified { + classificationLevel = ClassificationLevel::conf; + } + } + + // Alternative shorthand notation + part part_Y { + @Classified { + classificationLevel = ClassificationLevel::conf; + } + } + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/14-Language Extensions/14b-Language Extensions.sysml b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14b-Language Extensions.sysml new file mode 100644 index 00000000..d88e9e38 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14b-Language Extensions.sysml @@ -0,0 +1,51 @@ +package '14b-Language-Extensions' { + + package LibraryModel { + + part def ECU; + + } + + package UserModel { + + package Definitions { + private import LibraryModel::*; + + part def VehicleControlUnit :> ECU; + part def EngineControlUnit :> ECU; + + part def Vehicle; + part def Engine; + part def CanBus; + + port def BusIF; + } + + package Usages { + private import Definitions::*; + + part vehicle1: Vehicle { + part vehicleControlUnit : VehicleControlUnit { + port busIF: ~BusIF; + } + + connect vehicleControlUnit.busIF to canBus.vehicleControlIF; + + part canBus: CanBus { + port vehicleControlIF: BusIF; + port engineControlIF: BusIF; + port sensorIF: BusIF; + } + + connect engine.engineControlUnit.busIF to canBus.engineControlIF; + + part engine: Engine { + part engineControlUnit: EngineControlUnit { + port busIF: ~BusIF; + } + } + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/14-Language Extensions/14c-Language Extensions.sysml b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14c-Language Extensions.sysml new file mode 100644 index 00000000..b3f05884 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/14-Language Extensions/14c-Language Extensions.sysml @@ -0,0 +1,208 @@ +package '14c-Language-Extensions' { + private import ScalarValues::*; + + library package FMEALibrary { + + abstract occurrence def Situation; + + abstract occurrence situations : Situation[*] nonunique; + + occurrence def Cause :> Situation { + attribute occurs[0..1]: Real; + } + + abstract occurrence causes : Cause[*] nonunique; + + occurrence def FailureMode :> Situation { + attribute detected[0..1]: Real; + } + + abstract occurrence failureModes : FailureMode[*] nonunique; + + occurrence def Effect :> Situation { + attribute severity[0..1]: String; + } + + abstract occurrence effects : Effect[*] nonunique; + + item def FMEAItem :> Situation { + attribute RPN: Real[0..1]; + + occurrence :>> causes; + occurrence :>> failureModes; + occurrence :>> effects; + } + + abstract item fmeaItems : FMEAItem[*] nonunique; + + connection def Causation :> Occurrences::HappensBefore { + end [*] ref cause: Situation; + end [*] ref effect: Situation; + } + + abstract connection causations : Causation[*] nonunique; + + requirement def FMEARequirement; + + abstract requirement fmeaRequirements : FMEARequirement[*] nonunique; + + requirement def RequirementWithSIL :> FMEARequirement { + attribute sil: SIL; + } + + enum def SIL { A; B; C; } + + connection def Violation { + end [*] ref sit: Situation; + end [*] ref req: FMEARequirement; + } + + abstract connection violations : Violation[*] nonunique; + + abstract connection def ControllingMeasure { + end [*] ref sit: Situation; + end [*] ref req: FMEARequirement; + } + + connection def Prevention :> ControllingMeasure; + + abstract connection preventions : Prevention[*] nonunique; + + connection def Mitigation :> ControllingMeasure; + + abstract connection mitigations : Mitigation[*] nonunique; + + } + + library package FMEAMetadata { + private import Metaobjects::SemanticMetadata; + private import FMEALibrary::*; + + enum def Status { + Approved; + NotApproved; + } + + metadata def StatusHolder { + status: Status; + } + + metadata def SituationMetadata :> SemanticMetadata { + :>> baseType default situations meta SysML::Usage; + } + + metadata def CauseMetadata :> SituationMetadata { + :>> baseType = causes meta SysML::Usage; + } + + metadata def FailureModeMetadata :> SituationMetadata { + :>> baseType = failureModes meta SysML::Usage; + } + + metadata def EffectMetadata :> SituationMetadata { + :>> baseType = effects meta SysML::Usage; + } + + metadata def FMEAItemMetadata :> SituationMetadata { + :> annotatedElement : SysML::ItemDefinition; + :> annotatedElement : SysML::ItemUsage; + :>> baseType = fmeaItems meta SysML::Usage; + } + + metadata def CausationMetadata :> SemanticMetadata { + :>> annotatedElement : SysML::ConnectionUsage; + :>> baseType = causations meta SysML::Usage; + } + + metadata def FMEARequirementMetadata :> SemanticMetadata { + :>> annotatedElement : SysML::RequirementUsage; + :>> baseType = fmeaRequirements meta SysML::Usage; + } + + metadata def ViolationMetadata :> SemanticMetadata { + :>> annotatedElement : SysML::ConnectionUsage; + :>> baseType = violations meta SysML::Usage; + } + + abstract metadata def ControllingMeasureMetadata :> SemanticMetadata { + :>> annotatedElement : SysML::ConnectionUsage; + } + + metadata def PreventionMetadata :> ControllingMeasureMetadata { + :>> baseType = preventions meta SysML::Usage; + } + + metadata def MitigationMetadata :> ControllingMeasureMetadata { + :>> baseType = mitigations meta SysML::Usage; + } + + } + + package FMEAUserModel { + private import FMEALibrary::*; + private import FMEAMetadata::*; + + #fmeaspec requirement req1 { + doc /* Meter designed according to ISO00124 */ + } + + #fmeaspec requirement req2 { + doc /* Device working for 1 week without the need to replace batteries */ + } + + #fmeaspec requirement req3: RequirementWithSIL { + @StatusHolder { status = Status::Approved; } + + doc /* Alarm when battery has sank */ + + :>> sil = SIL::A; + } + + #fmea item def 'Glucose FMEA Item' { + + #prevention connect 'battery depleted' to req1; + + #cause occurrence 'battery depleted' { + :>> occurs = 0.005; + } + + #causation connect 'battery depleted' to 'battery cannot be charged'; + + #failure occurrence 'battery cannot be charged' { + :>> detected = 0.013; + } + + #causation connect 'battery cannot be charged' to 'glucose level undetected'; + + #effect occurrence 'glucose level undetected'; + + #causation connect 'glucose level undetected' to 'therapy delay'; + + #effect occurrence 'therapy delay' { + :>> severity = "High"; + } + + } + + #violation connect 'Glucose Meter in Use' to req2; + #mitigation connect 'Glucose Meter in Use' to req3; + + #fmea item 'Glucose Meter in Use' : 'Glucose FMEA Item' { + + part 'glucose meter' { + event 'glucose level undetected'[*]; + part battery { + event 'battery depleted'[*]; + event 'battery cannot be charged'[*]; + } + part pump; + part reservoir; + } + + part patient { + event 'therapy delay'[*]; + } + } + + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_01-Constants.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_01-Constants.sysml new file mode 100644 index 00000000..bb04e45d --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_01-Constants.sysml @@ -0,0 +1,55 @@ +package '15_01-Constants' { + private import MeasurementReferences::*; + private import SI::*; + private import RealFunctions::*; + + /* Note: Value properties that are bound to specific values are constants and have the specified + * values in all contexts. It is not legal to redefine them. + */ + + package 'Mathematical Constants' { + doc + /* + * Standard mathematical constants + * + * Irrational constants cannot be represented exactly with finite precision. + * However, they can be required to be implemented with a attribute that is accurate + * to at least a certain precision. + * + * (The decimal literals here should be interpreted as being fixed point and exact.) + */ + + attribute e: Real { + assert constraint { round(e * 1E20) == 271828182845904523536.0 } + } + attribute pi: Real { + assert constraint { round(pi * 1E20) == 314159265358979323846.0 } + } + } + + package 'Fundamental Physical Constants' { + doc + /* + * Standard fundamental physical constants + * + * Physical constants have a standard measured attribute to a finite precision. + * + * The reference source is: + * CODATA - Task Group on Fundamental Physical Constants (TGFC) - 2018 CODATA recommended values + * See https://codata.org/initiatives/strategic-programme/fundamental-physical-constants/ + * For the actual values see https://pml.nist.gov/cuu/Constants/ + */ + + attribute 'fine structure constant' : DimensionOneValue = 7.2973525693E-3[one]; // 2018 CODATA attribute 7.2973525693E-3; uncertainty = 0.0000000011E-3 + attribute 'electron to proton mass ratio': DimensionOneValue = 5.44617021487E-4[one]; // 2018 CODATA attribute 5.44617021487E-4; uncertainty = 0.00000000033E-4 + attribute 'speed of light in vacuum' : SpeedValue = 299792458[m/s]; // 2018 CODATA attribute 299792458 m s^-1; (exact) + } + + package 'Global Context' { + attribute 'nominal earth gravitational acceleration': AccelerationValue = 9.80665['m/s²']; + } + + package 'Model X Context' { + attribute 'amplifier gain': DimensionOneValue = 3.5[one]; + } +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_02-Basic Value Properties.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_02-Basic Value Properties.sysml new file mode 100644 index 00000000..84a7fe20 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_02-Basic Value Properties.sysml @@ -0,0 +1,25 @@ +package '15_02-Basic Value Properties' { + private import ScalarValues::*; + + attribute def LengthValue :> Real { + doc + /* + * Real world user models would use a quantity type + * from the library model. A attribute def is defined + * here to show that it is possible. + */ + } + + part def Tire { + attribute manufacturer: String; + attribute hubDiameter: LengthValue; + attribute width: Integer; + } + + part frenchTire: Tire { + attribute :>> manufacturer = "Michelin"; + attribute :>> hubDiameter = 18.0; + attribute :>> width = 245; + } + +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_03-Value Expression.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_03-Value Expression.sysml new file mode 100644 index 00000000..08efaa0a --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_03-Value Expression.sysml @@ -0,0 +1,30 @@ +package '15_03-Value Expression' { + private import SI::*; + private import USCustomaryUnits::*; + + part def Vehicle_1 { + attribute mass: MassValue = 1200 [kg]; + attribute length: LengthValue = 4.82 [m]; + part leftFrontWheel : Wheel; + part rightFrontWheel : Wheel; + } + + part def Wheel { + attribute hubDiameter: LengthValue = 18 ['in']; + attribute width: LengthValue = 245 [mm]; + attribute outerDiameter: LengthValue = (hubDiameter + 2 * tire.height) [mm] { + doc + /* + * This binds 'outDiameter' to the result of a computed attribute. + * There is no need to mark it as "derived". + */ + } + part tire: Tire[1]; + } + + part def Tire { + attribute profileDepth: LengthValue default 6.0 [mm]; + constraint hasLegalProfileDepth {profileDepth >= 3.5 [mm]} + attribute height: LengthValue = 45 [mm]; + } +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_04-Logical Expressions.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_04-Logical Expressions.sysml new file mode 100644 index 00000000..4bf87321 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_04-Logical Expressions.sysml @@ -0,0 +1,30 @@ +package '15_04-Logical Expressions' { + private import ScalarValues::*; + + part def Engine; + part def '4CylEngine' :> Engine; + part def '6CylEngine' :> Engine; + + part def Transmission; + part def ManualTransmission :> Transmission; + part def AutomaticTransmission :> Transmission; + + part def Vehicle { + attribute isHighPerformance: Boolean; + + part engine: Engine[1]; + part transmission: Transmission[1]; + + assert constraint { + if isHighPerformance? engine istype '6CylEngine' + else engine istype '4CylEngine' + } + + assert constraint { + (engine istype '4CylEngine' and + transmission istype ManualTransmission) xor + (engine istype '6CylEngine' and + transmission istype AutomaticTransmission) + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_05-Unification of Expression and Constraint Definition.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_05-Unification of Expression and Constraint Definition.sysml new file mode 100644 index 00000000..70d55bc2 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_05-Unification of Expression and Constraint Definition.sysml @@ -0,0 +1,56 @@ +package '15_05-Unification of Expression and Constraint Definition' { + private import '15_03-Value Expression'::*; + private import ControlFunctions::forAll; + private import SI::*; + + constraint def DiscBrakeConstraint { + in wheelAssy : WheelAssy[4]; + + wheelAssy->forAll {in ref w: WheelAssy; + 2 * w.discBrakeAssy.radius < w.wheel.outerDiameter + } + } + + constraint def DiscBrakeFitConstraint_Alt { + in discBrakeAssy : DiscBrakeAssy[1]; + in wheel : Wheel[1]; + + 2 * discBrakeAssy.radius < wheel.outerDiameter + } + + part def Vehicle_2 { + attribute mass : MassValue[1] = 1200 [kg]; + attribute length : LengthValue[1] = 4.82 [m]; + + part wheelAssy : WheelAssy[4]; + + constraint discBrakeConstraint : DiscBrakeConstraint { + doc + /* + * This constraint is computed, but not asserted. This means a tool can identify + * when it is violated without the model being inconsistent. + */ + in wheelAssy = Vehicle_2::wheelAssy; + } + } + + part def WheelAssy { + part wheel : Wheel[1]; + part discBrakeAssy : DiscBrakeAssy[1]; + + assert constraint discBrakeFitConstraint_Alt: DiscBrakeFitConstraint_Alt { + doc + /* + * This constraint is asserted to be true, which means that the model + * is inconsistent if it the constraint is violated. + */ + + in discBrakeAssy = WheelAssy::discBrakeAssy; + in wheel = WheelAssy::wheel; + } + } + + part def DiscBrakeAssy { + attribute radius : LengthValue[1] = 95 [mm]; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_06-System of Quantities.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_06-System of Quantities.sysml new file mode 100644 index 00000000..6e2076b0 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_06-System of Quantities.sysml @@ -0,0 +1,40 @@ +package '15_06-System of Quantities' { + private import ISQ::*; + + /* + * A System of Quantities is represented by a model library package. + * + * Its structure is modeled after the International System of Quantities (ISQ): + * - Quantity dimension is defined as the product of powers of a selected set of base quantities. + * - A system of quantities is multi-dimensional space spanned by the powers of its base quantities. + * - Any base quantity is modeled as a specialization of a SimpleUnit. Such a specialized SimpleUnit defines one base unit vector + * (with power one by definition), e.g. MassUnit with symbol M, that establishes a base quantity dimension for the system of quantities, + * without committing yet to a particular choice of measurement unit. + * - To complete the system of quantities any number of derived quantities can be added. + * - A derived quantity is modeled as a specialization of a DerivedUnit. A DerivedUnit is defined in terms of so-called UnitPowerFactors. + * Each UnitPowerFactor is a combination of a base (or other derived) quantity and an exponent. + * - As an example the AccelerationUnit (specialization of DerivedUnit) can be defined as the combination of LengthUnit (symbol L) + * to the power 1 and TimeUnit (symbol T) to the power -2, so having quantity dimension L¹⋅T⁻². + * - A quantity of dimension one is defined as a derived quantity for which the effective exponent for each + * of its base quantity power factors is zero. Historically a quantity of dimension one was also called a dimensionless quantity. + * - A quantity of dimension one may be defined by adding all quantity power factors that cancel out by having positive and negative + * exponents. Doing so enables distinction between different 'kinds of' quantities of dimension one, e.g: + * angle (L¹⋅L⁻¹), mass ratio (L¹⋅L⁻¹), power ratio (L²⋅M⋅T⁻³⋅L⁻²⋅M⁻¹⋅T³), Mach number (L¹⋅T⁻¹⋅L⁻¹⋅T¹). + * + * The International System of Quantities (ISQ) as defined in ISO/IEC 80000 is added as a predefined model library to SysML v2. + * However, this does not prevent to model any other system of quantities in another model library and use it. + */ + + /* + * Above capabilities were implemented in: + * - standard library Quantities: + * TensorQuantityValue, VectorQuantityValue, ScalarQuantityValue, + * tensorQuantities, vectorQuantities, scalarQuantities, + * SystemOfQuantities + * - standard library MeasurementReferences: + * TensorMeasurementReference, VectorMeasurementReference, ScalarMeasurementReference, + * SystemOfUnits + * - standard library ISQBase: + * attribute 'International System of Quantities': SystemOfQuantities in ISQBase + */ +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_07-System of Units and Scales.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_07-System of Units and Scales.sysml new file mode 100644 index 00000000..cd861d6b --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_07-System of Units and Scales.sysml @@ -0,0 +1,46 @@ +package '15_07-System of Units and Scales' { + private import ISQ::*; + private import USCustomaryUnits::*; + + /* + * A System of Units and Scales is represented by a model library package. + * + * Its structure is modeled after the International System of Units -- Système Internationale d'Unités, abbreviated to SI -- as defined in ISO/IEC 80000: + * - Measurement units and scales are generalized to a common super type MeasurementReference. + * - A particular quantity is modeled as the tuple of a numerical value (i.e. a mathematical number) and a MeasurementReference. + * - An actual measurement unit is modeled as a usage of a specialization of either SimpleUnit or DerivedUnit, e.g. TimeUnit or ForceUnit, + * see the SI package. + * - The quantity dimension of the actual unit usage must match the quantity dimension of the generic quantity unit definition that it is a usage of. + * - A system of units and scales must define exactly one selected base unit for each base quantity in the associated system of quantities. The collection of + * base units forms the foundation for automated quantity value conversion between any pair of compatible units and/or scales. + * - If only a measurement unit is used on a quantity value, it implies expression on a ratio scale, in other words only the ratio between the actual quantity value, + * and the defined unit value is of importance. On ratio scales for one kind of quantity that only differ in their unit (e.g. metre and inch) + * zero is zero no matter what unit is selected. + * - A unit may carry a conversion factor definition w.r.t. to another reference unit. It can be a conversion by convention (e.g. between metre and foot) or + * via an ISO/IEC 80000 prefix symbol that indicates a decimal or binary multiple or sub-multiple (e.g. kilo, nano, mega, kibi, mebi, ...). See package SIPrefixes. + * - In addition to measurement units / ratio scales also other types of measurement scales are supported. The additional scales are: + * - ordinal scales (e.g. Beaufort wind force, Richter Scale, Rockwell C hardness scale), + * - interval scales (e.g. absolute temperature in deg C or F), + * - cyclic ratio scales (e.g. rotation angle with modulus 360 degree), + * - logarithmic scales (e.g. dB(A) or dBA sound pressure level w.r.t. a reference ambient pressure, dB(m) or dBm power ratio w.r.t. 1 mW). + * - Any base unit quantity is modeled as a specialization of a SimpleUnit. This specialized SimpleUnit (e.g. MassUnit) defines one base unit vector (with power one by definition) + * that establishes a base quantity dimension for the system of quantities, without committing yet to a particular choice of measurement unit. + * + * The International System of Units (SI) as defined in ISO/IEC 80000 as well as the US Customary System of Units as defined by NIST SP 811 + * are added as predefined model libraries to SysML v2. + * However, this does not prevent to model any other system of units and scales in another model library and use it. + */ + + /* + * Above capabilities were implemented in: + * - standard library MeasurementReferences: + * TensorMeasurementReference, VectorMeasurementReference, ScalarMeasurementReference, + * MeasurementUnit, OrdinalScale, IntervalScale, CyclicRatioScale, LogarithmicScale, + * SystemOfUnits + * - standard library SI: + * attribute 'ISO/IEC 80000 International System of Units' : SystemOfUnits + * :>> systemOfQuantities = isq; + * :>> baseUnits = (m, kg, s, A, K, mol, cd); + * } + */ +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_08-Range Restriction.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_08-Range Restriction.sysml new file mode 100644 index 00000000..d2cc3445 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_08-Range Restriction.sysml @@ -0,0 +1,19 @@ +package '15_08-Range Restriction' { + private import ISQ::*; + private import SI::*; + private import '15_01-Constants'::'Mathematical Constants'::pi; + + part def HeadLightsTiltKnob { + attribute headLightsTile : LightBeamTiltAngleValue[1]; + } + + attribute def LightBeamTiltAngleValue :> PlaneAngleValue { + attribute angle: LightBeamTiltAngleValue :>> self { + doc + /* + * Tilt angle shall be limited to the range between 50 and 80 degrees (inclusive). + */ + } + assert constraint { angle >= 50 ['°'] and angle <= 80 ['°'] } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_10-Primitive Data Types.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_10-Primitive Data Types.sysml new file mode 100644 index 00000000..2a03ed01 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_10-Primitive Data Types.sysml @@ -0,0 +1,89 @@ +package '15.10-Primitive Data Types' { + /* + * Primitive data types are defined in normative model libraries. + * Any more specialized data types can be declared in user-defined + * model libraries or models as needed. + */ + + private import ScalarValues::Integer { + doc + /* + * The unqualified Integer is signed, in line with integer numbers in mathematics. + */ + } + + private import ScalarValues::Natural; + attribute def UnsignedInteger :> Natural { + doc /* Mathematically, unsigned integers are just natural numbers (non-negative integers). */ + } + + private import ScalarValues::Real { + doc + /* + * The unqualified Real is signed, in line with real numbers in mathematics. + */ + } + + attribute def UnsignedReal :> Real { + doc + /* + * Example of restriction of the base Real datatype. + */ + attribute x: Real :>> self; + assert constraint { x >= 0.0 } + } + + private import ScalarValues::String { + doc + /* + * String attributes are sequences of characters. + */ + } + + private import ScalarValues::Boolean { + doc + /* + * Boolean type has two legal attributes: true, false. + */ + } + + private import Time::DateTime; + + enum def ConditionColor { + doc + /* + * Enumerations are defined as an implicit restriction of the extent of the + * enumeration type to the listed enumeration values. + * Note: Enumerations are currently limited to attributes. + */ + + enum red; + enum yellow; + enum green; + } + + attribute def ConditionLevel { + attribute associatedColor : ConditionColor; + } + + enum def SeverityEnum :> ConditionLevel { + danger { + :>> associatedColor = ConditionColor::red; + } + warning { + :>> associatedColor = ConditionColor::yellow; + } + normal { + :>> associatedColor = ConditionColor::green; + } + } + + attribute def Diameter :> ISQ::LengthValue; + enum def DiameterChoice :> Diameter { + small = 60 [SI::mm]; + medium = 70 [SI::mm]; + large = 80 [SI::mm]; + } + attribute aperatureDiameter: DiameterChoice = DiameterChoice::small; + +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_11-Variable Length Collection Types.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_11-Variable Length Collection Types.sysml new file mode 100644 index 00000000..30b57d35 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_11-Variable Length Collection Types.sysml @@ -0,0 +1,36 @@ +package '15_11-Variable Length Collection Types' { + private import ScalarValues::*; + private import Collections::*; + + part def SparePart; + part def Person; + + /* Examples of declaring syntactic sugar-like names for instantiating collection types. */ + + attribute def 'Bag' :> Bag { + ref part :>> elements: SparePart; + } + + attribute def 'List' :> List { + value :>> elements: Integer; + } + + attribute def 'Set' :> Set { + attribute :>> elements: String; + } + + attribute def 'OrderedSet' :> OrderedSet { + ref part :>> elements: Person; + } + + attribute def 'List>' :> List { + attribute :>> elements: Set { + ref part :>> elements: Person; + } + } + + attribute def 'Array[4]' :> Array { + attribute :>> elements: Real; + attribute :>> dimensions = 4; + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_12-Compound Value Type.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_12-Compound Value Type.sysml new file mode 100644 index 00000000..2e412d84 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_12-Compound Value Type.sysml @@ -0,0 +1,31 @@ +package '15_12-Compound Value Type' { + private import ScalarValues::*; + private import USCustomaryUnits::'in'; + + /* + * Real world user models would use quantity and vector types + * from library models. They are included here for the purpose + * of showing how such attribute defs can be defined. + */ + + attribute def PositionVector { + attribute x: Real[1]; + attribute y: Real[1]; + attribute z: Real[1]; + } + + attribute def LengthValue :> Real; + + attribute def TireInfo { + attribute manufacturer: String; + attribute hubDiameter: LengthValue; + attribute width: Integer; + attribute placement: PositionVector[0..1]; + } + + attribute frenchTireInfo: TireInfo { + attribute :>> manufacturer = "Michelin"; + attribute :>> hubDiameter = 18.0['in']; + attribute :>> width = 245; + } +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_13-Discretely Sampled Function Value.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_13-Discretely Sampled Function Value.sysml new file mode 100644 index 00000000..8ad93be6 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_13-Discretely Sampled Function Value.sysml @@ -0,0 +1,76 @@ +package '15_13-Discretely Sampled Function Value' { + private import SampledFunctions::SampledFunction; + private import SampledFunctions::SamplePair; + private import Collections::Array; + private import ISQ::*; + private import SI::*; + private import MeasurementReferences::*; + private import Time::*; + + attribute def MissionElapsedTimeScale :> TimeScale { + :>> unit = s; + attribute :>> definitionalEpoch { + :>> num = 0; + :>> definition = "time instant zero at launch"; + } + attribute definitionalEpochInUTC : Iso8601DateTime; + + // Map the definitional epoch (t = 0) of this scale to a reference epoch expressed in UTC + // This modeled as a 1D coordinate transformation (translation only) + attribute :>> transformation : CoordinateFramePlacement { + :>> source = UTC; + :>> origin = definitionalEpochInUTC; + :>> basisDirections = 1 [UTC]; + } + } + + attribute mets: MissionElapsedTimeScale { + doc + /* + * Define mission elapsed time scale starting at given UTC date time (in microsecond resolution) + */ + :>> definitionalEpochInUTC { :>> val = "2020-08-23T22:42:32.924534Z";} + } + + attribute def MissionElapsedTimeValue :> TimeInstantValue { + doc + /* + * Define scalar quantity value type for mission elapsed time + */ + :>> mRef = mets; + } + + attribute spatialCF: CartesianSpatial3dCoordinateFrame[1] { + doc + /* + * Define Cartesian 3D coordinate systems for position and velocity + * Create a velocity coordinate system from the spatial coordinate system through division by second + */ + :>> mRefs = (m, m, m); + } + attribute velocityCF: CartesianVelocity3dCoordinateFrame[1] = spatialCF/s; + + attribute def PositionAndVelocity { + attribute position : CartesianPosition3dVector[1]; + attribute velocity : CartesianVelocity3dVector[1]; + } + + attribute def AscentProfile :> SampledFunction { + attribute def AscentSample :> SamplePair { + attribute :>> domainValue: MissionElapsedTimeValue[1]; + attribute :>> rangeValue: PositionAndVelocity[1]; + } + attribute :>> samples: AscentSample[*] ordered; + } + + attribute ascentProfile1: AscentProfile { + doc /* Example ascent profile */ + attribute sample1: AscentSample { :>> domainValue = 0.0 [mets]; :>> rangeValue = pv1; + attribute pv1: PositionAndVelocity {:>> position = (0, 0, 0) [spatialCF]; :>> velocity = (0, 0, 0) [velocityCF]; } } + attribute sample2: AscentSample { :>> domainValue = 2.5 [mets]; :>> rangeValue = pv1; + attribute pv1: PositionAndVelocity {:>> position = (0.01, 0.03, 8.6) [spatialCF]; :>> velocity = (0, 0, 5.5) [velocityCF]; } } + attribute sample3: AscentSample { :>> domainValue = 5.1 [mets]; :>> rangeValue = pv1; + attribute pv1: PositionAndVelocity {:>> position = (0.04, 0.12, 18.6) [spatialCF]; :>> velocity = (0.05, 0.03, 25.3) [velocityCF]; } } + attribute :>> samples = (sample1, sample2, sample3); + } +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19-Materials with Properties.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19-Materials with Properties.sysml new file mode 100644 index 00000000..65abf474 --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19-Materials with Properties.sysml @@ -0,0 +1,82 @@ +package '15_19-Materials with Properties' { + private import ScalarValues::Real; + private import Quantities::*; + private import MeasurementReferences::*; + private import SI::*; + + attribute def AtomicMassValue :> MassValue; + + attribute def TensileStrengthUnit :> DerivedUnit { + private attribute lengthPF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = -1; } + private attribute massPF: QuantityPowerFactor[1] { :>> quantity = isq.M; :>> exponent = 1; } + private attribute durationPF: QuantityPowerFactor[1] { :>> quantity = isq.T; :>> exponent = -2; } + attribute :>> quantityDimension { :>> quantityPowerFactors = (lengthPF, massPF, durationPF); } + } + + attribute def TensileStrengthValue :> ScalarQuantityValue { + attribute :>> num: Real; + attribute :>> mRef: TensileStrengthUnit; + } + + attribute <'N/mm²'> 'newton per square millimetre' : TensileStrengthUnit = N / mm^2; + + part def Substance; + part def Material :> Substance; + + /* + * The classification of materials into metals and alloys is grossly simplified and not exhaustive. + * A more complete classification would include: ChemicalSubstance, PureMaterial, MixedMaterial, + * Class, Ceramic, OrganicMaterial, AnorganicMaterial, Polymer, HybridMaterial, CompositeMaterial, + * etc. + */ + + part def Metal :> Material { + attribute atomicMass: AtomicMassValue[1]; + } + + attribute def MaterialFraction { + ref material: Material[1]; + attribute massFraction: MassFractionValue[1]; + } + + attribute def MassFractionValue :> DimensionOneValue; + + part def Alloy :> Material { + attribute fractions: MaterialFraction[2..*]; + } + + individual def Iron :> Metal { + attribute :>> atomicMass = 55.845 [Da]; + } + + individual def Carbon :> Metal { + attribute atomicMass :>> Metal::atomicMass = 12.011[Da]; + } + + individual def Manganese :> Metal { + attribute atomicMass :>> Metal::atomicMass = 54.938[Da]; + } + + individual def Steel_980 :> Alloy { + /* + * Particular example of high tensile strength steel. + */ + + attribute fraction1 :> fractions { + ref :>> material : Iron; + attribute :>> massFraction = 0.9862[one]; + } + + attribute fraction2 :> fractions { + ref :>> material : Carbon; + attribute :>> massFraction = 0.9862[one]; + } + + attribute fraction3 :> fractions { + ref :>> material : Manganese; + attribute :>> massFraction = 0.9862[one]; + } + + attribute tensileStrength: TensileStrengthValue = 980['N/mm²']; + } +} diff --git a/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19a-Materials with Properties.sysml b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19a-Materials with Properties.sysml new file mode 100644 index 00000000..7704f06f --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/15-Properties-Values-Expressions/15_19a-Materials with Properties.sysml @@ -0,0 +1,69 @@ +package '15_19a-Materials with Properties' { + private import ScalarValues::*; + private import Quantities::*; + private import MeasurementReferences::*; + private import SI::*; + + attribute def AtomicMassValue :> MassValue; + + /* Example declarations of a quantity and unit that are not specified in ISQ and SI */ + + attribute def TensileStrengthUnit :> DerivedUnit { + private attribute lengthPF: QuantityPowerFactor[1] { :>> quantity = isq.L; :>> exponent = -1; } + private attribute massPF: QuantityPowerFactor[1] { :>> quantity = isq.M; :>> exponent = 1; } + private attribute durationPF: QuantityPowerFactor[1] { :>> quantity = isq.T; :>> exponent = -2; } + attribute :>> quantityDimension { :>> quantityPowerFactors = (lengthPF, massPF, durationPF); } + } + + attribute def TensileStrengthValue :> ScalarQuantityValue { + attribute :>> num: Real; + attribute :>> mRef: TensileStrengthUnit; + } + + attribute <'N/mm²'> 'newton per square millimetre' : TensileStrengthUnit = N / mm^2; + + attribute def Substance; + attribute def Material :> Substance; + + /* + * The classification of materials into metals and alloys is grossly simplified and not exhaustive. + * A more complete classification would include: ChemicalSubstance, PureMaterial, MixedMaterial, + * Class, Ceramic, OrganicMaterial, AnorganicMaterial, Polymer, HybridMaterial, CompositeMaterial, + * etc. + */ + + attribute def Metal :> Material { + attribute atomicMass: AtomicMassValue[1]; + } + + attribute def Alloy :> Material { + attribute fractions: MaterialFraction[2..*]; + } + + attribute def MaterialFraction { + attribute material: Material[1]; + attribute massFraction: MassFractionValue[1]; + } + + attribute def MassFractionValue :> DimensionOneValue; + + /* + * Value properties bound to specifically constructed compound values. + */ + attribute Iron: Metal { :>> atomicMass = 55.845[Da]; } + attribute Carbon: Metal { :>> atomicMass = 12.011[Da]; } + attribute Manganese: Metal { :>> atomicMass = 54.938[Da]; } + + attribute Steel_980: Alloy { + /* + * Value property with redefined/added sub-properties. + * (Particular example of high tensile strength steel.) + */ + + private attribute fraction1: MaterialFraction { :>> material = Iron; :>> massFraction = 0.9862[one]; } + private attribute fraction2: MaterialFraction { :>> material = Carbon; :>> massFraction = 0.0018[one]; } + private attribute fraction3: MaterialFraction { :>> material = Manganese; :>> massFraction = 0.012[one]; } + attribute :>> fractions = (fraction1, fraction2, fraction3); + attribute tensileStrength: TensileStrengthValue = 980 ['N/mm²']; + } +} diff --git a/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17a-Sequence-Modeling.sysml b/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17a-Sequence-Modeling.sysml new file mode 100644 index 00000000..a10a525d --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17a-Sequence-Modeling.sysml @@ -0,0 +1,42 @@ +package '17a-Sequence-Modeling' { + private import ScalarValues::*; + private import PayloadDefinitions::*; + + package PayloadDefinitions { + item def Subscribe { + attribute topic : String; + ref part subscriber; + } + + item def Publish { + attribute topic : String; + ref publication; + } + + item def Deliver { + ref publication; + } + } + + occurrence def PubSubSequence { + part producer[1] { + event occurrence publish_source_event; + } + + message publish_message of Publish[1] from producer.publish_source_event to server.publish_target_event; + + part server[1] { + event occurrence subscribe_target_event; + then event occurrence publish_target_event; + then event occurrence deliver_source_event; + } + + message subscribe_message of Subscribe[1] from consumer.subscribe_source_event to server.subscribe_target_event; + message deliver_message of Deliver[1] from server.deliver_source_event to consumer.deliver_target_event; + + part consumer[1] { + event occurrence subscribe_source_event; + then event occurrence deliver_target_event; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17b-Sequence-Modeling.sysml b/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17b-Sequence-Modeling.sysml new file mode 100644 index 00000000..9d2f158f --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/17-Sequence Modeling/17b-Sequence-Modeling.sysml @@ -0,0 +1,42 @@ +package '17b-Sequence-Modeling' { + private import ScalarValues::*; + private import PayloadDefinitions::*; + + package PayloadDefinitions { + item def Subscribe { + attribute topic : String; + ref part subscriber; + } + + item def Publish { + attribute topic : String; + ref publication; + } + + item def Deliver { + ref publication; + } + } + + occurrence def PubSubSequence { + part producer[1] { + event publish_message.sourceEvent; + } + + message publish_message of Publish[1]; + + part server[1] { + event subscribe_message.targetEvent; + then event publish_message.targetEvent; + then event deliver_message.sourceEvent; + } + + message subscribe_message of Subscribe[1]; + message deliver_message of Deliver[1]; + + part consumer[1] { + event subscribe_message.sourceEvent; + then event deliver_message.targetEvent; + } + } +} \ No newline at end of file diff --git a/test-data/sysml2/official/sysml/validation/18-Use Case/18-Use Case.sysml b/test-data/sysml2/official/sysml/validation/18-Use Case/18-Use Case.sysml new file mode 100644 index 00000000..8554bb0d --- /dev/null +++ b/test-data/sysml2/official/sysml/validation/18-Use Case/18-Use Case.sysml @@ -0,0 +1,89 @@ +package '18-Use Case' { + + part def Vehicle; + part def Person; + part def Environment; + part def 'Fuel Station'; + + use case 'provide transportation' { + subject vehicle : Vehicle; + + actor driver : Person; + actor passengers : Person[0..4]; + actor environment : Environment; + + objective { + doc + /* Satisfy mission requirements to transport driver and passengers + * from starting location to ending location in conformance with + * the driving profile and meet the mission requirements for safety, + * reliability, comfort, and affordability. + */ + } + + ref :>> start { + doc /* Mock-up of a pre-condition. */ + assert constraint { + doc /* Vehicle at starting location */ + } + } + + first start; + + then include 'enter vehicle' { + subject; + actor :>> driver = 'provide transportation'::driver; + actor :>> passengers = 'provide transportation'::passengers; + } + + then use case 'drive vehicle' { + include 'add fuel'[0..*] { + doc + /* + * Mock-up of an extension point. + * (But reference to 'add fuel' is in the wrong direction, and it doesn't + * make the extension condition sufficient to trigger the behavior.) + */ + subject; + actor :>> fueler = driver; + ref :>> start { + doc /* Fuel level < 10% max fuel */ + } + } + } + + then include 'exit vehicle' { + subject; + actor :>> driver = 'provide transportation'::driver; + actor :>> passengers = 'provide transportation'::passengers; + } + + then done; + + ref :>> done { + doc /* Mock-up of a post-condition. */ + assert constraint { + doc /* Vehicle at ending location */ + } + } + + } + + use case 'enter vehicle' { + subject vehicle : Vehicle; + actor driver : Person; + actor passengers : Person[0..4]; + } + + use case 'exit vehicle' { + subject vehicle : Vehicle; + actor driver : Person; + actor passengers : Person[0..4]; + } + + use case 'add fuel' { + subject vehicle : Vehicle; + actor fueler : Person; + actor 'fuel station' : 'Fuel Station'; + } +} \ No newline at end of file diff --git a/tools/vendor-sysml2-corpus.sh b/tools/vendor-sysml2-corpus.sh new file mode 100755 index 00000000..4f84f9af --- /dev/null +++ b/tools/vendor-sysml2-corpus.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Re-vendor the official SysML v2 corpus at a pinned commit. +# +# Replaces test-data/sysml2/download-official-suite.sh, which fetched from +# `master` through the GitHub contents API with `|| true` on every download and +# a hardcoded fallback list when the API call failed. Three problems, all of +# which this script exists to not have: +# +# 1. UNPINNED. Upstream still ships monthly incremental grammar tags, so the +# corpus — and therefore every parse rate measured against it — moved +# under us between runs. +# 2. FAILURE READ AS SUCCESS. `curl ... || echo SKIP` means a network blip +# silently produces a SMALLER corpus, and a smaller corpus of +# still-failing files reads as a BETTER parse rate. The error path yielded +# the flattering answer. +# 3. NEVER RUN. The directories it targeted were empty, so the vacuous +# conformance suite was measuring 43 fixtures we wrote ourselves. +# +# Usage: +# tools/vendor-sysml2-corpus.sh # re-vendor at the recorded pin +# tools/vendor-sysml2-corpus.sh # move the pin, deliberately +# +# Moving the pin is a reviewable change: it will move the count that +# crates/spar-sysml2/tests/official_corpus.rs asserts, and that test names both +# constants when it fails. + +set -euo pipefail + +REPO="https://github.com/Systems-Modeling/SysML-v2-Release" +PIN="29a3d2acdd49600cff872e7a55962a40400f3335" +[ $# -ge 1 ] && PIN="$1" + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +DST="${ROOT}/test-data/sysml2/official" +WORK="$(mktemp -d)" +trap 'rm -rf "${WORK}"' EXIT + +echo "== vendoring the official SysML v2 corpus ==" +echo " upstream: ${REPO}" +echo " pin: ${PIN}" + +git clone --quiet "${REPO}" "${WORK}/up" +git -C "${WORK}/up" checkout --quiet "${PIN}" + +GOT="$(git -C "${WORK}/up" rev-parse HEAD)" +if [ "${GOT}" != "${PIN}" ]; then + echo "::error::asked for ${PIN}, checked out ${GOT}" >&2 + exit 1 +fi + +rm -rf "${DST}" +mkdir -p "${DST}" +cp "${WORK}/up/LICENSE" "${DST}/LICENSE" + +# Source models only. The rest of the 366 MB upstream tree is the Xtext pilot +# implementation, its Eclipse plugins, jars and IDE state — none of it is model +# source and none of it grades a parser. +# +# NOTE: paths in this corpus contain spaces ("Address Book Example/"). Every +# loop below is null-delimited for that reason; a `for f in $(find ...)` here +# word-splits them into fragments that do not exist. That mistake inflated the +# measured failure count twice before it was caught. +total=0 +for pair in \ + "sysml/src/validation:sysml/validation" \ + "sysml/src/training:sysml/training" \ + "sysml/src/examples:sysml/examples" \ + "kerml/src/validation:kerml/validation" \ + "kerml/src/examples:kerml/examples" +do + src="${WORK}/up/${pair%%:*}" + rel="${pair##*:}" + [ -d "${src}" ] || continue + n=0 + while IFS= read -r -d '' f; do + out="${DST}/${rel}/${f#./}" + mkdir -p "$(dirname "${out}")" + cp "${f}" "${out}" + n=$((n + 1)) + done < <(cd "${src}" && find . \( -name '*.sysml' -o -name '*.kerml' \) -print0) + printf ' %-20s %4d files\n' "${rel}" "${n}" + total=$((total + n)) +done + +echo " TOTAL ${total} files" + +# A vendoring run that copied nothing must not exit 0 — that is the same +# error-path-yields-the-ideal-reading shape the old script had. +if [ "${total}" -eq 0 ]; then + echo "::error::vendored 0 model files — refusing to leave an empty corpus" >&2 + exit 1 +fi + +echo +echo "Now update, together:" +echo " * test-data/sysml2/PROVENANCE.md — the pin and the file counts" +echo " * crates/spar-sysml2/tests/official_corpus.rs — OFFICIAL_TOTAL, and" +echo " OFFICIAL_PARSING if the parse count moved" +echo +echo " cargo test -p spar-sysml2 --test official_corpus"