Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/advanced_runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ fn example_7_global_constraints() {
println!("📝 Example 7: Global Constraint Shortcuts (Phase 2)");

let mut m = Model::default();
let digits = (0..4).map(|_| m.int(1, 4)).collect::<Vec<_>>();
let digits = m.ints(4, 1, 4);

// Ultra-short global constraints
m.alldiff(&digits); // All digits must be different
Expand Down
8 changes: 4 additions & 4 deletions examples/app_resource_allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn main() {
// Assignment variables: worker_assignments[task][worker] = 1 if assigned
let mut worker_assignments = Vec::new();
for _ in 0..tasks.len() {
let task_assignments: Vec<_> = m.new_vars_binary(workers.len()).collect();
let task_assignments = m.bools(workers.len());
worker_assignments.push(task_assignments);
}

Expand Down Expand Up @@ -82,9 +82,9 @@ fn main() {

let mut total_time = 0;
for (task_idx, task_assignments) in worker_assignments.iter().enumerate() {
let assignments = solution.get_values_binary(task_assignments);
for (worker_idx, &assigned) in assignments.iter().enumerate() {
if assigned {
let assignments = solution.get_values(task_assignments);
for (worker_idx, assigned) in assignments.iter().enumerate() {
if *assigned == Val::ValI(1) {
let task_time = match solution[task_completion_times[task_idx]] {
Val::ValI(t) => t,
_ => 0
Expand Down
35 changes: 12 additions & 23 deletions examples/constraint_boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ fn main() {
println!("📋 Test 1: Array AND - and([a, b, c, d])");
{
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let d = m.bool();
let vars = m.bools(4);
let (a, b, c, d) = (vars[0], vars[1], vars[2], vars[3]);

// All must be true (1) for result to be true
post!(m, and([a, b, c, d]));
Expand All @@ -33,10 +31,8 @@ fn main() {
println!("\n📋 Test 2: Array OR - or([a, b, c, d])");
{
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let d = m.bool();
let vars = m.bools(4);
let (a, b, c, d) = (vars[0], vars[1], vars[2], vars[3]);

// At least one must be true
post!(m, or([a, b, c, d]));
Expand All @@ -57,10 +53,8 @@ fn main() {
println!("\n📋 Test 3: Variadic AND - and(a, b, c, d)");
{
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let d = m.bool();
let vars = m.bools(4);
let (a, b, c, d) = (vars[0], vars[1], vars[2], vars[3]);

post!(m, and(a, b, c, d));
post!(m, a == 1);
Expand All @@ -81,10 +75,8 @@ fn main() {
println!("\n📋 Test 4: Variadic OR - or(a, b, c, d)");
{
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let d = m.bool();
let vars = m.bools(4);
let (a, b, c, d) = (vars[0], vars[1], vars[2], vars[3]);

post!(m, or(a, b, c, d));
post!(m, a == 0);
Expand All @@ -105,9 +97,8 @@ fn main() {
println!("\n📋 Test 5: Array NOT - not([a, b, c])");
{
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let vars = m.bools(3);
let (a, b, c) = (vars[0], vars[1], vars[2]);

// This applies not() to each variable individually
post!(m, not([a, b, c]));
Expand All @@ -124,10 +115,8 @@ fn main() {
println!("\n📋 Test 6: postall! with simple constraints");
{
let mut m = Model::default();
let x = m.bool();
let y = m.bool();
let z = m.bool();
let w = m.bool();
let vars = m.bools(4);
let (x, y, z, w) = (vars[0], vars[1], vars[2], vars[3]);

// Use separate constraints since nested arrays might not work yet
post!(m, and([x, y])); // x AND y must be true
Expand Down
16 changes: 8 additions & 8 deletions examples/constraint_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() {
println!("📝 Example 1: All Different Constraint");
{
let mut model = Model::default();
let vars: Vec<_> = (0..4).map(|_| model.int(1, 4)).collect();
let vars = model.ints(4, 1, 4);

// All variables must have different values
model.alldiff(&vars);
Expand All @@ -44,7 +44,7 @@ fn main() {
println!("📝 Example 2: All Equal Constraint");
{
let mut model = Model::default();
let vars: Vec<_> = (0..3).map(|_| model.int(1, 10)).collect();
let vars = model.ints(3, 1, 10);

// All variables must have the same value
model.alleq(&vars);
Expand Down Expand Up @@ -100,7 +100,7 @@ fn main() {
println!("📝 Example 4: Count Constraint");
{
let mut model = Model::default();
let vars: Vec<_> = (0..6).map(|_| model.int(1, 3)).collect();
let vars = model.ints(6, 1, 3);
let count_result = model.int(0, 6);

// Count how many variables have value 2
Expand Down Expand Up @@ -167,11 +167,11 @@ fn main() {
println!("📝 Example 6: Global Cardinality Constraint");
{
let mut model = Model::default();
let vars: Vec<_> = (0..8).map(|_| model.int(1, 4)).collect();
let vars = model.ints(8, 1, 4);

// We want to count 1s, 2s, 3s, and 4s
let values = [1, 2, 3, 4];
let counts: Vec<_> = (0..4).map(|_| model.int(0, 8)).collect();
let counts = model.ints(4, 0, 8);

// Global cardinality constraint
model.gcc(&vars, &values, &counts);
Expand Down Expand Up @@ -223,14 +223,14 @@ fn main() {
let mut model = Model::default();

// Create a small scheduling problem with global constraints
let tasks: Vec<_> = (0..4).map(|_| model.int(1, 10)).collect(); // Start times
let resources: Vec<_> = (0..4).map(|_| model.int(1, 3)).collect(); // Resource assignments
let tasks = model.ints(4, 1, 10); // Start times
let resources = model.ints(4, 1, 3); // Resource assignments

// All tasks must start at different times (no overlap)
model.alldiff(&tasks);

// Count resource usage - we have 3 resources, want balanced usage
let resource_counts: Vec<_> = (0..3).map(|_| model.int(0, 4)).collect();
let resource_counts = model.ints(3, 0, 4);
model.gcc(&resources, &[1, 2, 3], &resource_counts);

// Each resource should be used at least once
Expand Down
4 changes: 1 addition & 3 deletions examples/n_queens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ fn solve_n_queens(n: usize) -> Option<(Vec<i32>, SolverStats)> {
let mut model = Model::default();

// Variables: queen_row[i] = row position of queen in column i
let queen_rows: Vec<_> = (0..n)
.map(|_| model.int(1, n as i32))
.collect();
let queen_rows = model.ints(n, 1, n as i32);

// Constraint 1: All queens must be in different rows
// This is the most direct AllDifferent constraint
Expand Down
50 changes: 43 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@
//!
//! - **Integer variables**: `m.int(min, max)` - continuous range
//! - **Float variables**: `m.float(min, max)` - continuous range with precision control
//! - **Custom domains**: `m.ints(vec![values])` - specific integer values only
//! - **Custom domains**: `m.intset(vec![values])` - specific integer values only
//! - **Boolean variables**: `m.bool()` - equivalent to `m.int(0, 1)`
//!
//! ## Bulk Variable Creation
//!
//! - **Multiple integers**: `m.ints(n, min, max)` - create n integer variables with same bounds
//! - **Multiple floats**: `m.floats(n, min, max)` - create n float variables with same bounds
//! - **Multiple booleans**: `m.bools(n)` - create n boolean variables
//!
//! ## Constraint Types
//!
//! - **Arithmetic**: `+`, `-`, `*`, `/`, `%`, `abs()`, `min()`, `max()`, `sum()`
Expand Down Expand Up @@ -100,9 +106,9 @@
//! let mut m = Model::default();
//!
//! // Variables with custom domains
//! let red = m.ints(vec![1, 3, 5, 7]); // Odd numbers
//! let blue = m.ints(vec![2, 4, 6, 8]); // Even numbers
//! let green = m.ints(vec![2, 3, 5, 7]); // Prime numbers
//! let red = m.intset(vec![1, 3, 5, 7]); // Odd numbers
//! let blue = m.intset(vec![2, 4, 6, 8]); // Even numbers
//! let green = m.intset(vec![2, 3, 5, 7]); // Prime numbers
//!
//! // All must be different
//! post!(m, alldiff([red, blue, green]));
Expand All @@ -113,7 +119,37 @@
//! }
//! ```
//!
//! ## Example 4: Programmatic API - Basic Constraints
//! ## Example 4: Bulk Variable Creation
//!
//! Create multiple variables efficiently with the same domain:
//!
//! ```rust
//! use selen::prelude::*;
//!
//! let mut m = Model::default();
//!
//! // Create 5 integer variables, each with domain [1, 10]
//! let vars = m.ints(5, 1, 10);
//!
//! // Create 3 boolean variables
//! let flags = m.bools(3);
//!
//! // Create 4 float variables with same bounds
//! let weights = m.floats(4, 0.0, 1.0);
//!
//! // All variables in vars must be different
//! post!(m, alldiff(&vars));
//!
//! // At least one flag must be true (using slice syntax)
//! post!(m, or([flags[0], flags[1], flags[2]]));
//!
//! if let Ok(solution) = m.solve() {
//! println!("Solution found with {} variables!",
//! vars.len() + flags.len() + weights.len());
//! }
//! ```
//!
//! ## Example 5: Programmatic API - Basic Constraints
//!
//! For developers who prefer explicit, method-based constraint building:
//!
Expand All @@ -134,7 +170,7 @@
//! }
//! ```
//!
//! ## Example 5: Programmatic API - Global Constraints
//! ## Example 6: Programmatic API - Global Constraints
//!
//! ```rust
//! use selen::prelude::*;
Expand All @@ -157,7 +193,7 @@
//! }
//! ```
//!
//! ## Example 6: Programmatic API - Complex Operations
//! ## Example 7: Programmatic API - Complex Operations
//!
//! ```rust
//! use selen::prelude::*;
Expand Down
Loading