pub mod flow;
pub mod state;
pub(crate) mod build;
mod reduce;
pub use self::build::Build;
pub use self::state::{State, StateId, StateRange, StateSet};
pub(crate) use self::flow::FlowSet;
use std::collections::HashMap;
use std::fmt::{self, Debug};
use std::hash::BuildHasherDefault;
use seahash::SeaHasher;
use crate::{biunify, Constructor, ConstructorSet, Polarity};
pub struct Automaton<C: Constructor> {
pub(crate) states: Vec<State<C>>,
pub(crate) biunify_cache:
HashMap<(StateId, StateId), biunify::CacheEntry<C>, BuildHasherDefault<SeaHasher>>,
}
impl<C: Constructor> Automaton<C> {
pub fn new() -> Self {
Automaton {
states: Vec::new(),
biunify_cache: HashMap::default(),
}
}
pub fn clone_states<I>(&mut self, states: I) -> StateRange
where
I: IntoIterator<Item = (StateId, Polarity)>,
{
let mut reduced = Automaton::new();
let range = reduced.reduce(&self, states);
let offset = self.add_from(&reduced);
#[cfg(debug_assertions)]
debug_assert!(self.check_flow());
range.shift(offset)
}
pub(crate) fn merge(&mut self, pol: Polarity, target_id: StateId, source_id: StateId) {
if target_id != source_id {
let (target, source) = self.index_mut2(target_id, source_id);
#[cfg(debug_assertions)]
debug_assert_eq!(target.pol, pol);
#[cfg(debug_assertions)]
debug_assert_eq!(source.pol, pol);
target.cons.merge(&source.cons, pol);
self.merge_flow(pol, target_id, source_id);
}
}
}
impl<C: Constructor> Default for Automaton<C> {
fn default() -> Self {
Automaton::new()
}
}
impl<C> fmt::Debug for Automaton<C>
where
C: Constructor + Debug,
C::Label: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Automaton")
.field("states", &self.states)
.field("biunify_cache", &self.biunify_cache)
.finish()
}
}