pub fn parse(source: &str) -> Result<Model>Expand description
Examples found in repository?
examples/simple_constraints.rs (line 17)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let source = r#"
7 var 1..10: x;
8 var 1..10: y;
9
10 constraint x < y;
11 constraint x + y < 15;
12
13 solve satisfy;
14 "#;
15
16 println!("Parsing model with constraints...");
17 let ast = zelen::parse(source)?;
18
19 println!("Translating to Selen Model...");
20 let model = zelen::translate(&ast)?;
21
22 println!("Solving...");
23 match model.solve() {
24 Ok(solution) => {
25 println!("\n✓ Solution found!");
26 println!("{:?}", solution);
27 }
28 Err(e) => {
29 println!("No solution found: {:?}", e);
30 }
31 }
32
33 Ok(())
34}More examples
examples/sudoku.rs (line 9)
3fn main() {
4 let mzn_code = fs::read_to_string("examples/models/sudoku.mzn")
5 .expect("Failed to read sudoku.mzn");
6
7 println!("=== Parsing Sudoku Example ===\n");
8
9 let ast = match zelen::parse(&mzn_code) {
10 Ok(ast) => {
11 println!("✓ Parsing successful!");
12 println!("AST contains {} items", ast.items.len());
13 ast
14 }
15 Err(e) => {
16 println!("✗ Parsing failed: {}", e);
17 std::process::exit(1);
18 }
19 };
20
21 println!("\n=== Translating Sudoku Example ===\n");
22
23 match zelen::translate(&ast) {
24 Ok(_model) => {
25 println!("✓ Translation successful!");
26 println!("Model created successfully with 2D array constraints");
27 }
28 Err(e) => {
29 println!("✗ Translation failed: {}", e);
30 std::process::exit(1);
31 }
32 };
33}examples/boolean_logic_demo.rs (line 48)
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}examples/solve_nqueens.rs (line 15)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // Simple N-Queens model
7 let source = r#"
8 int: n = 4;
9 array[1..n] of var 1..n: queens;
10 constraint alldifferent(queens);
11 solve satisfy;
12 "#;
13
14 println!("Parsing MiniZinc model...");
15 let ast = zelen::parse(source)?;
16 println!("Parsed {} items", ast.items.len());
17
18 println!("\nTranslating to Selen Model...");
19 let translated = zelen::Translator::translate_with_vars(&ast)?;
20 println!("Translation successful!");
21
22 println!("\nSolving...");
23 match translated.model.solve() {
24 Ok(solution) => {
25 println!("✓ Solution found!");
26
27 // Extract and display the queens array values
28 if let Some(queens) = translated.int_var_arrays.get("queens") {
29 print!("\nQueens array: [");
30 for (i, var_id) in queens.iter().enumerate() {
31 if i > 0 { print!(", "); }
32 match solution[*var_id] {
33 selen::variables::Val::ValI(val) => print!("{}", val),
34 _ => print!("?"),
35 }
36 }
37 println!("]");
38
39 println!("\nInterpretation: Queen in row i is placed in column queens[i]");
40 }
41
42 println!("\nSolve stats: {} propagations, {} nodes, {:?}",
43 solution.stats.propagation_count,
44 solution.stats.node_count,
45 solution.stats.solve_time
46 );
47 }
48 Err(e) => {
49 println!("No solution found: {:?}", e);
50 }
51 }
52
53 Ok(())
54}examples/queens4.rs (line 30)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // N-Queens with all constraints
7 // Note: This example currently only has column constraints (alldifferent)
8 // Full N-Queens needs diagonal constraints too:
9 // - queens[i] + i != queens[j] + j (ascending diagonal)
10 // - queens[i] - i != queens[j] - j (descending diagonal)
11 // These will be added when we implement more constraint types
12 let source = r#"
13 int: n = 4;
14 array[1..n] of var 1..n: queens;
15
16 % All queens must be in different rows (implicit from domain)
17 % All queens must be in different columns
18 constraint alldifferent(queens);
19
20 % TODO: Add diagonal constraints when supported:
21 % constraint forall(i,j in 1..n where i < j)(
22 % queens[i] + i != queens[j] + j /\
23 % queens[i] - i != queens[j] - j
24 % );
25
26 solve satisfy;
27 "#;
28
29 println!("Parsing 4-Queens problem...");
30 let ast = zelen::parse(source)?;
31
32 println!("Translating to Selen Model...");
33 let translated = zelen::Translator::translate_with_vars(&ast)?;
34
35 println!("Solving...");
36 match translated.model.solve() {
37 Ok(solution) => {
38 println!("\n✓ Solution found!");
39
40 // Extract the queens array
41 if let Some(queens) = translated.int_var_arrays.get("queens") {
42 println!("\nQueens positions:");
43 for (i, var_id) in queens.iter().enumerate() {
44 if let selen::variables::Val::ValI(col) = solution[*var_id] {
45 println!(" Queen {} (row {}) is in column {}", i + 1, i + 1, col);
46 }
47 }
48
49 println!("\n⚠️ Note: This solution satisfies 'alldifferent' (different columns)");
50 println!(" but diagonal constraints are not yet implemented.");
51 println!(" All queens on the main diagonal is a valid solution for column-only constraints!");
52
53 // Print the board
54 println!("\nChessboard (. = empty, Q = queen):");
55 for row in 0..4 {
56 print!(" ");
57 for col in 0..4 {
58 let queen_var = queens[row];
59 if let selen::variables::Val::ValI(queen_col) = solution[queen_var] {
60 if queen_col == (col + 1) as i32 {
61 print!("Q ");
62 } else {
63 print!(". ");
64 }
65 }
66 }
67 println!();
68 }
69 }
70 }
71 Err(e) => {
72 println!("No solution found: {:?}", e);
73 }
74 }
75
76 Ok(())
77}examples/parser_demo.rs (line 29)
3fn main() {
4 println!("=== MiniZinc Parser Examples ===\n");
5
6 // Example 1: N-Queens problem
7 println!("Example 1: N-Queens Problem");
8 let nqueens = r#"
9% N-Queens Problem
10int: n = 8;
11
12% Decision variables: queen position in each row
13array[1..n] of var 1..n: queens;
14
15% All queens in different columns
16constraint alldifferent(queens);
17
18% No two queens on same diagonal
19constraint forall(i in 1..n, j in i+1..n) (
20 queens[i] != queens[j] + (j - i) /\
21 queens[i] != queens[j] - (j - i)
22);
23
24solve satisfy;
25
26output ["queens = ", show(queens), "\n"];
27 "#;
28
29 match parse(nqueens) {
30 Ok(model) => println!("✓ Successfully parsed {} items\n", model.items.len()),
31 Err(e) => println!("✗ Parse error:\n{}\n", e),
32 }
33
34 // Example 2: Simple optimization
35 println!("Example 2: Simple Optimization");
36 let optimization = r#"
37int: budget = 100;
38array[1..5] of int: costs = [10, 20, 15, 30, 25];
39array[1..5] of int: values = [50, 100, 75, 150, 125];
40array[1..5] of var 0..1: x;
41
42constraint sum(i in 1..5)(costs[i] * x[i]) <= budget;
43
44solve maximize sum(i in 1..5)(values[i] * x[i]);
45 "#;
46
47 match parse(optimization) {
48 Ok(model) => println!("✓ Successfully parsed {} items\n", model.items.len()),
49 Err(e) => println!("✗ Parse error:\n{}\n", e),
50 }
51
52 // Example 3: Syntax error - missing colon
53 println!("Example 3: Syntax Error (missing colon)");
54 let error1 = r#"
55int n = 5;
56var 1..n: x;
57 "#;
58
59 match parse(error1) {
60 Ok(_) => println!("✗ Should have failed!\n"),
61 Err(e) => println!("✓ Caught error:\n{}\n", e),
62 }
63
64 // Example 4: Syntax error - missing semicolon
65 println!("Example 4: Syntax Error (missing semicolon)");
66 let error2 = r#"
67int: n = 5
68var 1..n: x;
69 "#;
70
71 match parse(error2) {
72 Ok(_) => println!("✗ Should have failed!\n"),
73 Err(e) => println!("✓ Caught error:\n{}\n", e),
74 }
75
76 // Example 5: Complex expressions
77 println!("Example 5: Complex Expressions");
78 let complex = r#"
79int: n = 10;
80array[1..n] of var 1..100: x;
81
82constraint sum(x) == 500;
83constraint forall(i in 1..n-1)(x[i] <= x[i+1]);
84constraint x[1] >= 10;
85constraint x[n] <= 90;
86
87solve minimize sum(i in 1..n)(x[i] * x[i]);
88 "#;
89
90 match parse(complex) {
91 Ok(model) => println!("✓ Successfully parsed {} items\n", model.items.len()),
92 Err(e) => println!("✗ Parse error:\n{}\n", e),
93 }
94
95 // Example 6: Array comprehension
96 println!("Example 6: Array Comprehension");
97 let array_comp = r#"
98int: n = 10;
99array[1..n] of int: squares = [i*i | i in 1..n];
100array[int] of int: evens = [i | i in 1..20 where i mod 2 == 0];
101 "#;
102
103 match parse(array_comp) {
104 Ok(model) => println!("✓ Successfully parsed {} items\n", model.items.len()),
105 Err(e) => println!("✗ Parse error:\n{}\n", e),
106 }
107
108 // Example 7: Set operations
109 println!("Example 7: Set Operations");
110 let sets = r#"
111set of int: S = {1, 3, 5, 7, 9};
112set of int: T = 1..10;
113var 1..10: x;
114
115constraint x in S;
116constraint x in T;
117 "#;
118
119 match parse(sets) {
120 Ok(model) => println!("✓ Successfully parsed {} items\n", model.items.len()),
121 Err(e) => println!("✗ Parse error:\n{}\n", e),
122 }
123
124 println!("=== All examples completed ===");
125}Additional examples can be found in: