Skip to main content

minion_sys/
lib.rs

1//! This crate provides low level Rust bindings to the [Minion](https://github.com/minion/minion)
2//! constraint solver.
3//!
4//! # Examples
5//!
6//! Consider the following Minion problem:
7//!
8//! ```plaintext
9//! MINION 3
10//! **VARIABLES**
11//! DISCRETE x #
12//! {1..3}
13//! DISCRETE y #
14//! {2..4}
15//! DISCRETE z #
16//! {1..5}
17//! **SEARCH**
18//! PRINT[[x],[y],[z]]
19//! VARORDER STATIC [x, y, z]
20//! **CONSTRAINTS**
21//! sumleq([x,y,z],4)
22//! ineq(x, y, -1)
23//! **EOF**
24//! ```
25//!
26//! This can be solved in Rust like so:
27//!
28//! ```
29//! use minion_sys::ast::*;
30//! use minion_sys::run_minion;
31//! use std::collections::HashMap;
32//!
33//! // Collect solutions using a closure — no globals needed.
34//! let mut all_solutions: Vec<HashMap<VarName,Constant>> = vec![];
35//!
36//! let callback: Box<dyn FnMut(HashMap<VarName,Constant>) -> bool> =
37//!     Box::new(|solutions| {
38//!         all_solutions.push(solutions);
39//!         true
40//!     });
41//!
42//! // Build and run the model.
43//! let mut model = Model::new();
44//! model
45//!     .named_variables
46//!     .add_var("x".to_owned(), VarDomain::Bound(1, 3));
47//! model
48//!     .named_variables
49//!     .add_var("y".to_owned(), VarDomain::Bound(2, 4));
50//! model
51//!     .named_variables
52//!     .add_var("z".to_owned(), VarDomain::Bound(1, 5));
53//!
54//! let leq = Constraint::SumLeq(
55//!     vec![
56//!         Var::NameRef("x".to_owned()),
57//!         Var::NameRef("y".to_owned()),
58//!         Var::NameRef("z".to_owned()),
59//!     ],
60//!     Var::ConstantAsVar(4),
61//! );
62//!
63//! let geq = Constraint::SumGeq(
64//!     vec![
65//!         Var::NameRef("x".to_owned()),
66//!         Var::NameRef("y".to_owned()),
67//!         Var::NameRef("z".to_owned()),
68//!     ],
69//!     Var::ConstantAsVar(4),
70//! );
71//!
72//! let ineq = Constraint::Ineq(
73//!     Var::NameRef("x".to_owned()),
74//!     Var::NameRef("y".to_owned()),
75//!     Constant::Integer(-1),
76//! );
77//!
78//! model.constraints.push(leq);
79//! model.constraints.push(geq);
80//! model.constraints.push(ineq);
81//!
82//! let _solver_ctx = run_minion(model, callback).expect("Error occurred");
83//!
84//! let solution_set_1 = &all_solutions[0];
85//! let x1 = solution_set_1.get("x").unwrap();
86//! let y1 = solution_set_1.get("y").unwrap();
87//! let z1 = solution_set_1.get("z").unwrap();
88//!
89//! assert_eq!(all_solutions.len(),1);
90//! assert_eq!(*x1,Constant::Integer(1));
91//! assert_eq!(*y1,Constant::Integer(2));
92//! assert_eq!(*z1,Constant::Integer(1));
93//! ```
94//!
95//! ## `PRINT` and `VARORDER`
96//!
97//! These bindings have no replacement for Minion's `PRINT` and `VARORDER` statements - any
98//! variable given to the model that does not have a constant value is considered a search
99//! variable. Solutions are returned through the [callback function](Callback) as a `HashMap`.
100
101pub use run::*;
102
103pub mod error;
104mod ffi;
105
106pub mod ast;
107mod run;
108
109mod scoped_ptr;
110
111pub mod print;