use crate::{Variable, Decision};
pub trait Problem {
type State;
fn nb_variables(&self) -> usize;
fn initial_state(&self) -> Self::State;
fn initial_value(&self) -> isize;
fn transition(&self, state: &Self::State, decision: Decision) -> Self::State;
fn transition_cost(&self, source: &Self::State, dest: &Self::State, decision: Decision) -> isize;
fn next_variable(&self, depth: usize, next_layer: &mut dyn Iterator<Item = &Self::State>)
-> Option<Variable>;
fn for_each_in_domain(&self, var: Variable, state: &Self::State, f: &mut dyn DecisionCallback);
fn is_impacted_by(&self, _var: Variable, _state: &Self::State) -> bool {
true
}
}
pub trait Relaxation {
type State;
fn merge(&self, states: &mut dyn Iterator<Item = &Self::State>) -> Self::State;
fn relax(
&self,
source: &Self::State,
dest: &Self::State,
new: &Self::State,
decision: Decision,
cost: isize,
) -> isize;
fn fast_upper_bound(&self, _state: &Self::State) -> isize {
isize::MAX
}
}
pub trait DecisionCallback {
fn apply(&mut self, decision: Decision);
}
impl <X: FnMut(Decision)> DecisionCallback for X {
fn apply(&mut self, decision: Decision) {
self(decision)
}
}
#[cfg(test)]
mod tests {
use crate::{Relaxation, DecisionCallback, Decision, Problem};
#[test]
fn by_default_fast_upperbound_yields_positive_max() {
let rlx = DummyRelax;
assert_eq!(isize::MAX, rlx.fast_upper_bound(&'x'));
}
#[test]
fn by_default_all_states_are_impacted_by_all_vars() {
let pb = DummyProblem;
assert!(pb.is_impacted_by(crate::Variable(10), &'x'));
}
#[test]
fn any_closure_is_a_decision_callback() {
let mut changed = false;
let chg = &mut changed;
let closure: &mut dyn DecisionCallback = &mut |_: Decision| {
*chg = true;
};
closure.apply(Decision{variable: crate::Variable(0), value: 4});
assert!(changed);
}
struct DummyProblem;
impl Problem for DummyProblem {
type State = char;
fn nb_variables(&self) -> usize {
todo!()
}
fn initial_state(&self) -> Self::State {
todo!()
}
fn initial_value(&self) -> isize {
todo!()
}
fn transition(&self, _: &Self::State, _: Decision) -> Self::State {
todo!()
}
fn transition_cost(&self, _: &Self::State, _: &Self::State, _: Decision) -> isize {
todo!()
}
fn next_variable(&self, _: usize, _: &mut dyn Iterator<Item = &Self::State>)
-> Option<crate::Variable> {
todo!()
}
fn for_each_in_domain(&self, _: crate::Variable, _: &Self::State, _: &mut dyn DecisionCallback) {
todo!()
}
}
struct DummyRelax;
impl Relaxation for DummyRelax {
type State = char;
fn merge(&self, _states: &mut dyn Iterator<Item = &Self::State>) -> Self::State {
todo!()
}
fn relax(
&self,
_source: &Self::State,
_dest: &Self::State,
_new: &Self::State,
_decision: crate::Decision,
_cost: isize,
) -> isize {
todo!()
}
}
}