boolean_logic_demo/
boolean_logic_demo.rs1use zelen::parse;
2use zelen::translator::Translator;
3
4fn main() {
5 println!("=== Boolean Logic and Advanced Features Demo ===\n");
6
7 example_boolean_and_or();
9 println!("\n{}\n", "=".repeat(60));
10
11 example_boolean_not();
13 println!("\n{}\n", "=".repeat(60));
14
15 example_boolean_implication();
17 println!("\n{}\n", "=".repeat(60));
18
19 example_float_arithmetic();
21 println!("\n{}\n", "=".repeat(60));
22
23 example_array_indexing();
25
26 println!("\n=== Demo Complete ===");
27}
28
29fn example_boolean_and_or() {
30 println!("Example 1: Boolean AND and OR");
31
32 let source = r#"
33 var bool: lights_on;
34 var bool: door_open;
35 var bool: alarm_active;
36
37 % Alarm is active if lights are on AND door is open
38 constraint alarm_active <-> (lights_on /\ door_open);
39
40 % At least one safety feature must be active
41 constraint lights_on \/ alarm_active;
42
43 solve satisfy;
44 "#;
45
46 println!("MiniZinc Source:\n{}", source);
47
48 match parse(source) {
49 Ok(ast) => {
50 match Translator::translate_with_vars(&ast) {
51 Ok(model_data) => {
52 println!("✓ Translated to Selen Model");
53
54 match model_data.model.solve() {
55 Ok(solution) => {
56 println!("✓ Solution found!");
57
58 for (name, &var_id) in &model_data.bool_vars {
59 if let selen::variables::Val::ValI(val) = solution[var_id] {
60 println!(" {} = {}", name, val != 0);
61 }
62 }
63 }
64 Err(e) => println!("✗ No solution: {:?}", e),
65 }
66 }
67 Err(e) => println!("✗ Translation error: {:?}", e),
68 }
69 }
70 Err(e) => println!("✗ Parse error: {:?}", e),
71 }
72}
73
74fn example_boolean_not() {
75 println!("Example 2: Boolean NOT");
76
77 let source = r#"
78 var bool: system_enabled;
79 var bool: maintenance_mode;
80
81 % System is enabled only when NOT in maintenance mode
82 constraint system_enabled <-> not maintenance_mode;
83
84 % Must be in one of the two states
85 constraint system_enabled \/ maintenance_mode;
86
87 solve satisfy;
88 "#;
89
90 println!("MiniZinc Source:\n{}", source);
91
92 match parse(source) {
93 Ok(ast) => {
94 match Translator::translate_with_vars(&ast) {
95 Ok(model_data) => {
96 println!("✓ Translated to Selen Model");
97
98 match model_data.model.solve() {
99 Ok(solution) => {
100 println!("✓ Solution found!");
101
102 for (name, &var_id) in &model_data.bool_vars {
103 if let selen::variables::Val::ValI(val) = solution[var_id] {
104 println!(" {} = {}", name, val != 0);
105 }
106 }
107 }
108 Err(e) => println!("✗ No solution: {:?}", e),
109 }
110 }
111 Err(e) => println!("✗ Translation error: {:?}", e),
112 }
113 }
114 Err(e) => println!("✗ Parse error: {:?}", e),
115 }
116}
117
118fn example_boolean_implication() {
119 println!("Example 3: Boolean Implication");
120
121 let source = r#"
122 var bool: raining;
123 var bool: umbrella;
124 var bool: wet;
125
126 % If it's raining and no umbrella, then you get wet
127 constraint (raining /\ not umbrella) -> wet;
128
129 % If you have umbrella, you don't get wet
130 constraint umbrella -> not wet;
131
132 % It is raining
133 constraint raining;
134
135 solve satisfy;
136 "#;
137
138 println!("MiniZinc Source:\n{}", source);
139
140 match parse(source) {
141 Ok(ast) => {
142 match Translator::translate_with_vars(&ast) {
143 Ok(model_data) => {
144 println!("✓ Translated to Selen Model");
145
146 match model_data.model.solve() {
147 Ok(solution) => {
148 println!("✓ Solution found!");
149
150 for (name, &var_id) in &model_data.bool_vars {
151 if let selen::variables::Val::ValI(val) = solution[var_id] {
152 println!(" {} = {}", name, val != 0);
153 }
154 }
155 }
156 Err(e) => println!("✗ No solution: {:?}", e),
157 }
158 }
159 Err(e) => println!("✗ Translation error: {:?}", e),
160 }
161 }
162 Err(e) => println!("✗ Parse error: {:?}", e),
163 }
164}
165
166fn example_float_arithmetic() {
167 println!("Example 4: Float Arithmetic in Constraints");
168
169 let source = r#"
170 var 0.0..100.0: price;
171 var 0.0..1.0: tax_rate;
172 var 0.0..150.0: total;
173
174 % Total is price plus tax
175 constraint total = price + (price * tax_rate);
176
177 % Total must be under budget
178 constraint total <= 100.0;
179
180 % Reasonable tax rate
181 constraint tax_rate >= 0.05;
182 constraint tax_rate <= 0.20;
183
184 solve satisfy;
185 "#;
186
187 println!("MiniZinc Source:\n{}", source);
188
189 match parse(source) {
190 Ok(ast) => {
191 match Translator::translate_with_vars(&ast) {
192 Ok(model_data) => {
193 println!("✓ Translated to Selen Model");
194
195 match model_data.model.solve() {
196 Ok(solution) => {
197 println!("✓ Solution found!");
198
199 for (name, &var_id) in &model_data.float_vars {
200 if let selen::variables::Val::ValF(val) = solution[var_id] {
201 println!(" {} = {:.2}", name, val);
202 }
203 }
204 }
205 Err(e) => println!("✗ No solution: {:?}", e),
206 }
207 }
208 Err(e) => println!("✗ Translation error: {:?}", e),
209 }
210 }
211 Err(e) => println!("✗ Parse error: {:?}", e),
212 }
213}
214
215fn example_array_indexing() {
216 println!("Example 5: Array Indexing in Constraints");
217
218 let source = r#"
219 array[1..5] of var 1..10: values;
220
221 % First element must be less than 5
222 constraint values[1] < 5;
223
224 % Third element must be greater than 5
225 constraint values[3] > 5;
226
227 % Fifth element must equal first element plus second
228 constraint values[5] = values[1] + values[2];
229
230 solve satisfy;
231 "#;
232
233 println!("MiniZinc Source:\n{}", source);
234
235 match parse(source) {
236 Ok(ast) => {
237 match Translator::translate_with_vars(&ast) {
238 Ok(model_data) => {
239 println!("✓ Translated to Selen Model");
240
241 let model = model_data.model;
242 match model.solve() {
243 Ok(solution) => {
244 println!("✓ Solution found!");
245
246 if let Some(values_arr) = model_data.int_var_arrays.get("values") {
248 print!(" values = [");
249 for (i, var_id) in values_arr.iter().enumerate() {
250 if i > 0 {
251 print!(", ");
252 }
253 print!("{}", solution.get_int(*var_id));
254 }
255 println!("]");
256 }
257 }
258 Err(e) => println!("✗ No solution: {:?}", e),
259 }
260 }
261 Err(e) => println!("✗ Translation error: {:?}", e),
262 }
263 }
264 Err(e) => println!("✗ Parse error: {:?}", e),
265 }
266}