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;