1use std::{
2 collections::{HashMap, HashSet, VecDeque},
3 hash::Hash,
4};
5
6type Deltas<State, Transition> = HashMap<State, HashMap<Transition, HashSet<State>>>;
8
9enum Delta {
13 Delta,
14 IDelta,
15}
16
17pub type Dfa<State, Transition> = DeterministicFiniteAutomata<State, Transition>;
19
20#[derive(Debug, Clone)]
22pub struct DeterministicFiniteAutomata<State, Transition>
23where
24 State: Eq + Hash + Clone,
25 Transition: Eq + Hash + Clone,
26{
27 pub states: HashSet<State>,
29 sigma: HashSet<Transition>,
31 pub initial_states: HashMap<State, HashSet<Transition>>,
33 pub final_states: HashMap<State, HashSet<Transition>>,
35 delta: HashMap<State, HashMap<Transition, State>>,
38 idelta: HashMap<State, HashMap<Transition, State>>,
41}
42
43impl<State, Transition> DeterministicFiniteAutomata<State, Transition>
44where
45 State: Eq + Hash + Clone,
46 Transition: Eq + Hash + Clone,
47{
48 #[must_use]
50 pub fn new() -> Self {
51 Self {
52 states: HashSet::new(),
53 sigma: HashSet::new(),
54 initial_states: HashMap::new(),
55 final_states: HashMap::new(),
56 delta: HashMap::new(),
57 idelta: HashMap::new(),
58 }
59 }
60
61 pub fn add_state(&mut self, state: State) {
63 self.states.insert(state);
64 }
65
66 pub fn add_initial(&mut self, state: State, symbol: Transition) {
68 self.states.insert(state.clone());
69 if let Some(symbols) = self.initial_states.get_mut(&state) {
70 symbols.insert(symbol);
71 } else {
72 let mut symbols = HashSet::new();
73 symbols.insert(symbol);
74 self.initial_states.insert(state, symbols);
75 }
76 }
77
78 pub fn add_final(&mut self, state: State, symbol: Transition) {
80 self.states.insert(state.clone());
81 if let Some(symbols) = self.final_states.get_mut(&state) {
82 symbols.insert(symbol);
83 } else {
84 let mut symbols = HashSet::new();
85 symbols.insert(symbol);
86 self.final_states.insert(state, symbols);
87 }
88 }
89
90 pub fn add_sigma(&mut self, sigma: Transition) {
92 self.sigma.insert(sigma);
93 }
94
95 fn add_delta(&mut self, source: State, symbol: Transition, destination: State, delta: &Delta) {
96 let delta = match delta {
97 Delta::Delta => &mut self.delta,
98 Delta::IDelta => &mut self.idelta,
99 };
100 if let Some(transitions) = delta.get_mut(&source) {
101 if transitions.get_mut(&symbol).is_some() {
102 } else {
104 transitions.insert(symbol, destination);
105 }
106 } else {
107 let mut transitions = HashMap::new();
108 transitions.insert(symbol, destination);
109 delta.insert(source, transitions);
110 }
111 }
112
113 pub fn add_transition(&mut self, source: State, symbol: Transition, destination: State) {
115 self.add_sigma(symbol.clone());
117 self.add_delta(
118 source.clone(),
119 symbol.clone(),
120 destination.clone(),
121 &Delta::Delta,
122 );
123 self.add_delta(destination, symbol, source, &Delta::IDelta);
124 }
125
126 #[must_use]
128 pub fn productive_states(&self) -> HashSet<State> {
129 let mut stack: VecDeque<_> = self.final_states.keys().collect();
130 let mut productive = HashSet::new();
132 while let Some(state) = stack.pop_back() {
133 if productive.insert(state.clone()) {
134 if let Some(states) = self
135 .idelta
136 .get(state)
137 .map(std::collections::HashMap::values)
138 {
139 stack.extend(states)
140 }
141 }
142 }
143 productive
144 }
145
146 #[must_use]
150 pub fn non_productive_states(&self) -> HashSet<State> {
151 self.states
153 .difference(&self.productive_states())
154 .cloned()
155 .collect()
156 }
157
158 #[must_use]
160 pub fn useful_states(&self) -> HashSet<State> {
161 let productive = self.productive_states();
163 let mut stack: VecDeque<_> = self.initial_states.keys().collect();
164 let mut reachable = HashSet::new();
166 while let Some(state) = stack.pop_back() {
167 if reachable.insert(state.clone()) {
168 if let Some(states) = self.delta.get(state).map(std::collections::HashMap::values) {
169 stack.extend(states)
170 }
171 }
172 }
173 productive.intersection(&reachable).cloned().collect()
174 }
175
176 #[must_use]
180 pub fn non_useful_states(&self) -> HashSet<State> {
181 self.states
183 .difference(&self.useful_states())
184 .cloned()
185 .collect()
186 }
187}
188
189impl<State, Transition> Default for DeterministicFiniteAutomata<State, Transition>
191where
192 State: Eq + Hash + Clone,
193 Transition: Eq + Hash + Clone,
194{
195 fn default() -> Self {
197 Self::new()
198 }
199}
200
201#[cfg(test)]
203mod dfa_tests {
204 use super::test_traits::*;
205 use super::*;
206
207 fn setup_automata() -> Dfa<i32, usize> {
208 let mut dfa = Dfa::new();
209 let state_list = [1, 2, 3, 4, 5, 6, 7];
210 for &state in state_list.iter() {
211 dfa.add_state(state);
212 }
213 dfa.add_initial(1, 0);
214 dfa.add_final(7, 0);
215 let transition_list = [
216 (1, 2),
217 (1, 3),
218 (2, 6),
219 (3, 4),
220 (3, 5),
221 (3, 6),
222 (4, 5),
223 (5, 7),
224 (6, 7),
225 ];
226 for (idx, &(src, dst)) in transition_list.iter().enumerate() {
227 dfa.add_transition(src, idx + 1, dst);
228 }
229 dfa
230 }
231
232 fn setup_automata_loop() -> Dfa<i32, ()> {
233 let mut dfa = Dfa::new();
234 dfa.add_initial(1, ());
235 dfa.add_final(2, ());
236 dfa.add_transition(1, (), 2);
237 dfa.add_transition(2, (), 1);
238 dfa
239 }
240
241 #[test]
242 fn test_add_state() {
243 let dfa = setup_automata();
244 let expected_states = vec![1, 2, 3, 4, 5, 6, 7].into_hash_set();
245 let result_states = dfa.states;
246 assert_eq!(expected_states, result_states);
247 }
248
249 #[test]
250 fn test_add_initial_state() {
251 let dfa = setup_automata();
252 let expected_states = vec![1].into_hash_set();
253 let result_states: HashSet<i32> = dfa.initial_states.keys().map(|i| *i).collect();
254 assert_eq!(expected_states, result_states);
255 }
256
257 #[test]
258 fn test_add_final_state() {
259 let dfa = setup_automata();
260 let expected_states = vec![7].into_hash_set();
261 let result_states: HashSet<i32> = dfa.final_states.keys().map(|i| *i).collect();
262 assert_eq!(expected_states, result_states);
263 }
264
265 #[test]
266 fn test_add_transition() {
267 let dfa = setup_automata();
268 let expected_deltas = [
269 (1, 2),
270 (1, 3),
271 (2, 6),
272 (3, 4),
273 (3, 5),
274 (3, 6),
275 (4, 5),
276 (5, 7),
277 (6, 7),
278 ]
279 .iter()
280 .map(|t| t.to_owned())
281 .collect::<HashSet<_>>();
282 let expected_ideltas = expected_deltas
283 .iter()
284 .map(|(fst, snd)| (*snd, *fst))
285 .map(|t| t.to_owned())
286 .collect::<HashSet<_>>();
287 let mut result_deltas = HashSet::new();
288 for (src, transitions) in dfa.delta {
289 for &dst in transitions.values() {
290 result_deltas.insert((src, dst));
291 }
292 }
293 let mut result_ideltas = HashSet::new();
294 for (src, transitions) in dfa.idelta {
295 for &dst in transitions.values() {
296 result_ideltas.insert((src, dst));
297 }
298 }
299 assert_eq!(expected_deltas, result_deltas);
300 assert_eq!(expected_ideltas, result_ideltas);
301 }
302
303 #[test]
304 fn test_productive() {
305 let dfa = setup_automata();
306 let result = dfa.productive_states();
307 let expected = [1, 2, 3, 4, 5, 6, 7]
308 .iter()
309 .map(|i| i.to_owned())
310 .collect::<HashSet<i32>>();
311 assert_eq!(expected, result);
312 }
313
314 #[test]
315 fn test_productive_loop() {
316 let dfa = setup_automata_loop();
317 let result = dfa.productive_states();
318 let expected = [1, 2]
319 .iter()
320 .map(|i| i.to_owned())
321 .collect::<HashSet<i32>>();
322 assert_eq!(expected, result);
323 }
324
325 #[test]
326 fn test_useful() {
327 let dfa = setup_automata();
328 let result = dfa.useful_states();
329 let expected = [1, 2, 3, 4, 5, 6, 7]
330 .iter()
331 .map(|i| i.to_owned())
332 .collect::<HashSet<i32>>();
333 assert_eq!(expected, result);
334 }
335}
336
337pub type Nfa<State, Transition> = NonDeterministicFiniteAutomata<State, Transition>;
339
340#[derive(Debug, Clone)]
342pub struct NonDeterministicFiniteAutomata<State, Transition>
343where
344 State: Eq + Hash + Clone,
345 Transition: Eq + Hash + Clone,
346{
347 pub states: HashSet<State>,
349 sigma: HashSet<Transition>,
351 pub initial_states: HashMap<State, HashSet<Transition>>,
353 pub final_states: HashMap<State, HashSet<Transition>>,
355 delta: Deltas<State, Transition>,
358 idelta: Deltas<State, Transition>,
361}
362
363impl<State, Transition> NonDeterministicFiniteAutomata<State, Transition>
364where
365 State: Eq + Hash + Clone,
366 Transition: Eq + Hash + Clone,
367{
368 #[must_use]
370 pub fn new() -> Self {
371 Self {
372 states: HashSet::new(),
373 sigma: HashSet::new(),
374 initial_states: HashMap::new(),
375 final_states: HashMap::new(),
376 delta: HashMap::new(),
377 idelta: HashMap::new(),
378 }
379 }
380
381 pub fn add_state(&mut self, state: State) {
383 self.states.insert(state);
384 }
385
386 pub fn add_initial(&mut self, state: State, symbol: Transition) {
388 self.states.insert(state.clone());
389 if let Some(symbols) = self.initial_states.get_mut(&state) {
390 symbols.insert(symbol);
391 } else {
392 let mut symbols = HashSet::new();
393 symbols.insert(symbol);
394 self.initial_states.insert(state, symbols);
395 }
396 }
397
398 pub fn add_final(&mut self, state: State, symbol: Transition) {
400 self.states.insert(state.clone());
401 if let Some(symbols) = self.final_states.get_mut(&state) {
402 symbols.insert(symbol);
403 } else {
404 let mut symbols = HashSet::new();
405 symbols.insert(symbol);
406 self.final_states.insert(state, symbols);
407 }
408 }
409
410 pub fn add_sigma(&mut self, sigma: Transition) {
412 self.sigma.insert(sigma);
413 }
414
415 fn add_delta(&mut self, source: State, symbol: Transition, destination: State, delta: &Delta) {
416 let delta = match delta {
417 Delta::Delta => &mut self.delta,
418 Delta::IDelta => &mut self.idelta,
419 };
420 if let Some(transitions) = delta.get_mut(&source) {
421 if let Some(destinations) = transitions.get_mut(&symbol) {
422 destinations.insert(destination);
423 } else {
424 let mut destinations = HashSet::new();
425 destinations.insert(destination);
426 transitions.insert(symbol, destinations);
427 }
428 } else {
429 let mut transitions = HashMap::new();
430 let mut destinations = HashSet::new();
431 destinations.insert(destination);
432 transitions.insert(symbol, destinations);
433 delta.insert(source, transitions);
434 }
435 }
436
437 pub fn add_transition(&mut self, source: State, symbol: Transition, destination: State) {
439 self.add_sigma(symbol.clone());
441 self.add_delta(
442 source.clone(),
443 symbol.clone(),
444 destination.clone(),
445 &Delta::Delta,
446 );
447 self.add_delta(destination, symbol, source, &Delta::IDelta);
448 }
449
450 pub fn add_non_deterministic_transitions(
452 &mut self,
453 source: &State,
454 symbol: &Transition,
455 destinations: impl Iterator<Item = State>,
456 ) {
457 self.add_sigma(symbol.clone());
459 for destination in destinations {
460 self.add_delta(
461 source.clone(),
462 symbol.clone(),
463 destination.clone(),
464 &Delta::Delta,
465 );
466 self.add_delta(
467 destination.clone(),
468 symbol.clone(),
469 source.clone(),
470 &Delta::IDelta,
471 );
472 }
473 }
474
475 #[must_use]
477 pub fn productive_states(&self) -> HashSet<State> {
478 let mut stack: VecDeque<_> = self.final_states.keys().collect();
479 let mut productive = HashSet::new();
481 while let Some(state) = stack.pop_back() {
482 if productive.insert(state.clone()) {
483 if let Some(states) = self.idelta.get(state).map(|transitions| {
484 transitions
485 .values()
486 .flat_map(std::collections::HashSet::iter)
487 }) {
488 stack.extend(states)
489 }
490 }
491 }
492 productive
493 }
494
495 #[must_use]
499 pub fn non_productive_states(&self) -> HashSet<State> {
500 self.states
502 .difference(&self.productive_states())
503 .cloned()
504 .collect()
505 }
506
507 #[must_use]
509 pub fn useful_states(&self) -> HashSet<State> {
510 let productive = self.productive_states();
512 let mut stack: VecDeque<_> = self.initial_states.keys().collect();
513 let mut reachable = HashSet::new();
515 while let Some(state) = stack.pop_back() {
516 if reachable.insert(state.clone()) {
517 if let Some(states) = self.delta.get(state).map(|transitions| {
518 transitions
519 .values()
520 .flat_map(std::collections::HashSet::iter)
521 }) {
522 stack.extend(states)
523 }
524 }
525 }
526 productive.intersection(&reachable).cloned().collect()
527 }
528
529 #[must_use]
533 pub fn non_useful_states(&self) -> HashSet<State> {
534 self.states
536 .difference(&self.useful_states())
537 .cloned()
538 .collect()
539 }
540}
541
542impl<State, Transition> Default for NonDeterministicFiniteAutomata<State, Transition>
544where
545 State: Eq + Hash + Clone,
546 Transition: Eq + Hash + Clone,
547{
548 fn default() -> Self {
550 Self::new()
551 }
552}
553
554#[cfg(test)]
556mod nfa_tests {
557 use super::test_traits::*;
558 use super::*;
559
560 fn setup_automata() -> Nfa<i32, ()> {
561 let mut nfa = Nfa::new();
562 let state_list = [1, 2, 3, 4, 5, 6, 7];
563 for &state in state_list.iter() {
564 nfa.add_state(state);
565 }
566 nfa.add_initial(1, ());
567 nfa.add_final(7, ());
568 let transition_list = [
569 (1, 2),
570 (1, 3),
571 (2, 6),
572 (3, 4),
573 (3, 5),
574 (3, 6),
575 (4, 5),
576 (5, 7),
577 (6, 7),
578 ];
579 for &(src, dst) in transition_list.iter() {
580 nfa.add_transition(src, (), dst);
581 }
582 nfa
583 }
584
585 fn setup_automata_loop() -> Nfa<i32, ()> {
586 let mut nfa = Nfa::new();
587 nfa.add_initial(1, ());
588 nfa.add_final(2, ());
589 nfa.add_transition(1, (), 2);
590 nfa.add_transition(2, (), 1);
591 nfa
592 }
593
594 #[test]
595 fn test_add_state() {
596 let nfa = setup_automata();
597 let expected_states = vec![1, 2, 3, 4, 5, 6, 7].into_hash_set();
598 let result_states = nfa.states;
599 assert_eq!(expected_states, result_states);
600 }
601
602 #[test]
603 fn test_add_initial_state() {
604 let nfa = setup_automata();
605 let expected_states = vec![1].into_hash_set();
606 let result_states: HashSet<i32> = nfa.initial_states.keys().map(|i| *i).collect();
607 assert_eq!(expected_states, result_states);
608 }
609
610 #[test]
611 fn test_add_final_state() {
612 let nfa = setup_automata();
613 let expected_states = vec![7].into_hash_set();
614 let result_states: HashSet<i32> = nfa.final_states.keys().map(|i| *i).collect();
615 assert_eq!(expected_states, result_states);
616 }
617
618 #[test]
619 fn test_add_transition() {
620 let nfa = setup_automata();
621 let expected_deltas = [
622 (1, 2),
623 (1, 3),
624 (2, 6),
625 (3, 4),
626 (3, 5),
627 (3, 6),
628 (4, 5),
629 (5, 7),
630 (6, 7),
631 ]
632 .iter()
633 .map(|t| t.to_owned())
634 .collect::<HashSet<_>>();
635 let expected_ideltas = expected_deltas
636 .iter()
637 .map(|(fst, snd)| (*snd, *fst))
638 .map(|t| t.to_owned())
639 .collect::<HashSet<_>>();
640 let mut result_deltas = HashSet::new();
641 for (src, transitions) in nfa.delta {
642 for destinations in transitions.values() {
643 for &dst in destinations {
644 result_deltas.insert((src, dst));
645 }
646 }
647 }
648 let mut result_ideltas = HashSet::new();
649 for (src, transitions) in nfa.idelta {
650 for destinations in transitions.values() {
651 for &dst in destinations {
652 result_ideltas.insert((src, dst));
653 }
654 }
655 }
656 assert_eq!(expected_deltas, result_deltas);
657 assert_eq!(expected_ideltas, result_ideltas);
658 }
659
660 #[test]
661 fn test_add_non_deterministic_transition() {
662 let mut nfa = Nfa::new();
663 [1, 2, 3, 4, 5, 6, 7]
664 .iter()
665 .map(|i| *i)
666 .for_each(|i| nfa.add_state(i));
667 nfa.add_initial(1, ());
668 nfa.add_final(7, ());
669 let non_deterministic_transitions = vec![
670 (1, vec![2, 3]),
671 (2, vec![6]),
672 (3, vec![4, 5, 6]),
673 (4, vec![5]),
674 (5, vec![7]),
675 (6, vec![7]),
676 ];
677 for (source, destinations) in non_deterministic_transitions {
678 nfa.add_non_deterministic_transitions(&source, &(), destinations.into_iter());
679 }
680 let expected_deltas = [
681 (1, 2),
682 (1, 3),
683 (2, 6),
684 (3, 4),
685 (3, 5),
686 (3, 6),
687 (4, 5),
688 (5, 7),
689 (6, 7),
690 ]
691 .iter()
692 .map(|t| t.to_owned())
693 .collect::<HashSet<_>>();
694 let expected_ideltas = expected_deltas
695 .iter()
696 .map(|(fst, snd)| (*snd, *fst))
697 .map(|t| t.to_owned())
698 .collect::<HashSet<_>>();
699 let mut result_deltas = HashSet::new();
700 for (src, transitions) in nfa.delta {
701 for destinations in transitions.values() {
702 for &dst in destinations {
703 result_deltas.insert((src, dst));
704 }
705 }
706 }
707 let mut result_ideltas = HashSet::new();
708 for (src, transitions) in nfa.idelta {
709 for destinations in transitions.values() {
710 for &dst in destinations {
711 result_ideltas.insert((src, dst));
712 }
713 }
714 }
715 assert_eq!(expected_deltas, result_deltas);
716 assert_eq!(expected_ideltas, result_ideltas);
717 }
718
719 #[test]
720 fn test_productive() {
721 let nfa = setup_automata();
722 let result = nfa.productive_states();
723 let expected = [1, 2, 3, 4, 5, 6, 7]
724 .iter()
725 .map(|i| i.to_owned())
726 .collect::<HashSet<i32>>();
727 assert_eq!(expected, result);
728 }
729
730 #[test]
731 fn test_productive_loop() {
732 let nfa = setup_automata_loop();
733 let result = nfa.productive_states();
734 let expected = [1, 2]
735 .iter()
736 .map(|i| i.to_owned())
737 .collect::<HashSet<i32>>();
738 assert_eq!(expected, result);
739 }
740
741 #[test]
742 fn test_useful() {
743 let nfa = setup_automata();
744 let result = nfa.useful_states();
745 let expected = [1, 2, 3, 4, 5, 6, 7]
746 .iter()
747 .map(|i| i.to_owned())
748 .collect::<HashSet<i32>>();
749 assert_eq!(expected, result);
750 }
751}
752
753#[cfg(test)] mod test_traits {
756 use std::{collections::HashSet, hash::Hash, rc::Rc};
757
758 pub(crate) trait IntoHashSet<T>
760 where
761 T: Eq + Hash,
762 {
763 fn into_hash_set(self) -> HashSet<T>;
764 }
765
766 impl IntoHashSet<i32> for Vec<i32> {
768 fn into_hash_set(self) -> HashSet<i32> {
769 self.iter().map(|t| t.to_owned()).collect()
770 }
771 }
772
773 impl IntoHashSet<i32> for HashSet<Rc<i32>> {
775 fn into_hash_set(self) -> HashSet<i32> {
776 self.iter().map(|i| *i.to_owned()).collect()
777 }
778 }
779}