From e5b16ae9551e345ca11748fee1a14bb65d93a1c3 Mon Sep 17 00:00:00 2001 From: artus40 Date: Tue, 19 Feb 2019 16:24:05 +0100 Subject: [PATCH] some more thinking... --- planner/src/rules.rs | 28 ++++++++++++++++++++++++---- planner/src/solver.rs | 11 ++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/planner/src/rules.rs b/planner/src/rules.rs index 145c7d7..1dc2767 100644 --- a/planner/src/rules.rs +++ b/planner/src/rules.rs @@ -19,14 +19,34 @@ //! Price //! - Per week : should restrict ingredients cost to a given amount -trait Rule { - type State; +enum Status { + Ok, + Violated, +} - fn check(&self, state: Self::State); - fn insights(&self, state: Self::State) -> Insight; +trait Rule { + type Key; + type Value; + + fn status(&self, state: (Vec<&Self::Key>, Vec<&Self::Value>)); + fn update(&self, idx: usize, value: Option) -> Option; }; struct AllDifferentMeals; + +impl Rule for AllDifferentMeals { + type State = Vec; + + fn status(&self, _: Self::State) -> Status { + Status::Ok // Always enforced by update rule + } + + fn update(&self, _: Self::State) -> Option { + // Returns a filter excluding this value from domain. + // so that it is impossible to select the same meal twice. + None + } +} struct FilterRecipeByMeals; // Essentially work on domain struct NutritionalByDayAverageReq; diff --git a/planner/src/solver.rs b/planner/src/solver.rs index 49b107f..4cea0de 100644 --- a/planner/src/solver.rs +++ b/planner/src/solver.rs @@ -180,6 +180,8 @@ impl<'p, V: PartialEq, K: Eq + Hash + Clone> Problem<'p, V, K> { /// a Clear to ensure the variable is unset before when leaving the branch. fn _push_updates(&self) -> Option>> { if let Some(idx) = self._next_assign() { + // TODO: Domain will filter possible values for us + // let values = self.domain.get(idx); let domain_values = self.domains .get(idx) .expect("No domain for variable !"); @@ -187,7 +189,6 @@ impl<'p, V: PartialEq, K: Eq + Hash + Clone> Problem<'p, V, K> { assert!(!domain_values.is_empty()); // Push a clear assignment first, just before going up the stack. let mut updates = vec![Assignment::Clear(idx.clone())]; - // TODO: should be able to filter domain values (inference, pertinence) domain_values.iter().for_each(|value| { updates.push( Assignment::Update(idx, *value) @@ -233,14 +234,14 @@ impl<'p, V: PartialEq, K: Eq + Hash + Clone> Problem<'p, V, K> { fn _assign(&mut self, idx: usize, value: Option<&'p V>) { self.variables[idx] = value; let var_key = &self.keys[idx]; + // TODO: manage dynamic filters on Domain + // let filters: Filter::Chain = self.constraints.iter_mut().map([...]).collect(); + // self.domain.set_global(idx, filters); self.constraints.iter_mut() .for_each(|c| { c.update(&var_key, value); }); - // Some thoughts: what if we used a stack of filters, - // for each variable, that is cleared, on every assign, - // and repopulated by aggregating update calls on constraints. - // Domain would then be filtered by ALL filters in these stacks. + } fn _solve(&mut self, limit: Option) -> Vec> {