From 1e91d985819e0274b710c392263da7d4c0baabf2 Mon Sep 17 00:00:00 2001 From: artus40 Date: Tue, 12 Feb 2019 14:15:27 +0100 Subject: [PATCH] adds solve_one --- planner/src/solver.rs | 33 +++++++++++++++++++++++++++++++++ web/src/main.rs | 27 ++++++++++++++------------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/planner/src/solver.rs b/planner/src/solver.rs index dd08a4b..75b9a39 100644 --- a/planner/src/solver.rs +++ b/planner/src/solver.rs @@ -144,6 +144,39 @@ impl<'a,V, K: Eq + Hash + Clone> Problem<'a, V, K> { }; solutions } + + pub fn solve_one(&mut self) -> Option> + where V: Clone + fmt::Debug, + K: Clone + fmt::Debug, + { + let mut stack: Vec> = vec![]; + stack.append(&mut self._push_updates().unwrap()); + loop { + let node = stack.pop(); + if node.is_none() { + return None; + }; + match node.unwrap() { + Assignment::Update(key, val) => { + // Assign the variable and open new branches, if any. + *self.variables.get_mut(&key).unwrap() = Some(val); + // TODO: handle case of empty domain.values + if let Some(mut nodes) = self._push_updates() { + stack.append(&mut nodes); + } else { + // Assignements are completed + if self._is_valid() { + return Some(self.variables.clone()); + }; + }; + }, + Assignment::Clear(key) => { + // We are closing this branch, unset the variable + *self.variables.get_mut(&key).unwrap() = None; + }, + }; + } + } } pub struct ProblemBuilder<'a, V, K>(Problem<'a, V, K>); diff --git a/web/src/main.rs b/web/src/main.rs index 6509386..01ee0a5 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -103,19 +103,20 @@ mod api { let mut problem = problem .add_constraint(|_| true) .finish(); - let results = problem.solve_all(); - let one_result = results.first().unwrap(); - - Json(TemplateObject { - items: one_result - .into_iter() - .map(|(k,v)| { - TemplateItems { - key: (format!("{}", k.0), format!("{:?}", k.1)), - value: v.map(|r| RecipeObject::from(&conn, r.clone())), - }}) - .collect(), - }) + if let Some(one_result) = problem.solve_one() { + Json(TemplateObject { + items: one_result + .into_iter() + .map(|(k,v)| { + TemplateItems { + key: (format!("{}", k.0), format!("{:?}", k.1)), + value: v.map(|r| RecipeObject::from(&conn, r.clone())), + }}) + .collect(), + }) + } else { + panic!("No solution at all !"); + } } }