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
1
//! 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
1
//!     let mut guard = ALL_SOLUTIONS.lock().unwrap();
41
1
//!     guard.push(solutions);
42
1
//!     true
43
1
//! }
44
1
//!
45
//! // Build and run the model.
46
//! let mut model = Model::new();
47
1
//! model
48
1
//!     .named_variables
49
1
//!     .add_var("x".to_owned(), VarDomain::Bound(1, 3));
50
1
//! model
51
1
//!     .named_variables
52
1
//!     .add_var("y".to_owned(), VarDomain::Bound(2, 4));
53
1
//! model
54
1
//!     .named_variables
55
1
//!     .add_var("z".to_owned(), VarDomain::Bound(1, 5));
56
1
//!
57
1
//! let leq = Constraint::SumLeq(
58
1
//!     vec![
59
1
//!         Var::NameRef("x".to_owned()),
60
1
//!         Var::NameRef("y".to_owned()),
61
1
//!         Var::NameRef("z".to_owned()),
62
1
//!     ],
63
1
//!     Var::ConstantAsVar(4),
64
1
//! );
65
1
//!
66
1
//! let geq = Constraint::SumGeq(
67
1
//!     vec![
68
1
//!         Var::NameRef("x".to_owned()),
69
1
//!         Var::NameRef("y".to_owned()),
70
1
//!         Var::NameRef("z".to_owned()),
71
1
//!     ],
72
1
//!     Var::ConstantAsVar(4),
73
1
//! );
74
1
//!
75
1
//! let ineq = Constraint::Ineq(
76
1
//!     Var::NameRef("x".to_owned()),
77
1
//!     Var::NameRef("y".to_owned()),
78
1
//!     Constant::Integer(-1),
79
1
//! );
80
1
//!
81
1
//! model.constraints.push(leq);
82
1
//! model.constraints.push(geq);
83
1
//! model.constraints.push(ineq);
84
1
//!
85
1
//! let res = run_minion(model, callback);
86
1
//! res.expect("Error occurred");
87
1
//!
88
1
//! // Get solutions
89
1
//! let guard = ALL_SOLUTIONS.lock().unwrap();
90
1
//! let solution_set_1 = &(guard.get(0).unwrap());
91
1
//!
92
1
//! let x1 = solution_set_1.get("x").unwrap();
93
1
//! let y1 = solution_set_1.get("y").unwrap();
94
1
//! let z1 = solution_set_1.get("z").unwrap();
95
1
//!
96
1
//! assert_eq!(guard.len(),1);
97
1
//! assert_eq!(*x1,Constant::Integer(1));
98
1
//! assert_eq!(*y1,Constant::Integer(2));
99
1
//! assert_eq!(*z1,Constant::Integer(1));
100
1
//! ```
101
1
//!
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

            
108
pub use run::*;
109

            
110
pub mod error;
111
mod ffi;
112

            
113
pub mod ast;
114
mod run;
115

            
116
mod scoped_ptr;
117

            
118
mod wrappers;
119
pub use wrappers::*;