Skip to main content

queens4/
queens4.rs

1/// Example: Solve 4-Queens with diagonal constraints
2///
3/// This demonstrates a fuller N-Queens solution with diagonal constraints
4
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}