runtime_api_demo/
runtime_api_demo.rs1use cspsolver::prelude::*;
17
18fn main() {
19 println!("🚀 Runtime Constraint API Demo - Phase 1 & 2");
20 println!("===============================================\n");
21
22 example_1_basic_runtime_building();
24 example_2_dynamic_from_data();
25 example_3_expression_chaining();
26 example_4_constraint_composition();
27
28 example_5_model_c_syntax();
30 example_6_builder_fluent_interface();
31 example_7_global_constraints();
32 example_8_mixed_phase_usage();
33}
34
35fn example_1_basic_runtime_building() {
37 println!("📝 Example 1: Basic Runtime Constraint Building");
38
39 let mut m = Model::default();
40 let x = m.int(0, 10);
41 let y = m.int(0, 10);
42 let z = m.int(0, 20);
43
44 m.post(x.add(y).eq(z)); m.post(x.gt(int(5))); m.post(y.le(int(8))); if let Ok(solution) = m.solve() {
50 println!("✓ Solution found:");
51 println!(" x = {:?}", solution[x]);
52 println!(" y = {:?}", solution[y]);
53 println!(" z = {:?}", solution[z]);
54 } else {
55 println!("❌ No solution found");
56 }
57 println!();
58}
59
60fn example_2_dynamic_from_data() {
62 println!("📝 Example 2: Dynamic Constraints from Data");
63
64 let mut m = Model::default();
65 let x = m.int(0, 10);
66 let y = m.int(0, 10);
67
68 let rules = vec![
70 ("x", "gt", 3), ("y", "le", 7), ("x", "ne", 5), ];
74
75 println!(" Building constraints from data: {:?}", rules);
76
77 for (var_name, op, value) in rules {
78 let var_id = match var_name {
79 "x" => x,
80 "y" => y,
81 _ => continue,
82 };
83
84 let constraint = match op {
85 "gt" => var_id.gt(int(value)),
86 "le" => var_id.le(int(value)),
87 "eq" => var_id.eq(int(value)),
88 "ne" => var_id.ne(int(value)),
89 "ge" => var_id.ge(int(value)),
90 "lt" => var_id.lt(int(value)),
91 _ => {
92 println!(" ⚠️ Unknown operator: {}", op);
93 continue;
94 }
95 };
96
97 m.post(constraint);
98 println!(" ✓ Posted: {} {} {}", var_name, op, value);
99 }
100
101 if let Ok(solution) = m.solve() {
102 println!("✓ Solution found:");
103 println!(" x = {:?}", solution[x]);
104 println!(" y = {:?}", solution[y]);
105 } else {
106 println!("❌ No solution found");
107 }
108 println!();
109}
110
111fn example_3_expression_chaining() {
113 println!("📝 Example 3: Expression Chaining");
114
115 let mut m = Model::default();
116 let a = m.int(1, 10); let b = m.int(1, 10); let result = m.int(0, 100); m.post(a.eq(int(5))); m.post(b.eq(int(5))); m.post(result.eq(int(10))); if let Ok(solution) = m.solve() {
126 println!("✓ Found simple values:");
127 println!(" a = {:?}", solution[a]);
128 println!(" b = {:?}", solution[b]);
129 println!(" result = {:?}", solution[result]);
130 } else {
131 println!("❌ No solution found");
132 }
133 println!();
134}
135
136fn example_4_constraint_composition() {
138 println!("📝 Example 4: Constraint Composition");
139
140 let mut m = Model::default();
141 let x = m.int(0, 20);
142 let y = m.int(0, 20);
143
144 let c1 = x.gt(int(5)); let c2 = x.lt(int(15)); let c3 = y.ge(int(10)); let range_constraint = c1.and(c2);
151 let combined = range_constraint.and(c3);
152
153 m.post(combined);
154
155 if let Ok(solution) = m.solve() {
156 println!("✓ Solution with composed constraints:");
157 println!(" x = {:?} (should be 6-14)", solution[x]);
158 println!(" y = {:?} (should be >= 10)", solution[y]);
159 } else {
160 println!("❌ No solution found");
161 }
162 println!();
163}
164
165fn example_5_model_c_syntax() {
169 println!("📝 Example 5: Model::c() Ultra-Short Syntax (Phase 2)");
170
171 let mut m = Model::default();
172 let x = m.int(1, 10);
173 let y = m.int(1, 10);
174 let sum = m.int(2, 20);
175
176 m.c(x).gt(int(3)); m.c(y).le(int(8)); m.c(x).add(y).eq(sum); m.c(sum).eq(int(12)); if let Ok(solution) = m.solve() {
183 println!("✓ Solution found:");
184 println!(" x = {:?}", solution[x]);
185 println!(" y = {:?}", solution[y]);
186 println!(" sum = {:?}", solution[sum]);
187 } else {
188 println!("❌ No solution found");
189 }
190 println!();
191}
192
193fn example_6_builder_fluent_interface() {
195 println!("📝 Example 6: Builder Fluent Interface (Phase 2)");
196
197 let mut m = Model::default();
198 let a = m.int(0, 20);
199 let b = m.int(0, 20);
200 let result = m.int(0, 100);
201
202 m.c(a).mul(int(3)).add(int(5)).le(int(50)); m.c(b).div(int(2)).sub(int(1)).ge(int(2)); m.c(a).add(b).mul(int(2)).eq(result); m.c(result).ne(int(20)); if let Ok(solution) = m.solve() {
209 println!("✓ Complex fluent constraints satisfied:");
210 println!(" a = {:?}", solution[a]);
211 println!(" b = {:?}", solution[b]);
212 println!(" result = {:?}", solution[result]);
213 } else {
214 println!("❌ No solution found");
215 }
216 println!();
217}
218
219fn example_7_global_constraints() {
221 println!("📝 Example 7: Global Constraint Shortcuts (Phase 2)");
222
223 let mut m = Model::default();
224 let digits = (0..4).map(|_| m.int(1, 4)).collect::<Vec<_>>();
225
226 m.alldiff(&digits); m.c(digits[0]).gt(digits[1]); m.c(digits[2]).add(digits[3]).eq(int(5)); if let Ok(solution) = m.solve() {
232 println!("✓ Global constraint solution:");
233 for (i, &digit) in digits.iter().enumerate() {
234 println!(" digit[{}] = {:?}", i, solution[digit]);
235 }
236 } else {
237 println!("❌ No solution found");
238 }
239 println!();
240}
241
242fn example_8_mixed_phase_usage() {
244 println!("📝 Example 8: Mixed Phase 1 & 2 Usage");
245
246 let mut m = Model::default();
247 let x = m.int(1, 10);
248 let y = m.int(1, 10);
249 let z = m.int(1, 10);
250
251 let constraint1 = x.add(y).gt(int(5));
253 m.post(constraint1);
254
255 m.c(y).mul(int(2)).le(z.add(int(3)));
257
258 m.alldiff(&[x, y, z]);
260
261 let c1 = x.lt(int(8));
263 let c2 = y.ge(int(2));
264 let combined = c1.and(c2);
265 m.post(combined);
266
267 if let Ok(solution) = m.solve() {
268 println!("✓ Mixed API solution:");
269 println!(" x = {:?}", solution[x]);
270 println!(" y = {:?}", solution[y]);
271 println!(" z = {:?}", solution[z]);
272 } else {
273 println!("❌ No solution found");
274 }
275 println!();
276}