use crate::DeterministicAutomatonBlueprint;
pub trait MutationAutomatonBlueprint {
type State: Clone;
type Alphabet: PartialEq;
type StateSort;
type ErrorType;
fn initial_mutation_state(&self) -> Self::State;
fn mutation_state_sort_map(&self, state: &Self::State) -> Result<Self::StateSort,Self::ErrorType>;
fn mutation_transition_map(&self, state: &mut Self::State, character: &Self::Alphabet) -> Result<(),Self::ErrorType>;
fn mutation_characterise(&self, word: &[Self::Alphabet]) -> Result<Self::StateSort, Self::ErrorType>
where
Self: Sized
{
let mut automaton = self.mutation_automaton();
for character in word {
automaton.update_state(character)?;
}
automaton.current_state_sort()
}
fn mutation_automaton(&self) -> MutationAutomaton<'_, Self>
where
Self: Sized
{
MutationAutomaton::new(self)
}
}
pub struct MutationAutomaton<'a, Blueprint:MutationAutomatonBlueprint> {
blueprint: &'a Blueprint,
current_state: Blueprint::State
}
impl<'a, Blueprint:MutationAutomatonBlueprint> MutationAutomaton<'a, Blueprint> {
pub fn new(blueprint: &'a Blueprint) -> Self {
Self {
blueprint,
current_state: blueprint.initial_mutation_state()
}
}
pub fn current_state_sort(&self) -> Result<Blueprint::StateSort,Blueprint::ErrorType> {
self.blueprint.mutation_state_sort_map(&self.current_state)
}
pub fn update_state(&mut self, character: &Blueprint::Alphabet) -> Result<(), Blueprint::ErrorType> {
self.blueprint.mutation_transition_map(&mut self.current_state, character)
}
pub fn update_sort_state(&mut self, character: &Blueprint::Alphabet) -> Result<Blueprint::StateSort, Blueprint::ErrorType> {
self.update_state(character)?;
self.current_state_sort()
}
pub fn view_state(&'a self) -> &'a Blueprint::State {
&self.current_state
}
pub fn take_state(self) -> Blueprint::State {
self.current_state
}
}
impl<Blueprint: DeterministicAutomatonBlueprint> MutationAutomatonBlueprint for Blueprint {
type State = Blueprint::State;
type Alphabet = Blueprint::Alphabet;
type StateSort = Blueprint::StateSort;
type ErrorType = Blueprint::ErrorType;
fn initial_mutation_state(&self) -> Self::State {
self.initial_state()
}
fn mutation_state_sort_map(&self, state: &Self::State) -> Result<Self::StateSort,Self::ErrorType> {
self.state_sort_map(state)
}
fn mutation_transition_map(&self, state: &mut Self::State, character: &Self::Alphabet) -> Result<(),Self::ErrorType> {
*state = self.transition_map(state, character)?;
Ok(())
}
}