Trying to organize it all :$

This commit is contained in:
2019-01-30 21:47:21 +01:00
parent 253045c742
commit d4454e7f16
2 changed files with 49 additions and 16 deletions

View File

@@ -5,28 +5,61 @@ extern crate planner;
use self::cookbook::*; use self::cookbook::*;
use self::cookbook::models::Recipe; use self::cookbook::models::Recipe;
use self::planner::solver::{Domain, Problem, Constraint, Variables}; use self::planner::solver::{Variables, Domain, Problem, Constraint};
/// We want a mapping of the week meals (matin, midi, soir) /// We want a mapping of the week meals (matin, midi, soir)
/// Breakfast => RecipeCategory::Breakfast
/// Lunch => RecipeCategory::MainCourse
/// Dinner => RecipeCategory::MainCourse
type Day = String;
enum Meals {
Breakfast(Day),
Lunch(Day),
Dinner(Day)
}
impl Into<String> for Meals {
fn into(self) -> String {
match self {
Meals::Breakfast(d) => format!("{}_Breakfast", d),
Meals::Lunch(d) => format!("{}_Lunch", d),
Meals::Dinner(d) => format!("{}_Dinner", d),
}
}
}
/// associated with filters for Domain, depending on recipes RecipeCategory /// associated with filters for Domain, depending on recipes RecipeCategory
enum RecipeCategory {
Breakfast,
MainCourse
}
/// It may also contains an initial value for each variable /// It may also contains an initial value for each variable
fn generate_variables<V>(domain: &Domain<V>) -> Vec<(String, &Domain<V>, Option<&V>)> {
let mut vars = Vec::new();
for day in &["Lundi", "Mardi", "Mercredi"] {
vars.push((Meals::Lunch(String::from(day)).into(), domain, None));
vars.push((Meals::Dinner(String::from(day)).into(), domain, None));
}
vars
}
fn ingredients_contains<'a>(assign: &Variables<'a,Recipe>) -> bool { fn ingredients_contains<'a>(assign: &Variables<'a,Recipe>) -> bool {
assign.get("Lundi_midi").unwrap().unwrap().ingredients.contains("Patates") assign.get("Lundi_Lunch").unwrap().unwrap().ingredients.contains("Patates")
&& assign.get("Mardi_midi").unwrap().unwrap().ingredients.contains("Patates") && !assign.get("Mardi_Lunch").unwrap().unwrap().ingredients.contains("Patates")
} }
fn get_planning_all_results() -> String { fn get_planning_all_results() -> String {
let conn = establish_connection(); let conn = establish_connection();
let possible_values = recipes::load_all(&conn); let possible_values = recipes::load_all(&conn);
let domain = Domain::new(possible_values); let domain = Domain::new(possible_values);
let mut problem = Problem::build() let mut problem = Problem::build();
.add_variable("Lundi_midi".to_string(), &domain, None) for (var, dom, ini) in generate_variables(&domain) {
.add_variable("Mardi_midi".to_string(), &domain, None) problem = problem.add_variable(var, dom, ini);
.add_constraint(ingredients_contains) }
.finish(); let mut problem = problem.add_constraint(ingredients_contains)
.finish();
let results = problem.solve_all(); let results = problem.solve_all();
format!("{:#?}\nTotal = {}", &results, results.len()) format!("{:#?}\nTotal = {}", &results.first(), results.len())
} }
fn main() { fn main() {

View File

@@ -13,7 +13,7 @@ enum Assignment<'a, V> {
Clear(String) Clear(String)
} }
type Domains<'a, V> = HashMap<String, &'a Domain<V>>;
/// The domain of values that can be assigned to variables /// The domain of values that can be assigned to variables
#[derive(Clone)] #[derive(Clone)]
pub struct Domain<V> { pub struct Domain<V> {
@@ -51,13 +51,14 @@ impl<V: fmt::Debug> fmt::Debug for Domain<V> {
} }
} }
pub type Constraint<'a,V> = fn(&Variables<'a,V>) -> bool; pub type Constraint<'a,V> = fn(&Variables<'a,V>) -> bool;
pub struct Problem<'a, V> { pub struct Problem<'a, V> {
/// The initial assignements map /// The initial assignements map
variables: Variables<'a, V>, variables: Variables<'a, V>,
/// Each variable has its associated domain /// Each variable has its associated domain
domains: HashMap<String, &'a Domain<V>>, domains: Domains<'a,V>,
/// Set of constraints to validate /// Set of constraints to validate
constraints: Vec<Constraint<'a,V>>, constraints: Vec<Constraint<'a,V>>,
} }
@@ -141,11 +142,10 @@ impl<'a, V> ProblemBuilder<'a, V> {
}) })
} }
pub fn add_variable(mut self, pub fn add_variable<S>(mut self, name: S, domain: &'a Domain<V>, value: Option<&'a V>) -> Self
name: String, where S: Into<String>
domain: &'a Domain<V>, {
value: Option<&'a V>, let name = name.into();
) -> Self {
self.0.variables.insert(name.clone(), value); self.0.variables.insert(name.clone(), value);
self.0.domains.insert(name, domain); self.0.domains.insert(name, domain);
self self