Files
ARCADIA-Studio/harness/experiments/canvas-editing-followup-20260912/draft-fixture.rs
T

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());
}