selen 0.9.4

Constraint Satisfaction Problem (CSP) solver
Documentation
# Selen - CSP Solver

[![Crates.io](https://img.shields.io/crates/v/selen.svg?color=blue)](https://crates.io/crates/selen)
[![Documentation](https://docs.rs/selen/badge.svg)](https://docs.rs/selen)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

A Constraint Satisfaction Problem (CSP) solver library written in Rust with zero external dependencies. 


## Overview

This library provides efficient algorithms and data structures for solving constraint satisfaction problems. CSPs are mathematical problems defined as a set of objects whose state must satisfy a number of constraints or limitations.


**Variable Types**: `int`, `float`, mixed constraints

**Unbounded Variables**: Automatic bound inference for `int(i32::MIN, i32::MAX)` and `float(f64::NEG_INFINITY, f64::INFINITY)` - bounds inferred from context or sensible defaults

**Constraint Categories**:
- **Mathematical**: `+`, `-`, `*`, `/`, `%`, `abs()`, `min()`, `max()`, `sum()`
- **Comparison**: `==`, `!=`, `<`, `<=`, `>`, `>=` (natural syntax)
- **Boolean Logic**: `and()`, `or()`, `not()` with array syntax `and([a,b,c])` and variadic syntax `and(a,b,c,d)`
- **Global**: `alldiff()`, `allequal()`, element `x[y] = z`, `count(vars, value, count)`, `table(vars, tuples)`
- **Ordering**: `a <= b <= c`, `a < b < c`, `a >= b >= c`, `a > b > c` (natural `between` constraints) 
- **Cardinality**: `at_least(vars, value, count)`, `at_most(vars, value, count)`, `exactly(vars, value, count)`
- **Conditional**: `if_then(condition, constraint)`, `if_then_else(condition, then_constraint, else_constraint)`

**Programmatic version of constraints**
```rust
m.new(x.lt(y));                        // x < y
m.new(y.le(z));                        // y <= z
m.new(z.gt(5));                        // z > 5
m.new(x.add(y).le(z));                 // x + y <= z
m.new(y.sub(x).ge(0));                 // y - x >= 0
m.new(x.mul(y).eq(12));                // x * y == 12
m.new(z.div(y).ne(0));                 // z / y != 0
```

**Mathematical syntax with post! macro**
```rust
post!(m, x < y);                        // x < y
post!(m, y <= z);                       // y <= z
post!(m, z > int(5));                   // z > 5
post!(m, x + y <= z);                   // x + y <= z
post!(m, y - x >= int(0));              // y - x >= 0
post!(m, x * y == int(12));             // x * y == 12
post!(m, z / y != int(0));              // z / y != 0
```

**FlatZinc/MiniZinc Support**

For FlatZinc `.fzn` file support, use the separate [Zelen](https://github.com/radevgit/zelen) crate.

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
selen = "0.9"
```

## Examples

```
๐Ÿงฉ Solving Platinum Blonde puzzle:
๐Ÿ“Š Puzzle stats: 17 clues given, 64 empty cells

Puzzle:                                 Solution:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ยท ยท ยท โ”‚ ยท ยท ยท โ”‚ ยท ยท ยท โ”‚               โ”‚ 9 8 7 โ”‚ 6 5 4 โ”‚ 3 2 1 โ”‚
โ”‚ ยท ยท ยท โ”‚ ยท ยท 3 โ”‚ ยท 8 5 โ”‚               โ”‚ 2 4 6 โ”‚ 1 7 3 โ”‚ 9 8 5 โ”‚
โ”‚ ยท ยท 1 โ”‚ ยท 2 ยท โ”‚ ยท ยท ยท โ”‚               โ”‚ 3 5 1 โ”‚ 9 2 8 โ”‚ 7 4 6 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค               โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ยท ยท ยท โ”‚ 5 ยท 7 โ”‚ ยท ยท ยท โ”‚               โ”‚ 1 2 8 โ”‚ 5 3 7 โ”‚ 6 9 4 โ”‚
โ”‚ ยท ยท 4 โ”‚ ยท ยท ยท โ”‚ 1 ยท ยท โ”‚               โ”‚ 6 3 4 โ”‚ 8 9 2 โ”‚ 1 5 7 โ”‚
โ”‚ ยท 9 ยท โ”‚ ยท ยท ยท โ”‚ ยท ยท ยท โ”‚               โ”‚ 7 9 5 โ”‚ 4 6 1 โ”‚ 8 3 2 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค               โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 5 ยท ยท โ”‚ ยท ยท ยท โ”‚ ยท 7 3 โ”‚               โ”‚ 5 1 9 โ”‚ 2 8 6 โ”‚ 4 7 3 โ”‚
โ”‚ ยท ยท 2 โ”‚ ยท 1 ยท โ”‚ ยท ยท ยท โ”‚               โ”‚ 4 7 2 โ”‚ 3 1 9 โ”‚ 5 6 8 โ”‚
โ”‚ ยท ยท ยท โ”‚ ยท 4 ยท โ”‚ ยท ยท 9 โ”‚               โ”‚ 8 6 3 โ”‚ 7 4 5 โ”‚ 2 1 9 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โœ… Solution found in 2289.885ms!
๐Ÿ“Š Statistics: 538 propagations, 25 nodes explored
๐Ÿ” Efficiency: 21.5 propagations/node

```

### Core Problems
```bash
cargo run --release --example sudoku                 # Classic 9x9 Sudoku solver
cargo run --release --example n_queens               # N-Queens backtracking
cargo run --release --example send_more_money        # Cryptarithmetic puzzle
cargo run --release --example graph_coloring         # Graph constraint problems
cargo run --release --example zebra_puzzle           # Logic puzzle solving
```

### Constraint Types
```bash
cargo run --release --example constraint_global      # AllEqual, Count, AllDiff
cargo run --release --example constraint_element     # Element constraint usage
cargo run --release --example constraint_table       # Table constraints
cargo run --release --example constraint_boolean     # Boolean arrays and logic
```

### Advanced Features
```bash
cargo run --release --example advanced_runtime_api   # Dynamic constraint building
cargo run --release --example advanced_memory_limits # Memory management demo
cargo run --release --example advanced_timeout       # Timeout handling
```

### Real Applications
```bash
cargo run --release --example app_manufacturing      # Industrial optimization
cargo run --release --example app_portfolio          # Financial modeling
cargo run --release --example app_resource_allocation # Resource planning
```

### Basic Usage

```rust
use selen::prelude::*;

fn main() {
    let mut m = Model::default();

    // Create variables
    let x = m.int(1, 10);       // Integer variable from 1 to 10
    let y = m.int(5, 15);       // Integer variable from 5 to 15

    // Add constraints
    post!(m, x < y);            // x must be less than y
    post!(m, x + y == int(12)); // x + y must equal 12
    
    // Solve the problem
    if let Ok(solution) = m.solve() {
        println!("x = {:?}", solution[x]);  // x = ValI(1)  
        println!("y = {:?}", solution[y]);  // y = ValI(11)
    }
}
```

### Programmatic API Example

For developers who prefer a more explicit, programmatic approach, the same constraints can be built using the runtime API:

```rust
use selen::prelude::*;

fn main() {
    let mut m = Model::default();

    // Create variables
    let x = m.int(1, 10);
    let y = m.int(5, 15);

    // Add constraints using programmatic API
    m.new(x.lt(y));                    // x < y
    m.new(x.add(y).eq(12));            // x + y == 12

    // Global constraints
    let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
    m.alldiff(&vars.clone());       // All different
    
    // Mathematical functions
    let abs_result = m.abs(x);
    m.new(abs_result.ge(1));           // abs(x) >= 1
    
    // Solve the problem
    if let Ok(solution) = m.solve() {
        println!("x = {:?}", solution[x]);
        println!("y = {:?}", solution[y]);
    }
}
```




## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.