Skip to main content

boolean_logic_demo/
boolean_logic_demo.rs

1use zelen::parse;
2use zelen::translator::Translator;
3
4fn main() {
5    println!("=== Boolean Logic and Advanced Features Demo ===\n");
6
7    // Example 1: Boolean AND and OR
8    example_boolean_and_or();
9    println!("\n{}\n", "=".repeat(60));
10
11    // Example 2: Boolean NOT
12    example_boolean_not();
13    println!("\n{}\n", "=".repeat(60));
14
15    // Example 3: Boolean Implication
16    example_boolean_implication();
17    println!("\n{}\n", "=".repeat(60));
18
19    // Example 4: Float Arithmetic
20    example_float_arithmetic();
21    println!("\n{}\n", "=".repeat(60));
22
23    // Example 5: Array Indexing
24    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                            // Get the array variable IDs
247                            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}