diff --git a/CHANGELOG.md b/CHANGELOG.md index d370d5e..e9bb60e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixed + +- `validateStateDefinitionParallelSubactions` and `validateStateUsageParallelSubactions` report only transitions in a parallel state, not successions: SysML 8.3.18.5 and 8.3.18.6 forbid incoming and outgoing transitions of the substates, and 7.18.2 and 7.18.3 say the same. The Pilot Implementation also rejects a succession there; the opensysml fixtures `s33-parallel-state-usage-with-succession` and `p19-parallel-state-with-transition`, which hold a succession and no transition, move to unknown in both baselines. + ## v0.11.3 ### Added diff --git a/crates/sysmlv2-model/src/check.rs b/crates/sysmlv2-model/src/check.rs index da39904..59ce3bc 100644 --- a/crates/sysmlv2-model/src/check.rs +++ b/crates/sysmlv2-model/src/check.rs @@ -1168,6 +1168,29 @@ mod tests { assert_eq!(shown(&on_threads), shown(&in_line)); } + /// SysML 8.3.18.5 validateStateDefinitionParallelSubactions and + /// 8.3.18.6 validateStateUsageParallelSubactions forbid transitions of + /// the substates of a parallel state, not successions (7.18.2). + #[test] + fn a_parallel_state_may_own_successions() { + let mut model = Model::new(); + model.add_source( + "user.sysml", + "package P { + state def S parallel { state a; state b; first a then b; } + state t parallel { state a; state b; first a then b; } + state def T parallel { state a; state b; transition first a then b; } + state u parallel { state a; state b; transition first a then b; } + }", + ); + let found: Vec = findings(&model) + .into_iter() + .map(|(_, m)| m) + .filter(|m| m.contains("ParallelSubactions")) + .collect(); + assert_eq!(found.len(), 2, "{found:?}"); + } + #[test] fn semantic_checks_walk_tables_without_copying_them() { // Fresh build: library rows and user rows share one storage. diff --git a/crates/sysmlv2-model/src/check/structural.rs b/crates/sysmlv2-model/src/check/structural.rs index 3750e77..9cc1a61 100644 --- a/crates/sysmlv2-model/src/check/structural.rs +++ b/crates/sysmlv2-model/src/check/structural.rs @@ -582,9 +582,9 @@ pub(super) fn validate(r: &ResolvedModel, model: &Model, g: &Facts) -> Vec<(usiz } } if flag(b, e, "isParallel") - && g.members[e].iter().any(|&m| { - is_a!(b.elements[m], "TransitionUsage") || is_a!(b.elements[m], "Succession") - }) + && g.members[e] + .iter() + .any(|&m| is_a!(b.elements[m], "TransitionUsage")) { report( e, @@ -594,7 +594,7 @@ pub(super) fn validate(r: &ResolvedModel, model: &Model, g: &Facts) -> Vec<(usiz } else { "validateStateUsageParallelSubactions" }, - "A parallel state cannot own successions or transitions", + "A parallel state cannot own transitions", ); } } diff --git a/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline-library.json b/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline-library.json index b0e256d..b9ae2d2 100644 --- a/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline-library.json +++ b/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline-library.json @@ -2702,16 +2702,8 @@ "status": "diagnostic baseline" }, "negative/semantic/s33-parallel-state-usage-with-succession.sysml": { - "diagnostics": [ - { - "end": 196, - "message": "A parallel state cannot own successions or transitions [validateStateUsageParallelSubactions]", - "severity": "Error", - "stage": "semantics", - "start": 195 - } - ], - "status": "diagnostic baseline" + "diagnostics": [], + "status": "unknown" }, "negative/semantic/s34-state-usage-two-entry-actions.sysml": { "diagnostics": [ @@ -3422,16 +3414,8 @@ "status": "accepted (adjudicated)" }, "negative/xpect/p19-parallel-state-with-transition.sysml": { - "diagnostics": [ - { - "end": 215, - "message": "A parallel state cannot own successions or transitions [validateStateDefinitionParallelSubactions]", - "severity": "Error", - "stage": "semantics", - "start": 214 - } - ], - "status": "diagnostic baseline" + "diagnostics": [], + "status": "unknown" }, "negative/xpect/p20-connection-with-one-end.sysml": { "diagnostics": [ @@ -5416,7 +5400,7 @@ "diagnostics": [ { "end": 151, - "message": "A parallel state cannot own successions or transitions [validateStateDefinitionParallelSubactions]", + "message": "A parallel state cannot own transitions [validateStateDefinitionParallelSubactions]", "severity": "Error", "stage": "semantics", "start": 150 @@ -5452,7 +5436,7 @@ "diagnostics": [ { "end": 156, - "message": "A parallel state cannot own successions or transitions [validateStateUsageParallelSubactions]", + "message": "A parallel state cannot own transitions [validateStateUsageParallelSubactions]", "severity": "Error", "stage": "semantics", "start": 155 diff --git a/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline.json b/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline.json index e5e723b..b87ca3f 100644 --- a/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline.json +++ b/crates/sysmlv2-parser/tests/fixtures/opensysml/baseline.json @@ -2744,16 +2744,8 @@ "status": "diagnostic baseline" }, "negative/semantic/s33-parallel-state-usage-with-succession.sysml": { - "diagnostics": [ - { - "end": 196, - "message": "A parallel state cannot own successions or transitions [validateStateUsageParallelSubactions]", - "severity": "Error", - "stage": "semantics", - "start": 195 - } - ], - "status": "diagnostic baseline" + "diagnostics": [], + "status": "unknown without library" }, "negative/semantic/s34-state-usage-two-entry-actions.sysml": { "diagnostics": [ @@ -3569,16 +3561,8 @@ "status": "accepted (adjudicated)" }, "negative/xpect/p19-parallel-state-with-transition.sysml": { - "diagnostics": [ - { - "end": 215, - "message": "A parallel state cannot own successions or transitions [validateStateDefinitionParallelSubactions]", - "severity": "Error", - "stage": "semantics", - "start": 214 - } - ], - "status": "diagnostic baseline" + "diagnostics": [], + "status": "unknown without library" }, "negative/xpect/p20-connection-with-one-end.sysml": { "diagnostics": [ @@ -5878,7 +5862,7 @@ "diagnostics": [ { "end": 151, - "message": "A parallel state cannot own successions or transitions [validateStateDefinitionParallelSubactions]", + "message": "A parallel state cannot own transitions [validateStateDefinitionParallelSubactions]", "severity": "Error", "stage": "semantics", "start": 150 @@ -5914,7 +5898,7 @@ "diagnostics": [ { "end": 156, - "message": "A parallel state cannot own successions or transitions [validateStateUsageParallelSubactions]", + "message": "A parallel state cannot own transitions [validateStateUsageParallelSubactions]", "severity": "Error", "stage": "semantics", "start": 155