pub struct Model {
pub props: Propagators,
pub float_precision_digits: i32,
/* private fields */
}Fields§
§props: Propagators§float_precision_digits: i32Precision for float variables (decimal places)
Implementations§
Source§impl Model
impl Model
Sourcepub fn with_float_precision(precision_digits: i32) -> Self
pub fn with_float_precision(precision_digits: i32) -> Self
Create a new model with custom float precision
use cspsolver::prelude::*;
let mut m = Model::with_float_precision(4); // 4 decimal places
let var = m.float(0.0, 1.0);Sourcepub fn float_precision_digits(&self) -> i32
pub fn float_precision_digits(&self) -> i32
Get the current float precision setting
Sourcepub fn float_step_size(&self) -> f64
pub fn float_step_size(&self) -> f64
Get the step size for the current float precision
Sourcepub fn get_constraint_registry(&self) -> &ConstraintRegistry
pub fn get_constraint_registry(&self) -> &ConstraintRegistry
Get access to constraint registry for debugging/analysis
Sourcepub fn new_var(&mut self, min: Val, max: Val) -> VarId
pub fn new_var(&mut self, min: Val, max: Val) -> VarId
Create a new decision variable, with the provided domain bounds.
Both lower and upper bounds are included in the domain.
In case max < min the bounds will be swapped.
We don’t want to deal with “unwrap” every time
use cspsolver::prelude::*;
let mut m = Model::default();
let var = m.new_var(Val::int(1), Val::int(10));Sourcepub fn new_vars(
&mut self,
n: usize,
min: Val,
max: Val,
) -> impl Iterator<Item = VarId> + '_
pub fn new_vars( &mut self, n: usize, min: Val, max: Val, ) -> impl Iterator<Item = VarId> + '_
Create new decision variables, with the provided domain bounds.
All created variables will have the same starting domain bounds.
Both lower and upper bounds are included in the domain.
In case max < min the bounds will be swapped.
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.new_vars(3, Val::int(0), Val::int(5)).collect();Sourcepub fn int_vars(
&mut self,
n: usize,
min: i32,
max: i32,
) -> impl Iterator<Item = VarId> + '_
pub fn int_vars( &mut self, n: usize, min: i32, max: i32, ) -> impl Iterator<Item = VarId> + '_
Create new integer decision variables, with the provided domain bounds.
Both lower and upper bounds are included in the domain.
In case max < min the bounds will be swapped.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.int_vars(5, 0, 9).collect();Sourcepub fn ints(&mut self, values: Vec<i32>) -> VarId
pub fn ints(&mut self, values: Vec<i32>) -> VarId
Create a new integer decision variable from a vector of specific values. This is useful for creating variables with non-contiguous domains.
§Arguments
values- Vector of integer values that the variable can take
§Returns
A new VarId for the created variable
use cspsolver::prelude::*;
let mut m = Model::default();
let var = m.ints(vec![2, 4, 6, 8]); // Even numbers onlySourcepub fn float_vars(
&mut self,
n: usize,
min: f64,
max: f64,
) -> impl Iterator<Item = VarId> + '_
pub fn float_vars( &mut self, n: usize, min: f64, max: f64, ) -> impl Iterator<Item = VarId> + '_
Create new float decision variables, with the provided domain bounds.
Both lower and upper bounds are included in the domain.
In case max < min the bounds will be swapped.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.float_vars(3, 0.0, 1.0).collect();Sourcepub fn bool(&mut self) -> VarId
pub fn bool(&mut self) -> VarId
Create a new boolean decision variable (0 or 1).
This is a convenience method equivalent to new_var_int(0, 1).
Boolean variables can be used with boolean logic constraints.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
// Boolean operations using model methods:
let and_result = m.bool_and(&[a, b]); // AND
let or_result = m.bool_or(&[a, c]); // OR
let not_result = m.bool_not(a); // NOT
// Basic constraints:
post!(m, a != b);
post!(m, and_result != c);Sourcepub fn new_var_binary(&mut self) -> VarIdBin
pub fn new_var_binary(&mut self) -> VarIdBin
Create a new binary decision variable.
use cspsolver::prelude::*;
let mut m = Model::default();
let var = m.new_var_binary();Sourcepub fn new_vars_binary(
&mut self,
n: usize,
) -> impl Iterator<Item = VarIdBin> + '_
pub fn new_vars_binary( &mut self, n: usize, ) -> impl Iterator<Item = VarIdBin> + '_
Create new binary decision variables.
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.new_vars_binary(4).collect();Sourcepub fn int(&mut self, min: i32, max: i32) -> VarId
pub fn int(&mut self, min: i32, max: i32) -> VarId
Short method to create an integer variable.
Alias for new_var_int() - more concise and readable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(0, 10); // Instead of m.int(0, 10)
let y = m.int(-5, 5); // Clean and conciseSourcepub fn float(&mut self, min: f64, max: f64) -> VarId
pub fn float(&mut self, min: f64, max: f64) -> VarId
Short method to create a float variable.
Alias for new_var_float() - more concise and readable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.float(0.0, 10.0); // Instead of m.float(0.0, 10.0)
let y = m.float(-1.5, 3.14); // Clean and conciseSourcepub fn binary(&mut self) -> VarIdBin
pub fn binary(&mut self) -> VarIdBin
Short method to create a binary variable.
Alias for new_var_binary() - more concise and readable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.binary(); // Instead of m.new_var_binary()Sourcepub fn add(&mut self, x: impl View, y: impl View) -> VarId
pub fn add(&mut self, x: impl View, y: impl View) -> VarId
Create an expression of two views added together.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 5);
let y = m.int(2, 8);
let sum = m.add(x, y);Sourcepub fn sub(&mut self, x: impl View, y: impl View) -> VarId
pub fn sub(&mut self, x: impl View, y: impl View) -> VarId
Create an expression representing the difference of two views: x - y.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(5, 10);
let y = m.int(2, 4);
let diff = m.sub(x, y);Sourcepub fn mul(&mut self, x: impl View, y: impl View) -> VarId
pub fn mul(&mut self, x: impl View, y: impl View) -> VarId
Create an expression of the multiplication of two views.
§Example
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(3, 5);
let y = m.int(2, 4);
let product = m.mul(x, y);Sourcepub fn modulo(&mut self, x: impl View, y: impl View) -> VarId
pub fn modulo(&mut self, x: impl View, y: impl View) -> VarId
Create a new variable that holds the result of x % y (modulo operation).
For the modulo operation x % y = result:
- If y > 0: result is in range [0, y-1]
- If y < 0: result is in range [y+1, 0]
- If y contains 0, the constraint may fail during solving
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(10, 20);
let y = m.int(3, 7);
let remainder = m.modulo(x, y);Sourcepub fn abs(&mut self, x: impl View) -> VarId
pub fn abs(&mut self, x: impl View) -> VarId
Create a new variable that holds the result of |x| (absolute value).
The absolute value operation always produces a non-negative result:
- If x >= 0: |x| = x
- If x < 0: |x| = -x
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(-10, 5);
let abs_x = m.abs(x);Sourcepub fn min(&mut self, vars: &[VarId]) -> VarId
pub fn min(&mut self, vars: &[VarId]) -> VarId
Create a new variable that holds the minimum value of the given variables.
The minimum operation finds the smallest value among all input variables:
result = min(vars[0], vars[1], ..., vars[n])- At least one variable must be able to achieve the minimum value
- All variables must be >= result
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let y = m.int(5, 15);
let z = m.int(3, 8);
let minimum = m.min(&[x, y, z]);Sourcepub fn max(&mut self, vars: &[VarId]) -> VarId
pub fn max(&mut self, vars: &[VarId]) -> VarId
Create a new variable that holds the maximum value of the given variables.
The maximum operation finds the largest value among all input variables:
result = max(vars[0], vars[1], ..., vars[n])- At least one variable must be able to achieve the maximum value
- All variables must be <= result
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let y = m.int(5, 15);
let z = m.int(3, 8);
let maximum = m.max(&[x, y, z]);Sourcepub fn div(&mut self, x: impl View, y: impl View) -> VarId
pub fn div(&mut self, x: impl View, y: impl View) -> VarId
Create a new variable that holds the result of x / y (division).
For the division operation x / y = result:
- If y contains 0, the constraint may fail during solving
- Division by values very close to 0 is also avoided for numerical stability
- The result may be converted to float even for integer inputs
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(10, 20);
let y = m.int(2, 5);
let quotient = m.div(x, y);Sourcepub fn sum(&mut self, xs: &[impl View]) -> VarId
pub fn sum(&mut self, xs: &[impl View]) -> VarId
Create an expression of the sum of a slice of views.
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.int_vars(3, 1, 10).collect();
let total = m.sum(&vars);Sourcepub fn sum_iter(&mut self, xs: impl IntoIterator<Item = impl View>) -> VarId
pub fn sum_iter(&mut self, xs: impl IntoIterator<Item = impl View>) -> VarId
Create an expression of the sum of an iterator of views.
use cspsolver::prelude::*;
let mut m = Model::default();
let vars: Vec<_> = m.int_vars(3, 1, 10).collect();
let total = m.sum_iter(vars.iter().copied());Sourcepub fn bool_and(&mut self, operands: &[VarId]) -> VarId
pub fn bool_and(&mut self, operands: &[VarId]) -> VarId
Create a variable representing the boolean AND of multiple operands. Returns a variable that is 1 if ALL operands are non-zero, 0 otherwise.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let c = m.bool();
let and_result = m.bool_and(&[a, b, c]);Sourcepub fn bool_or(&mut self, operands: &[VarId]) -> VarId
pub fn bool_or(&mut self, operands: &[VarId]) -> VarId
Create a variable representing the boolean OR of multiple operands. Returns a variable that is 1 if ANY operand is non-zero, 0 otherwise.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let a = m.bool();
let b = m.bool();
let or_result = m.bool_or(&[a, b]);Sourcepub fn bool_not(&mut self, operand: VarId) -> VarId
pub fn bool_not(&mut self, operand: VarId) -> VarId
Create a variable representing the boolean NOT of an operand. Returns a variable that is 1 if the operand is 0, and 0 if the operand is non-zero.
§Examples
use cspsolver::prelude::*;
let mut m = Model::default();
let a = m.bool();
let not_a = m.bool_not(a);Sourcepub fn minimize(self, objective: impl View) -> Option<Solution>
pub fn minimize(self, objective: impl View) -> Option<Solution>
Find assignment that minimizes objective expression while satisfying all constraints.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
post!(m, x > 3);
let solution = m.minimize(x);Sourcepub fn minimize_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Option<Solution>where
F: FnOnce(&SolveStats),
pub fn minimize_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Option<Solution>where
F: FnOnce(&SolveStats),
Find assignment that minimizes objective expression with callback to capture solving statistics.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let solution = m.minimize_with_callback(x, |stats| {
println!("Propagations: {}", stats.propagation_count);
});Sourcepub fn minimize_and_iterate(
self,
objective: impl View,
) -> impl Iterator<Item = Solution>
pub fn minimize_and_iterate( self, objective: impl View, ) -> impl Iterator<Item = Solution>
Enumerate assignments that satisfy all constraints, while minimizing objective expression.
The order in which assignments are yielded is not stable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 5);
let solutions: Vec<_> = m.minimize_and_iterate(x).collect();Sourcepub fn minimize_and_iterate_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Vec<Solution>where
F: FnOnce(&SolveStats),
pub fn minimize_and_iterate_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Vec<Solution>where
F: FnOnce(&SolveStats),
Enumerate assignments that satisfy all constraints, while minimizing objective expression, with callback.
The callback is called with final statistics after all solutions are found. Returns a vector of all solutions found during the search.
Sourcepub fn maximize(self, objective: impl View) -> Option<Solution>
pub fn maximize(self, objective: impl View) -> Option<Solution>
Find assignment that maximizes objective expression while satisfying all constraints.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
post!(m, x < 8);
let solution = m.maximize(x);Sourcepub fn maximize_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Option<Solution>where
F: FnOnce(&SolveStats),
pub fn maximize_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Option<Solution>where
F: FnOnce(&SolveStats),
Find assignment that maximizes objective expression with callback to capture solving statistics.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let solution = m.maximize_with_callback(x, |stats| {
println!("Nodes explored: {}", stats.node_count);
});Sourcepub fn maximize_and_iterate(
self,
objective: impl View,
) -> impl Iterator<Item = Solution>
pub fn maximize_and_iterate( self, objective: impl View, ) -> impl Iterator<Item = Solution>
Enumerate assignments that satisfy all constraints, while maximizing objective expression.
The order in which assignments are yielded is not stable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 5);
let solutions: Vec<_> = m.maximize_and_iterate(x).collect();Sourcepub fn maximize_and_iterate_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Vec<Solution>where
F: FnOnce(&SolveStats),
pub fn maximize_and_iterate_with_callback<F>(
self,
objective: impl View,
callback: F,
) -> Vec<Solution>where
F: FnOnce(&SolveStats),
Enumerate assignments that satisfy all constraints, while maximizing objective expression, with callback.
The callback is called with final statistics after all solutions are found. Returns a vector of all solutions found during the search.
Sourcepub fn validate(&self) -> Result<(), String>
pub fn validate(&self) -> Result<(), String>
Validate that all integer variable domains fit within the u16 optimization range.
This method checks that all integer variables have domains that can be represented using u16 optimization (domain size ≤ 65535). Since we’ve already replaced VarI with VarSparse in the new_var_with_bounds method, this validation mainly serves as a safety check and provides clear error messages for invalid domain sizes.
§Returns
Returns Ok(()) if validation succeeds, or Err(String) with error details if validation fails.
Sourcepub fn solve(self) -> Option<Solution>
pub fn solve(self) -> Option<Solution>
Search for assignment that satisfies all constraints within bounds of decision variables.
This method automatically tries optimization algorithms for suitable problems before falling back to traditional constraint propagation search.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let y = m.int(1, 10);
post!(m, x != y);
let solution = m.solve();Sourcepub fn solve_with_callback<F>(self, callback: F) -> Option<Solution>where
F: FnOnce(&SolveStats),
pub fn solve_with_callback<F>(self, callback: F) -> Option<Solution>where
F: FnOnce(&SolveStats),
Search for assignment with a callback to capture solving statistics.
The callback receives the solving statistics when the search completes.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 10);
let solution = m.solve_with_callback(|stats| {
println!("Search completed with {} propagations", stats.propagation_count);
});Sourcepub fn enumerate(self) -> impl Iterator<Item = Solution>
pub fn enumerate(self) -> impl Iterator<Item = Solution>
Enumerate all assignments that satisfy all constraints.
The order in which assignments are yielded is not stable.
use cspsolver::prelude::*;
let mut m = Model::default();
let x = m.int(1, 3);
let y = m.int(1, 3);
post!(m, x != y);
let solutions: Vec<_> = m.enumerate().collect();Sourcepub fn enumerate_with_callback<F>(self, callback: F) -> Vec<Solution>where
F: FnOnce(&SolveStats),
pub fn enumerate_with_callback<F>(self, callback: F) -> Vec<Solution>where
F: FnOnce(&SolveStats),
Enumerate all assignments that satisfy all constraints with callback to capture solving statistics.
The callback is called with final statistics after all solutions are found. Returns a vector of all solutions found during the search.
Source§impl Model
impl Model
Sourcepub fn eq_op(&mut self, left: VarId, right: VarId)
pub fn eq_op(&mut self, left: VarId, right: VarId)
Create equality constraint using operator syntax
Sourcepub fn ne_op(&mut self, left: VarId, right: VarId)
pub fn ne_op(&mut self, left: VarId, right: VarId)
Create inequality constraint using operator syntax
Sourcepub fn lt_op(&mut self, left: VarId, right: VarId)
pub fn lt_op(&mut self, left: VarId, right: VarId)
Create less-than constraint using operator syntax
Sourcepub fn le_op(&mut self, left: VarId, right: VarId)
pub fn le_op(&mut self, left: VarId, right: VarId)
Create less-than-or-equal constraint using operator syntax
Sourcepub fn gt_op(&mut self, left: VarId, right: VarId)
pub fn gt_op(&mut self, left: VarId, right: VarId)
Create greater-than constraint using operator syntax
Sourcepub fn ge_op(&mut self, left: VarId, right: VarId)
pub fn ge_op(&mut self, left: VarId, right: VarId)
Create greater-than-or-equal constraint using operator syntax
Sourcepub fn and_op(&mut self, left: VarId, right: VarId)
pub fn and_op(&mut self, left: VarId, right: VarId)
Create boolean AND constraint using operator syntax