minion_rs/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_rs::ast::*;
30//! use minion_rs::run_minion;
31//! use std::collections::HashMap;
32//! use std::sync::Mutex;
33//!
34//! // Get solutions out of Minion.
35//! // See the documentation for Callback for details.
36//!
37//! static ALL_SOLUTIONS: Mutex<Vec<HashMap<VarName,Constant>>> = Mutex::new(vec![]);
38//!
39//! fn callback(solutions: HashMap<VarName,Constant>) -> bool {
40//! let mut guard = ALL_SOLUTIONS.lock().unwrap();
41//! guard.push(solutions);
42//! true
43//! }
44//!
45//! // Build and run the model.
46//! let mut model = Model::new();
47//! model
48//! .named_variables
49//! .add_var("x".to_owned(), VarDomain::Bound(1, 3));
50//! model
51//! .named_variables
52//! .add_var("y".to_owned(), VarDomain::Bound(2, 4));
53//! model
54//! .named_variables
55//! .add_var("z".to_owned(), VarDomain::Bound(1, 5));
56//!
57//! let leq = Constraint::SumLeq(
58//! vec![
59//! Var::NameRef("x".to_owned()),
60//! Var::NameRef("y".to_owned()),
61//! Var::NameRef("z".to_owned()),
62//! ],
63//! Var::ConstantAsVar(4),
64//! );
65//!
66//! let geq = Constraint::SumGeq(
67//! vec![
68//! Var::NameRef("x".to_owned()),
69//! Var::NameRef("y".to_owned()),
70//! Var::NameRef("z".to_owned()),
71//! ],
72//! Var::ConstantAsVar(4),
73//! );
74//!
75//! let ineq = Constraint::Ineq(
76//! Var::NameRef("x".to_owned()),
77//! Var::NameRef("y".to_owned()),
78//! Constant::Integer(-1),
79//! );
80//!
81//! model.constraints.push(leq);
82//! model.constraints.push(geq);
83//! model.constraints.push(ineq);
84//!
85//! let res = run_minion(model, callback);
86//! res.expect("Error occurred");
87//!
88//! // Get solutions
89//! let guard = ALL_SOLUTIONS.lock().unwrap();
90//! let solution_set_1 = &(guard.get(0).unwrap());
91//!
92//! let x1 = solution_set_1.get("x").unwrap();
93//! let y1 = solution_set_1.get("y").unwrap();
94//! let z1 = solution_set_1.get("z").unwrap();
95//!
96//! assert_eq!(guard.len(),1);
97//! assert_eq!(*x1,Constant::Integer(1));
98//! assert_eq!(*y1,Constant::Integer(2));
99//! assert_eq!(*z1,Constant::Integer(1));
100//! ```
101//!
102//! ## `PRINT` and `VARORDER`
103//!
104//! These bindings have no replacement for Minion's `PRINT` and `VARORDER` statements - any
105//! variable given to the model that does not have a constant value is considered a search
106//! variable. Solutions are returned through the [callback function](Callback) as a `HashMap`.
107
108pub use run::*;
109
110pub mod error;
111mod ffi;
112
113pub mod ast;
114mod run;
115
116mod scoped_ptr;
117
118mod wrappers;
119pub use wrappers::*;