use std::fmt;
use std::collections::{hash_set, hash_map, HashSet, HashMap};
use terms::{
PatternLike,
PatternLikeKind
};
use crate::{
utils::combinations,
Symbol,
State,
Label,
Ranked,
NoLabel,
Labeled,
Language,
ConfigurationIterator
};
pub mod macros;
pub mod search;
pub mod width_search;
pub use search::*;
pub use width_search::*;
#[derive(Hash, PartialEq, Eq, Clone, Debug)]
pub struct Configuration<F, Q: State>(pub F, pub Vec<Q>);
impl<F, Q: State> Configuration<F, Q> {
pub fn symbol(&self) -> &F {
&self.0
}
pub fn states(&self) -> &[Q] {
&self.1
}
pub fn len(&self) -> usize {
self.1.len()
}
pub fn signature(&self) -> (&F, usize) {
(&self.0, self.1.len())
}
pub fn map<R: State, M>(&self, g: M) -> Configuration<F, R> where M: Fn(&Q) -> R, F: Clone {
let states = self.1.iter().map(|q| g(q)).collect();
Configuration(self.0.clone(), states)
}
}
impl<F: fmt::Display, Q: State + fmt::Display> fmt::Display for Configuration<F, Q> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)?;
match self.1.split_first() {
Some((head, tail)) => {
write!(f, "({}", head)?;
for e in tail.iter() {
write!(f, ", {}", e)?;
}
write!(f, ")")
},
None => Ok(())
}
}
}
pub type Configurations<'a, F, Q, L> = hash_set::Iter<'a, Labeled<Configuration<F, Q>, L>>;
pub struct Transifions<'a, F, Q: State, L: Label> {
it: hash_map::Iter<'a, Q, HashSet<Labeled<Configuration<F, Q>, L>>>,
current: Option<(&'a Q, Configurations<'a, F, Q, L>)>
}
impl<'a, F, Q: State, L: Label> Transifions<'a, F, Q, L> {
fn new(aut: &'a Automaton<F, Q, L>) -> Transifions<'a, F, Q, L> {
Transifions {
it: aut.state_configurations.iter(),
current: None
}
}
}
impl<'a, F, Q: State, L: Label> Iterator for Transifions<'a, F, Q, L> {
type Item = (&'a Configuration<F, Q>, &'a L, &'a Q);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.current {
Some((q, ref mut configurations)) => {
match configurations.next() {
Some((configuration, label)) => {
return Some((configuration, label, q))
},
None => self.current = None
}
},
None => {
match self.it.next() {
Some((q, configurations)) => self.current = Some((q, configurations.iter())),
None => return None
}
}
}
}
}
}
#[derive(Clone)]
pub struct Automaton<F, Q: State, L: Label> {
dummy_states: HashSet<Labeled<Q, L>>,
dummy_configurations: HashSet<Labeled<Configuration<F, Q>, L>>,
configuration_states: HashMap<Configuration<F, Q>, HashSet<Labeled<Q, L>>>,
state_configurations: HashMap<Q, HashSet<Labeled<Configuration<F, Q>, L>>>,
final_states: HashSet<Q>
}
pub type States<'a, F, Q, L> = hash_map::Keys<'a, Q, HashSet<Labeled<Configuration<F, Q>, L>>>;
impl<F: Symbol, Q: State, L: Label> Language<F> for Automaton<F, Q, L> {
}
impl<F: Symbol, Q: State, L: Label> Automaton<F, Q, L> {
pub fn new() -> Automaton<F, Q, L> {
Automaton {
dummy_states: HashSet::new(),
dummy_configurations: HashSet::new(),
configuration_states: HashMap::new(),
state_configurations: HashMap::new(),
final_states: HashSet::new()
}
}
pub fn len(&self) -> usize {
self.state_configurations.len()
}
pub fn states(&self) -> States<F, Q, L> {
self.state_configurations.keys()
}
pub fn final_states(&self) -> hash_set::Iter<Q> {
self.final_states.iter()
}
pub fn set_final(&mut self, q: Q) -> bool {
self.final_states.insert(q)
}
pub fn includes(&self, q: &Q) -> bool {
self.state_configurations.get(q).is_some()
}
pub fn transitions(&self) -> Transifions<F, Q, L> {
Transifions::new(self)
}
pub fn configurations_for_state(&self, q: &Q) -> Configurations<F, Q, L> {
match self.state_configurations.get(q) {
Some(confs) => confs.iter(),
None => self.dummy_configurations.iter()
}
}
pub fn states_for_configuration(&self, conf: &Configuration<F, Q>) -> hash_set::Iter<Labeled<Q, L>> {
match self.configuration_states.get(conf) {
Some(states) => states.iter(),
None => self.dummy_states.iter()
}
}
pub fn add(&mut self, conf: Configuration<F, Q>, label: L, state: Q) {
match self.configuration_states.get_mut(&conf) {
Some(states) => {
states.insert((state.clone(), label.clone()));
},
None => {
let mut states = HashSet::new();
states.insert((state.clone(), label.clone()));
self.configuration_states.insert(conf.clone(), states);
}
}
match self.state_configurations.get_mut(&state) {
Some(configurations) => {
configurations.insert((conf, label));
},
None => {
let mut configurations = HashSet::new();
configurations.insert((conf, label));
self.state_configurations.insert(state, configurations);
}
}
}
pub fn add_normalized<P: PatternLike<F, Q>, N>(&mut self, pattern: &P, normalizer: &mut N) -> Q
where N: FnMut(&Configuration<F, Q>) -> Labeled<Q, L> {
match pattern.kind() {
PatternLikeKind::Cons(f, l) => {
let mut normalized_l = Vec::with_capacity(l.len());
for sub_conf in l.iter() {
let q = match sub_conf.kind() {
PatternLikeKind::Var(q) => q.clone(),
_ => {
self.add_normalized(sub_conf, normalizer)
}
};
normalized_l.push(q);
}
let normalized_conf = Configuration(f.clone(), normalized_l);
if let Some((state, _)) = self.states_for_configuration(&normalized_conf).next() {
state.clone()
} else {
let (state, label) = (*normalizer)(&normalized_conf);
self.add(normalized_conf, label, state.clone());
state
}
},
PatternLikeKind::Var(_) => {
panic!("epsilon transitions are not allowed!")
}
}
}
pub fn common_configurations<'a>(
automata: &'a [&'a Automaton<F, Q, L>],
positions: &'a [Q]
) -> CommonConfigurations<'a, F, Q, L> {
CommonConfigurations::new(automata, positions)
}
pub fn representatives(&self) -> Representatives<F, Q, L> {
Representatives::new(self)
}
pub fn complement(&mut self) {
let states: HashSet<Q> = self.states().cloned().collect();
let new_final_states = states.difference(&self.final_states).cloned().collect();
self.final_states = new_final_states;
}
pub fn alphabet(&self) -> HashSet<F> {
let mut alphabet = HashSet::new();
for (Configuration(f, _), _, _) in self.transitions() {
alphabet.insert(f.clone());
}
alphabet
}
pub fn map_states<R: State, M>(&self, g: M) -> Automaton<F, R, L> where M: Fn(&Q) -> R {
let mut configuration_states: HashMap<Configuration<F, R>, HashSet<Labeled<R, L>>> = HashMap::new();
for (conf, states) in self.configuration_states.iter() {
let conf = conf.map(|q| g(q));
let states: HashSet<Labeled<R, L>> = states.iter().map(|(q, l)| (g(q), l.clone())).collect();
match configuration_states.get_mut(&conf) {
Some(conf_states) => {
conf_states.extend(states.into_iter());
},
None => {
configuration_states.insert(conf, states);
}
}
}
let mut state_configurations: HashMap<R, HashSet<Labeled<Configuration<F, R>, L>>> = HashMap::new();
for (state, confs) in self.state_configurations.iter() {
let state = g(state);
let confs: HashSet<Labeled<Configuration<F, R>, L>> = confs.iter().map(|(conf, l)| (conf.map(|q| g(q)), l.clone())).collect();
match state_configurations.get_mut(&state) {
Some(state_confs) => {
state_confs.extend(confs.into_iter());
},
None => {
state_configurations.insert(state, confs);
}
}
}
let mut final_states = HashSet::new();
for q in self.final_states.iter() {
final_states.insert(g(q));
}
Automaton {
dummy_states: HashSet::new(),
dummy_configurations: HashSet::new(),
configuration_states: configuration_states,
state_configurations: state_configurations,
final_states: final_states
}
}
}
impl<F: Symbol, Q: State> Automaton<F, Q, NoLabel> {
pub fn complete_with<'a, A: Iterator<Item=&'a F>, R: State>(&mut self, alphabet: A, lang: &Automaton<F, R, NoLabel>) where F: 'a + Ranked, R: From<Q>, Q: From<R> {
let mut states: Vec<Q> = self.states().map(|q| (*q).clone()).collect();
states.extend(lang.states().map(|r| r.clone().into()));
for f in alphabet {
let indexes: Vec<usize> = (0..f.arity()).collect();
for states in combinations(&indexes, |_| states.clone().into_iter()) {
let conf = Configuration(f.clone(), states.clone());
match self.states_for_configuration(&conf).next() {
Some(_) => (),
None => {
let parent_states: Vec<R> = states.iter().map(|q| (*q).clone().into()).collect();
if let Some((r, _)) = lang.states_for_configuration(&Configuration(f.clone(), parent_states)).next() {
self.add(conf, NoLabel, (*r).clone().into());
}
}
}
}
}
}
}
pub struct CloneConfigurations<'a, F: Symbol, Q: State, L: Label> {
it: Configurations<'a, F, Q, L>
}
impl<'a, F: Symbol, Q: State, L: Label> Iterator for CloneConfigurations<'a, F, Q, L> {
type Item = Configuration<F, Q>;
fn next(&mut self) -> Option<Configuration<F, Q>> {
match self.it.next() {
Some((conf, _)) => Some(conf.clone()),
None => None
}
}
}
impl<'a, F: Symbol, Q: State, L: Label> ConfigurationIterator<'a, F, Q> for CloneConfigurations<'a, F, Q, L> {
}
impl<F: Symbol + fmt::Display, Q: State + fmt::Display, L: Label + fmt::Display> fmt::Display for Automaton<F, Q, L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (conf, label, q) in self.transitions() {
write!(f, "{} -{}-> {}\n", conf, label, q)?;
}
write!(f, "final states: ")?;
for q in self.final_states() {
write!(f, "{} ", q)?;
}
Ok(())
}
}