pub mod a_star;
pub use a_star::{AStar, AStarConnect};
pub mod dijkstra;
pub use dijkstra::{BackwardDijkstra, Dijkstra};
pub mod tree;
pub mod path;
pub use path::Path;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SearchStatus<Solution> {
Incomplete,
Impossible,
Solved(Solution),
}
impl<S> SearchStatus<S> {
pub fn incomplete(&self) -> bool {
matches!(self, SearchStatus::Incomplete)
}
pub fn impossible(&self) -> bool {
matches!(self, SearchStatus::Impossible)
}
pub fn solved(&self) -> bool {
matches!(self, SearchStatus::Solved(_))
}
pub fn solution(self) -> Option<S> {
match self {
Self::Solved(solution) => Some(solution),
_ => None,
}
}
pub fn map<U, F: FnOnce(S) -> U>(self, op: F) -> SearchStatus<U> {
match self {
SearchStatus::Solved(solution) => SearchStatus::Solved(op(solution)),
SearchStatus::Incomplete => SearchStatus::Incomplete,
SearchStatus::Impossible => SearchStatus::Impossible,
}
}
pub fn and_then<U, E, F: FnOnce(S) -> Result<U, E>>(self, op: F) -> Result<SearchStatus<U>, E> {
match self {
SearchStatus::Solved(solution) => Ok(SearchStatus::Solved(op(solution)?)),
SearchStatus::Incomplete => Ok(SearchStatus::Incomplete),
SearchStatus::Impossible => Ok(SearchStatus::Impossible),
}
}
}
impl<S> From<S> for SearchStatus<S> {
fn from(value: S) -> Self {
SearchStatus::Solved(value)
}
}
pub trait Algorithm {
type Memory;
}
pub trait Coherent<Start, Goal>: Algorithm {
type InitError;
fn initialize(&self, start: Start, goal: &Goal) -> Result<Self::Memory, Self::InitError>;
}
pub trait Solvable<Goal>: Algorithm + Sized {
type Solution;
type StepError;
fn step(
&self,
memory: &mut Self::Memory,
goal: &Goal,
) -> Result<SearchStatus<Self::Solution>, Self::StepError>;
}
use std::sync::Arc;
impl<Algo: Algorithm> Algorithm for Arc<Algo> {
type Memory = Algo::Memory;
}
impl<Start, Goal, Algo: Coherent<Start, Goal>> Coherent<Start, Goal> for Arc<Algo> {
type InitError = Algo::InitError;
fn initialize(&self, start: Start, goal: &Goal) -> Result<Self::Memory, Self::InitError> {
self.as_ref().initialize(start, goal)
}
}
impl<Goal, Algo: Solvable<Goal>> Solvable<Goal> for Arc<Algo> {
type Solution = Algo::Solution;
type StepError = Algo::StepError;
fn step(
&self,
memory: &mut Self::Memory,
goal: &Goal,
) -> Result<SearchStatus<Self::Solution>, Self::StepError> {
self.as_ref().step(memory, goal)
}
}
pub trait QueueLength {
fn queue_length(&self) -> usize;
}
pub trait MinimumCostBound {
type Cost;
fn minimum_cost_bound(&self) -> Option<Self::Cost>;
}