Crates.io | selen |
lib.rs | selen |
version | 0.8.1 |
created_at | 2025-09-23 09:50:23.92716+00 |
updated_at | 2025-09-25 08:24:18.72759+00 |
description | Constraint Satisfaction Problem (CSP) solver |
homepage | https://github.com/radevgit/selen |
repository | https://github.com/radevgit/selen |
max_upload_size | |
id | 1851245 |
size | 1,895,354 |
A Constraint Satisfaction Problem (CSP) solver library written in Rust with zero external dependencies.
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
Constraint Categories:
+
, -
, *
, /
, %
, abs()
, min()
, max()
, sum()
==
, !=
, <
, <=
, >
, >=
(natural syntax)and()
, or()
, not()
with array syntax and([a,b,c])
and variadic syntax and(a,b,c,d)
alldiff()
, allequal()
, element x[y] = z
, count(vars, value, count)
, table(vars, tuples)
a <= b <= c
, a < b < c
, a >= b >= c
, a > b > c
(natural between
constraints)at_least(vars, value, count)
, at_most(vars, value, count)
, exactly(vars, value, count)
if_then(condition, constraint)
, if_then_else(condition, then_constraint, else_constraint)
Programmatic version of constraints
m.post(x.lt(y)); // x < y
m.post(y.le(z)); // y <= z
m.post(z.gt(5)); // z > 5
m.post(x.add(y).le(z)); // x + y <= z
m.post(y.sub(x).ge(0)); // y - x >= 0
m.post(x.mul(y).eq(12)); // x * y == 12
m.post(z.div(y).ne(0)); // z / y != 0
Mathematical syntax with post! macro
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
Add this to your Cargo.toml
:
[dependencies]
selen = "0.8.1"
๐งฉ 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 3020.832ms!
๐ Statistics: 499 propagations, 22 nodes explored
๐ Efficiency: 22.7 propagations/node
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
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
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
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
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)
}
}
For developers who prefer a more explicit, programmatic approach, the same constraints can be built using the runtime API:
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.post(x.lt(y)); // x < y
m.post(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); // All different
// Mathematical functions
let abs_result = m.abs(x);
m.post(abs_result.ge(1)); // abs(x) >= 1
// Solve the problem
if let Ok(solution) = m.solve() {
println!("x = {:?}", solution[x]);
println!("y = {:?}", solution[y]);
}
}
This project is licensed under the MIT License - see the LICENSE file for details.