#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
#![allow(dead_code)]
use wasm4pm_compat::powl::{
assert_tree_projectable, AcyclicPartialOrder, Choice, Loop, OrderEdge, PartialOrder, Powl,
PowlChoiceNode, PowlNode, PowlNodeId, PowlNodeKind, PowlRefusal, ProcessTreeProjectable,
TypedPowlLoopNode,
};
use wasm4pm_compat::process_tree::{
ProcessTree, ProcessTreeNode, ProcessTreeNodeId, ProcessTreeOperator, TypedAndNode,
TypedLoopNode, TypedSeqNode, TypedXorNode,
};
fn main() {
demo_process_tree_projectable_gate();
demo_powl_partial_order_witness();
demo_powl_choice_construction();
demo_typed_loop_arity();
demo_process_tree_operators();
println!("All POWL and process tree shape demonstrations passed.");
}
fn demo_process_tree_projectable_gate() {
let marker = ProcessTreeProjectable;
let passed = assert_tree_projectable(marker);
assert!(
passed,
"ProcessTreeProjectable must pass the tree-projectable gate"
);
println!("[1] ProcessTreeProjectable gate: ok");
}
fn demo_powl_partial_order_witness() {
let node_a = PowlNodeId(0);
let node_b = PowlNodeId(1);
let po_node: PowlNode<PartialOrder> = PowlNode::new(
PowlNodeId(2),
PowlNodeKind::PartialOrder(vec![node_a, node_b]),
);
assert_eq!(po_node.id, PowlNodeId(2));
let edge = OrderEdge::new(node_a, node_b);
assert_eq!(edge.from, node_a);
assert_eq!(edge.to, node_b);
let acyclic = AcyclicPartialOrder;
let _ = acyclic;
let mut model = Powl::new();
model
.nodes
.push(PowlNode::new(node_a, PowlNodeKind::Atom("A".into())));
model
.nodes
.push(PowlNode::new(node_b, PowlNodeKind::Atom("B".into())));
model.nodes.push(PowlNode::new(po_node.id, po_node.kind));
model.edges.push(edge);
model.root = Some(PowlNodeId(2));
assert_eq!(model.node_count(), 3);
println!(
"[2] POWL partial order witness: ok (nodes={}, edges={})",
model.node_count(),
model.edges.len()
);
}
fn demo_powl_choice_construction() {
let choice = PowlChoiceNode::new(vec![PowlNodeId(0), PowlNodeId(1)]);
assert!(choice.is_well_formed());
assert_eq!(choice.branch_count(), 2);
assert!(choice.validate().is_ok());
let bad = PowlChoiceNode::new(vec![PowlNodeId(0)]);
assert!(!bad.is_well_formed());
assert_eq!(bad.validate(), Err(PowlRefusal::InvalidChoice));
let choice_node: PowlNode<Choice> = PowlNode::new(
PowlNodeId(2),
PowlNodeKind::Choice(vec![PowlNodeId(0), PowlNodeId(1)]),
);
assert_eq!(choice_node.id, PowlNodeId(2));
println!("[3] POWL choice construction: ok");
}
fn demo_typed_loop_arity() {
let loop_node: TypedLoopNode<[&str; 2], 2> = TypedLoopNode::new(["do_body", "redo_branch"]);
assert_eq!(loop_node.children[0], "do_body");
assert_eq!(loop_node.children[1], "redo_branch");
let powl_loop: TypedPowlLoopNode<[&str; 2], 2> =
TypedPowlLoopNode::new(["do_body", "redo_branch"]);
assert_eq!(powl_loop.children[0], "do_body");
let loop_kind_node: PowlNode<Loop> = PowlNode::new(
PowlNodeId(10),
PowlNodeKind::Loop {
body: PowlNodeId(8),
redo: Some(PowlNodeId(9)),
},
);
assert_eq!(loop_kind_node.id, PowlNodeId(10));
println!(
"[4] Typed loop arity enforcement: ok (loop_node.children={:?})",
loop_node.children
);
}
fn demo_process_tree_operators() {
let xor: TypedXorNode<[&str; 2], 2> = TypedXorNode::new(["branch_a", "branch_b"]);
assert_eq!(xor.children.len(), 2);
let and: TypedAndNode<[&str; 3], 3> = TypedAndNode::new(["left", "mid", "right"]);
assert_eq!(and.children.len(), 3);
let seq: TypedSeqNode<[&str; 2], 2> = TypedSeqNode::new(["first", "second"]);
assert_eq!(seq.children[0], "first");
let mut tree = ProcessTree::new();
tree.nodes.push(ProcessTreeNode::Activity("a".into()));
tree.nodes.push(ProcessTreeNode::Activity("b".into()));
tree.nodes.push(ProcessTreeNode::Operator {
operator: ProcessTreeOperator::Sequence,
children: vec![ProcessTreeNodeId(0), ProcessTreeNodeId(1)],
});
tree.root = Some(ProcessTreeNodeId(2));
assert_eq!(tree.admit_shape(), Ok(()));
let xor_op = ProcessTreeOperator::Xor;
let and_op = ProcessTreeOperator::Parallel;
let seq_op = ProcessTreeOperator::Sequence;
assert_ne!(xor_op, and_op);
assert_ne!(and_op, seq_op);
println!(
"[5] ProcessOperator shapes: Xor={:?}, And={:?}, Seq={:?} — tree admit_shape=ok",
xor_op, and_op, seq_op
);
}