1use std::fmt;
2use std::collections::{hash_set, hash_map, HashSet, HashMap};
3use terms::{
4 PatternLike,
5 PatternLikeKind
6};
7
8use crate::{
9 utils::combinations,
10 Symbol,
11 State,
12 Label,
13 Ranked,
14 NoLabel,
15 Labeled,
16 Language,
17 ConfigurationIterator
19};
20
21pub mod macros;
22pub mod search;
23pub mod width_search;
24
25pub use search::*;
26pub use width_search::*;
27
28#[derive(Hash, PartialEq, Eq, Clone, Debug)]
30pub struct Configuration<F, Q: State>(pub F, pub Vec<Q>);
31
32impl<F, Q: State> Configuration<F, Q> {
33 pub fn symbol(&self) -> &F {
34 &self.0
35 }
36
37 pub fn states(&self) -> &[Q] {
38 &self.1
39 }
40
41 pub fn len(&self) -> usize {
42 self.1.len()
43 }
44
45 pub fn signature(&self) -> (&F, usize) {
46 (&self.0, self.1.len())
47 }
48
49 pub fn map<R: State, M>(&self, g: M) -> Configuration<F, R> where M: Fn(&Q) -> R, F: Clone {
50 let states = self.1.iter().map(|q| g(q)).collect();
51 Configuration(self.0.clone(), states)
52 }
53}
54
55impl<F: fmt::Display, Q: State + fmt::Display> fmt::Display for Configuration<F, Q> {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 self.0.fmt(f)?;
58 match self.1.split_first() {
59 Some((head, tail)) => {
60 write!(f, "({}", head)?;
61 for e in tail.iter() {
62 write!(f, ", {}", e)?;
63 }
64 write!(f, ")")
65 },
66 None => Ok(())
67 }
68 }
69}
70
71pub type Configurations<'a, F, Q, L> = hash_set::Iter<'a, Labeled<Configuration<F, Q>, L>>;
72
73pub struct Transifions<'a, F, Q: State, L: Label> {
74 it: hash_map::Iter<'a, Q, HashSet<Labeled<Configuration<F, Q>, L>>>,
75 current: Option<(&'a Q, Configurations<'a, F, Q, L>)>
76}
77
78impl<'a, F, Q: State, L: Label> Transifions<'a, F, Q, L> {
79 fn new(aut: &'a Automaton<F, Q, L>) -> Transifions<'a, F, Q, L> {
80 Transifions {
81 it: aut.state_configurations.iter(),
82 current: None
83 }
84 }
85}
86
87impl<'a, F, Q: State, L: Label> Iterator for Transifions<'a, F, Q, L> {
88 type Item = (&'a Configuration<F, Q>, &'a L, &'a Q);
89
90 fn next(&mut self) -> Option<Self::Item> {
91 loop {
92 match self.current {
93 Some((q, ref mut configurations)) => {
94 match configurations.next() {
95 Some((configuration, label)) => {
96 return Some((configuration, label, q))
97 },
98 None => self.current = None
99 }
100 },
101 None => {
102 match self.it.next() {
103 Some((q, configurations)) => self.current = Some((q, configurations.iter())),
104 None => return None
105 }
106 }
107 }
108 }
109 }
110}
111
112#[derive(Clone)]
114pub struct Automaton<F, Q: State, L: Label> {
115 dummy_states: HashSet<Labeled<Q, L>>,
117
118 dummy_configurations: HashSet<Labeled<Configuration<F, Q>, L>>,
120
121 configuration_states: HashMap<Configuration<F, Q>, HashSet<Labeled<Q, L>>>,
123
124 state_configurations: HashMap<Q, HashSet<Labeled<Configuration<F, Q>, L>>>,
126
127 final_states: HashSet<Q>
132}
133
134pub type States<'a, F, Q, L> = hash_map::Keys<'a, Q, HashSet<Labeled<Configuration<F, Q>, L>>>;
135
136impl<F: Symbol, Q: State, L: Label> Language<F> for Automaton<F, Q, L> {
137 }
139
140impl<F: Symbol, Q: State, L: Label> Automaton<F, Q, L> {
141 pub fn new() -> Automaton<F, Q, L> {
145 Automaton {
146 dummy_states: HashSet::new(),
147 dummy_configurations: HashSet::new(),
148 configuration_states: HashMap::new(),
149 state_configurations: HashMap::new(),
150 final_states: HashSet::new()
152 }
153 }
154
155 pub fn len(&self) -> usize {
157 self.state_configurations.len()
158 }
159
160 pub fn states(&self) -> States<F, Q, L> {
161 self.state_configurations.keys()
162 }
163
164 pub fn final_states(&self) -> hash_set::Iter<Q> {
166 self.final_states.iter()
167 }
168
169 pub fn set_final(&mut self, q: Q) -> bool {
173 self.final_states.insert(q)
174 }
175
176 pub fn includes(&self, q: &Q) -> bool {
179 self.state_configurations.get(q).is_some()
180 }
181
182 pub fn transitions(&self) -> Transifions<F, Q, L> {
183 Transifions::new(self)
184 }
185
186 pub fn configurations_for_state(&self, q: &Q) -> Configurations<F, Q, L> {
188 match self.state_configurations.get(q) {
189 Some(confs) => confs.iter(),
190 None => self.dummy_configurations.iter()
191 }
192 }
193
194 pub fn states_for_configuration(&self, conf: &Configuration<F, Q>) -> hash_set::Iter<Labeled<Q, L>> {
213 match self.configuration_states.get(conf) {
214 Some(states) => states.iter(),
215 None => self.dummy_states.iter()
216 }
217 }
218
219 pub fn add(&mut self, conf: Configuration<F, Q>, label: L, state: Q) {
221 match self.configuration_states.get_mut(&conf) {
222 Some(states) => {
223 states.insert((state.clone(), label.clone()));
224 },
225 None => {
226 let mut states = HashSet::new();
227 states.insert((state.clone(), label.clone()));
228 self.configuration_states.insert(conf.clone(), states);
229 }
230 }
231
232 match self.state_configurations.get_mut(&state) {
244 Some(configurations) => {
245 configurations.insert((conf, label));
246 },
247 None => {
248 let mut configurations = HashSet::new();
249 configurations.insert((conf, label));
250 self.state_configurations.insert(state, configurations);
251 }
252 }
253 }
254
255 pub fn add_normalized<P: PatternLike<F, Q>, N>(&mut self, pattern: &P, normalizer: &mut N) -> Q
258 where N: FnMut(&Configuration<F, Q>) -> Labeled<Q, L> {
259 match pattern.kind() {
260 PatternLikeKind::Cons(f, l) => {
261 let mut normalized_l = Vec::with_capacity(l.len());
262 for sub_conf in l.iter() {
263 let q = match sub_conf.kind() {
264 PatternLikeKind::Var(q) => q.clone(),
265 _ => {
266 self.add_normalized(sub_conf, normalizer)
267 }
268 };
269 normalized_l.push(q);
270 }
271
272 let normalized_conf = Configuration(f.clone(), normalized_l);
273
274 if let Some((state, _)) = self.states_for_configuration(&normalized_conf).next() {
275 state.clone()
276 } else {
277 let (state, label) = (*normalizer)(&normalized_conf);
278 self.add(normalized_conf, label, state.clone());
279 state
280 }
281 },
282 PatternLikeKind::Var(_) => {
283 panic!("epsilon transitions are not allowed!")
284 }
285 }
286 }
287
288 pub fn common_configurations<'a>(
295 automata: &'a [&'a Automaton<F, Q, L>],
296 positions: &'a [Q]
297 ) -> CommonConfigurations<'a, F, Q, L> {
298 CommonConfigurations::new(automata, positions)
299 }
300
301 pub fn representatives(&self) -> Representatives<F, Q, L> {
319 Representatives::new(self)
320 }
321
322 pub fn complement(&mut self) {
326 let states: HashSet<Q> = self.states().cloned().collect();
327 let new_final_states = states.difference(&self.final_states).cloned().collect();
328 self.final_states = new_final_states;
329 }
330
331 pub fn alphabet(&self) -> HashSet<F> {
333 let mut alphabet = HashSet::new();
334 for (Configuration(f, _), _, _) in self.transitions() {
335 alphabet.insert(f.clone());
336 }
337
338 alphabet
339 }
340
341 pub fn map_states<R: State, M>(&self, g: M) -> Automaton<F, R, L> where M: Fn(&Q) -> R {
342 let mut configuration_states: HashMap<Configuration<F, R>, HashSet<Labeled<R, L>>> = HashMap::new();
343 for (conf, states) in self.configuration_states.iter() {
344 let conf = conf.map(|q| g(q));
345 let states: HashSet<Labeled<R, L>> = states.iter().map(|(q, l)| (g(q), l.clone())).collect();
346 match configuration_states.get_mut(&conf) {
347 Some(conf_states) => {
348 conf_states.extend(states.into_iter());
349 },
350 None => {
351 configuration_states.insert(conf, states);
352 }
353 }
354 }
355
356 let mut state_configurations: HashMap<R, HashSet<Labeled<Configuration<F, R>, L>>> = HashMap::new();
357 for (state, confs) in self.state_configurations.iter() {
358 let state = g(state);
359 let confs: HashSet<Labeled<Configuration<F, R>, L>> = confs.iter().map(|(conf, l)| (conf.map(|q| g(q)), l.clone())).collect();
360 match state_configurations.get_mut(&state) {
361 Some(state_confs) => {
362 state_confs.extend(confs.into_iter());
363 },
364 None => {
365 state_configurations.insert(state, confs);
366 }
367 }
368 }
369
370 let mut final_states = HashSet::new();
371 for q in self.final_states.iter() {
372 final_states.insert(g(q));
373 }
374
375 Automaton {
376 dummy_states: HashSet::new(),
377 dummy_configurations: HashSet::new(),
378 configuration_states: configuration_states,
379 state_configurations: state_configurations,
380 final_states: final_states
381 }
382 }
383}
384
385impl<F: Symbol, Q: State> Automaton<F, Q, NoLabel> {
386 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> {
390 let mut states: Vec<Q> = self.states().map(|q| (*q).clone()).collect();
391 states.extend(lang.states().map(|r| r.clone().into()));
392
393 for f in alphabet {
394 let indexes: Vec<usize> = (0..f.arity()).collect();
395 for states in combinations(&indexes, |_| states.clone().into_iter()) {
396 let conf = Configuration(f.clone(), states.clone());
397 match self.states_for_configuration(&conf).next() {
398 Some(_) => (),
399 None => {
400 let parent_states: Vec<R> = states.iter().map(|q| (*q).clone().into()).collect();
401 if let Some((r, _)) = lang.states_for_configuration(&Configuration(f.clone(), parent_states)).next() {
402 self.add(conf, NoLabel, (*r).clone().into());
403 }
404 }
405 }
406 }
407 }
408 }
409}
410
411pub struct CloneConfigurations<'a, F: Symbol, Q: State, L: Label> {
416 it: Configurations<'a, F, Q, L>
417}
418
419impl<'a, F: Symbol, Q: State, L: Label> Iterator for CloneConfigurations<'a, F, Q, L> {
420 type Item = Configuration<F, Q>;
421
422 fn next(&mut self) -> Option<Configuration<F, Q>> {
423 match self.it.next() {
424 Some((conf, _)) => Some(conf.clone()),
425 None => None
426 }
427 }
428}
429
430impl<'a, F: Symbol, Q: State, L: Label> ConfigurationIterator<'a, F, Q> for CloneConfigurations<'a, F, Q, L> {
431 }
433
434impl<F: Symbol + fmt::Display, Q: State + fmt::Display, L: Label + fmt::Display> fmt::Display for Automaton<F, Q, L> {
446 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
447 for (conf, label, q) in self.transitions() {
448 write!(f, "{} -{}-> {}\n", conf, label, q)?;
449 }
450 write!(f, "final states: ")?;
451 for q in self.final_states() {
452 write!(f, "{} ", q)?;
453 }
454 Ok(())
455 }
456}