1use crate::nfa::{Nfa, NfaState};
2use std::collections::{HashMap, HashSet};
3use std::iter;
4use std::rc::Rc;
5
6#[derive(Clone, Debug)]
7pub struct NfaEvaluator<'a> {
8 nfa: &'a Nfa,
9 rev_map: Rc<HashMap<&'a str, usize>>,
10 current_states: HashSet<usize>,
11 unknown_elem_seen: bool,
12}
13
14impl<'a> NfaEvaluator<'a> {
15 pub fn is_accepting(&self) -> bool {
16 if self.unknown_elem_seen {
17 false
18 } else {
19 self.current_states().iter().any(|s| s.accepting)
20 }
21 }
22
23 pub fn current_states(&self) -> Vec<&NfaState> {
24 self.current_states
25 .iter()
26 .map(|&s| &self.nfa.states[s])
27 .collect()
28 }
29
30 pub fn current_states_idx(&self) -> &HashSet<usize> {
31 &self.current_states
32 }
33
34 pub fn step_all(&self) -> Vec<NfaEvaluator<'a>> {
35 iter::repeat(self.clone())
36 .zip(self.nfa.alphabet())
37 .map(|(mut eval, elem)| {
38 eval.step(elem);
39 eval
40 })
41 .collect()
42 }
43
44 pub fn step(&mut self, elem: &str) -> Option<()> {
45 match self.rev_map.get(elem) {
46 None => {
47 self.unknown_elem_seen = true;
48 None
49 }
50 Some(&idx) => {
51 self.current_states = self
52 .current_states
53 .iter()
54 .flat_map(|&state| &self.nfa.states[state].transitions[idx])
55 .copied()
56 .collect();
57 self.include_closure();
58 Some(())
59 }
60 }
61 }
62
63 pub fn step_multiple(&mut self, elems: &[&str]) -> Option<()> {
64 match elems.iter().try_for_each(|e| self.step(e)) {
65 None => {
66 self.unknown_elem_seen = true;
67 None
68 }
69 Some(_) => Some(())
70 }
71 }
72
73 fn include_closure(&mut self) {
74 let mut updated = true;
75 let mut to_push = HashSet::new();
76 while updated {
77 updated = false;
78 for state in self.current_states.iter() {
79 for epsilon_state in self.nfa.states[*state].epsilon_transitions.iter() {
80 if !self.current_states.contains(epsilon_state) {
81 updated = true;
82 to_push.insert(epsilon_state);
83 }
84 }
85 }
86 self.current_states.extend(to_push.drain());
87 }
88 }
89}
90
91impl<'a> From<&'a Nfa> for NfaEvaluator<'a> {
92 fn from(value: &'a Nfa) -> Self {
93 let map = value
94 .alphabet
95 .iter()
96 .enumerate()
97 .map(|(idx, c)| (c as &str, idx))
98 .collect();
99 let mut evaluator = Self {
100 nfa: value,
101 rev_map: Rc::new(map),
102 current_states: HashSet::new(),
103 unknown_elem_seen: false,
104 };
105 evaluator.current_states.insert(value.initial_state);
106 evaluator.include_closure();
107 evaluator
108 }
109}