#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SearchStep<State> {
Continue(State),
Pruned {
reason: String,
},
Infeasible {
reason: String,
},
}
impl<State> SearchStep<State> {
pub fn pruned(reason: impl Into<String>) -> Self {
Self::Pruned {
reason: reason.into(),
}
}
pub fn infeasible(reason: impl Into<String>) -> Self {
Self::Infeasible {
reason: reason.into(),
}
}
}
pub trait SearchInterrupt {
fn is_cancelled(&self) -> bool;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct NeverInterrupt;
impl SearchInterrupt for NeverInterrupt {
fn is_cancelled(&self) -> bool {
false
}
}
pub trait SearchProblem {
type State: Clone;
type Choice: Clone + Ord;
type Output: Clone + std::fmt::Debug;
fn initial_state(&self) -> Self::State;
fn expand(&self, state: &Self::State, out: &mut Vec<Self::Choice>);
fn apply(&self, state: &Self::State, choice: &Self::Choice) -> SearchStep<Self::State>;
fn propagate(&self, state: Self::State) -> SearchStep<Self::State> {
SearchStep::Continue(state)
}
fn finish(&self, state: &Self::State) -> Option<Self::Output>;
fn score_state(&self, _state: &Self::State) -> i64 {
0
}
fn estimate_remaining(&self, _state: &Self::State) -> i64 {
0
}
fn bound(&self, _state: &Self::State) -> Option<i64> {
None
}
fn output_score(&self, _output: &Self::Output) -> Option<i64> {
None
}
}