cycle_detection/
cycle_detection.rs1use zzstat::source::ConstantSource;
8use zzstat::transform::ScalingTransform;
9use zzstat::*;
10
11fn main() {
12 let mut resolver = StatResolver::new();
13
14 let a_id = StatId::from_str("A");
16 let b_id = StatId::from_str("B");
17 let c_id = StatId::from_str("C");
18
19 println!("=== Setting up circular dependencies ===\n");
20
21 resolver.register_source(a_id.clone(), Box::new(ConstantSource(10.0)));
23 resolver.register_transform(
24 a_id.clone(),
25 Box::new(ScalingTransform::new(b_id.clone(), 1.0)),
26 );
27 println!("A: 10 (base) + B * 1.0");
28
29 resolver.register_source(b_id.clone(), Box::new(ConstantSource(20.0)));
31 resolver.register_transform(
32 b_id.clone(),
33 Box::new(ScalingTransform::new(c_id.clone(), 1.0)),
34 );
35 println!("B: 20 (base) + C * 1.0");
36
37 resolver.register_source(c_id.clone(), Box::new(ConstantSource(30.0)));
39 resolver.register_transform(
40 c_id.clone(),
41 Box::new(ScalingTransform::new(a_id.clone(), 1.0)),
42 );
43 println!("C: 30 (base) + A * 1.0");
44
45 println!("\n=== Attempting to resolve (should detect cycle) ===\n");
46
47 let context = StatContext::new();
48 match resolver.resolve(&a_id, &context) {
49 Err(StatError::CycleDetected(cycle)) => {
50 println!("ā Cycle detected successfully!");
51 println!("\nCycle path:");
52 for (i, stat_id) in cycle.iter().enumerate() {
53 if i < cycle.len() - 1 {
54 print!("{} -> ", stat_id);
55 } else {
56 println!("{}", stat_id);
57 }
58 }
59 }
60 Err(e) => {
61 println!("ā Unexpected error: {}", e);
62 }
63 Ok(_) => {
64 println!("ā ERROR: Cycle was not detected! This should not happen.");
65 }
66 }
67
68 println!("\n=== Valid dependency chain (no cycle) ===\n");
69
70 let mut resolver2 = StatResolver::new();
72
73 let x_id = StatId::from_str("X");
74 let y_id = StatId::from_str("Y");
75 let z_id = StatId::from_str("Z");
76
77 resolver2.register_source(x_id.clone(), Box::new(ConstantSource(10.0)));
79 println!("X: 10 (base)");
80
81 resolver2.register_source(y_id.clone(), Box::new(ConstantSource(20.0)));
82 resolver2.register_transform(
83 y_id.clone(),
84 Box::new(ScalingTransform::new(x_id.clone(), 1.0)),
85 );
86 println!("Y: 20 (base) + X * 1.0");
87
88 resolver2.register_source(z_id.clone(), Box::new(ConstantSource(30.0)));
89 resolver2.register_transform(
90 z_id.clone(),
91 Box::new(ScalingTransform::new(y_id.clone(), 1.0)),
92 );
93 println!("Z: 30 (base) + Y * 1.0");
94
95 println!("\n=== Resolving valid chain ===\n");
96
97 let results = resolver2.resolve_all(&context).unwrap();
98
99 println!("Results:");
100 println!(" X: {:.2}", results[&x_id].value);
101 println!(" Y: {:.2} (20 + 10)", results[&y_id].value);
102 println!(" Z: {:.2} (30 + 30)", results[&z_id].value);
103
104 println!("\nā Valid dependency chain resolved successfully!");
105}