108 lines
6.6 KiB
Rust
108 lines
6.6 KiB
Rust
//! Actual oa-core fixtures for issue 21. Source-only contribution; NOT compiled/run.
|
|
//! Link to the current oa_core rlib, then run with a NEW output directory argument.
|
|
//! Draw/paint/hit verification belongs to the production desktop, not this probe.
|
|
use oa_core::*;
|
|
use std::{fs, path::Path};
|
|
|
|
fn id(n: u128) -> Id { Id::from_u128(0x21ca1100000040008000000000000000 + n) }
|
|
fn seed(p: &mut Project, layer: Layer, n: u128, kind: Kind, name: &str, parent: Option<Id>) -> Id {
|
|
let mut e = p.make_element(kind, layer, name, parent).unwrap();
|
|
e.id = id(n);
|
|
e.alias = format!("activation_{n}");
|
|
let result = e.id;
|
|
assert!(p.elements.insert(result, e).is_none());
|
|
result
|
|
}
|
|
fn occurrence(p: &mut Project, layer: Layer, n: u128, name: &str, parent: Id, body: OccurrenceBody) -> Id {
|
|
let result = seed(p, layer, n, Kind::Occurrence, name, Some(parent));
|
|
*p.elements.get_mut(&result).unwrap().shared_mut().unwrap() = SharedBody::Occurrence {
|
|
body, precondition: String::new(), postcondition: String::new(),
|
|
};
|
|
result
|
|
}
|
|
fn message(p: &mut Project, layer: Layer, n: u128, name: &str, parent: Id, sender: Id, receiver: Id, reply: Option<Id>) -> Id {
|
|
occurrence(p, layer, n, name, parent, OccurrenceBody::Exchange {
|
|
operation: None, exchange: None, sender: Some(sender), receiver: Some(receiver),
|
|
message_kind: if reply.is_some() { MessageKind::Reply } else { MessageKind::Call },
|
|
reply_to: reply, values: vec![],
|
|
})
|
|
}
|
|
fn steps(p: &mut Project, owner: Id, values: Vec<Id>) {
|
|
*p.elements.get_mut(&owner).unwrap().steps_mut().unwrap() = values;
|
|
}
|
|
fn main() {
|
|
let args: Vec<_> = std::env::args().collect();
|
|
assert_eq!(args.len(), 2, "Pass a NEW output directory");
|
|
let directory = Path::new(&args[1]);
|
|
assert!(!directory.exists(), "Preserve existing evidence; use a fresh directory");
|
|
let mut p = Project::empty();
|
|
p.id = id(1);
|
|
p.alias = "nested_call_evaluator".into();
|
|
p.name = "Nested call activation evaluator".into();
|
|
p.description = "Draft exchange references intentionally absent; exact lifelines and correlations isolate receiver activation geometry.".into();
|
|
for (side, layer) in [(0u128, Layer::Oa), (1, Layer::Sa)] {
|
|
let base = 10000 + side * 10000;
|
|
let work_kind = if layer == Layer::Oa { Kind::Activity } else { Kind::Function };
|
|
let a = seed(&mut p, layer, base, work_kind, "Caller work", None);
|
|
let b = seed(&mut p, layer, base + 1, work_kind, "Callee work", None);
|
|
for (case_index, case) in ["nested", "sequential", "crossed", "self", "reentrant", "open", "alt", "parallel"].iter().enumerate() {
|
|
let n = base + 100 + case_index as u128 * 100;
|
|
let owner = seed(&mut p, layer, n, Kind::Scenario, &format!("{layer:?} {case}"), None);
|
|
if let SharedBody::Scenario { viewpoint, .. } = p.elements.get_mut(&owner).unwrap().shared_mut().unwrap() {
|
|
*viewpoint = if layer == Layer::Oa { ScenarioViewpoint::OperationalActivity } else { ScenarioViewpoint::Functional };
|
|
}
|
|
let l1 = seed(&mut p, layer, n + 1, Kind::Lifeline, "L1 Caller", Some(owner));
|
|
let l2 = seed(&mut p, layer, n + 2, Kind::Lifeline, "L2 Callee", Some(owner));
|
|
for (line, represented) in [(l1, a), (l2, b)] {
|
|
*p.elements.get_mut(&line).unwrap().shared_mut().unwrap() = SharedBody::Lifeline { represented: Some(represented) };
|
|
}
|
|
// Deliberately reverse Call UUID order compared with semantic order.
|
|
let c1 = message(&mut p, layer, n + 40, "Call 1", owner, l1, l2, None);
|
|
if *case == "alt" || *case == "parallel" {
|
|
let operator = if *case == "alt" { FragmentOperator::Alternative } else { FragmentOperator::Parallel };
|
|
let fragment = occurrence(&mut p, layer, n + 10, case, owner, OccurrenceBody::Fragment { operator, branches: vec![id(n + 11), id(n + 12)] });
|
|
for branch_index in 0..2u128 {
|
|
let branch = occurrence(&mut p, layer, n + 11 + branch_index, &format!("Operand {branch_index}"), fragment, OccurrenceBody::Branch {
|
|
guard: format!("condition_{branch_index}"), occurrences: vec![],
|
|
});
|
|
let local = message(&mut p, layer, n + 20 + branch_index * 3, "Branch Call", branch, l1, l2, None);
|
|
let local_reply = message(&mut p, layer, n + 21 + branch_index * 3, "Branch Reply", branch, l2, l1, Some(local));
|
|
let mut branch_steps = vec![local, local_reply];
|
|
if *case == "alt" && branch_index == 0 {
|
|
let reply = message(&mut p, layer, n + 70, "Conditional outer Reply", branch, l2, l1, Some(c1));
|
|
branch_steps.push(reply);
|
|
}
|
|
steps(&mut p, branch, branch_steps);
|
|
}
|
|
steps(&mut p, owner, vec![c1, fragment]);
|
|
continue;
|
|
}
|
|
let (from, to) = match *case { "self" => (l2, l2), "reentrant" => (l2, l1), _ => (l1, l2) };
|
|
let c2 = message(&mut p, layer, n + 30, "Call 2", owner, from, to, None);
|
|
let r2 = message(&mut p, layer, n + 60, "Reply 2 to Call 2", owner, to, from, Some(c2));
|
|
let r1 = message(&mut p, layer, n + 50, "Reply 1 to Call 1", owner, l2, l1, Some(c1));
|
|
let ordered = match *case {
|
|
"sequential" => vec![c1, r1, c2, r2],
|
|
"crossed" => vec![c1, c2, r1, r2],
|
|
"open" => { p.elements.remove(&r1); vec![c1, c2, r2] },
|
|
_ => vec![c1, c2, r2, r1],
|
|
};
|
|
steps(&mut p, owner, ordered);
|
|
}
|
|
}
|
|
let issues = validation::validate(&p);
|
|
let errors: Vec<_> = issues.iter().filter(|i| i.severity == validation::Severity::Error).collect();
|
|
assert!(errors.is_empty(), "Core fixture errors: {errors:#?}");
|
|
let canonical = language::format(&p);
|
|
let reparsed = language::parse(&canonical).expect("Actual canonical source must parse");
|
|
assert_eq!(language::format(&reparsed), canonical, "Canonical source round trip");
|
|
assert_eq!(reparsed.elements.len(), p.elements.len());
|
|
for (uuid, element) in &p.elements {
|
|
assert_eq!(reparsed.elements[uuid].steps(), element.steps(), "Exact ordered steps for {uuid}");
|
|
}
|
|
fs::create_dir_all(directory).unwrap();
|
|
fs::write(directory.join("nested-call-evaluator.arcadia"), canonical).unwrap();
|
|
fs::write(directory.join("diagnostics.txt"), format!("{issues:#?}\n")).unwrap();
|
|
println!("PASS actual core validation and canonical round trip: {} elements, {} warnings; no desktop draw/hit/runtime claim", p.elements.len(), issues.len());
|
|
}
|