1use std::{
2 collections::{
3 BTreeMap as Map,
4 BTreeSet as Set,
5 },
6 iter,
7};
8use ::segment_map::{
9 Segment,
10 SegmentMap,
11 segment_map,
12};
13use crate::{
14 StateIndex,
15 TransitionIndex,
16 Subsume,
17 Nfa,
18 Dfa,
19 StatesContains,
20 StatesIndex,
21 StatesSlice,
22 states_contains_from,
23};
24
25#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
27pub struct Enfa<S, T> {
28 state_to_index: Map<S, StateIndex>,
29 index_to_state: Map<StateIndex, S>,
30 next_state_index: u128,
31 transition_to_index: Map<StateIndex, SegmentMap<T, Map<StateIndex, TransitionIndex>>>,
32 index_to_transition: Map<TransitionIndex, (StateIndex, Segment<T>, StateIndex)>,
33 next_transition_index: u128,
34 initial_index: StateIndex,
35 final_indices: Set<StateIndex>
36}
37
38impl<S: Clone + Ord, T: Clone + Ord> Enfa<S, T> {
39 pub fn new(initial: S) -> Enfa<S, T> {
41 Enfa {
42 state_to_index: map![initial.clone() => 0.into()],
43 index_to_state: map![0.into() => initial],
44 next_state_index: 1,
45 transition_to_index: Map::new(),
46 index_to_transition: Map::new(),
47 next_transition_index: 0,
48 initial_index: 0.into(),
49 final_indices: Set::new(),
50 }
51 }
52
53 pub fn states_insert(&mut self, state: S) -> StateIndex {
55 if let Some(&state_index) = self.state_to_index.get(&state) {
56 state_index
57 } else {
58 let state_index = self.next_state_index.into();
59 self.next_state_index += 1;
60 self.state_to_index.insert(state.clone(), state_index);
61 self.index_to_state.insert(state_index, state);
62 state_index
63 }
64 }
65}
66
67impl<S: Ord, T: Ord> Enfa<S, T> {
68 pub fn states_contains(&self, state: &S) -> Option<StateIndex> {
70 self.state_to_index.get(state).copied()
71 }
72
73 pub fn states_index(&self, state_index: StateIndex) -> &S {
75 self.index_to_state.get(&state_index).expect("state index out of bounds")
76 }
77
78 pub fn states_slice<'a>(&'a self, state_indices: impl IntoIterator<Item = StateIndex> + 'a) -> Box<dyn Iterator<Item = &S> + 'a> {
80 Box::new(state_indices.into_iter().map(move |state_index| self.states_index(state_index)))
81 }
82
83 pub fn state_indices<'a>(&'a self) -> Box<dyn Iterator<Item = StateIndex> + 'a> {
85 Box::new(self.index_to_state.keys().copied())
86 }
87
88 pub fn closure_indices<'a>(&'a self, state_index: StateIndex) -> Box<dyn Iterator<Item = StateIndex> + 'a> {
90 let mut stack = vec![state_index];
91 let mut closure = Set::new();
92 while let Some(source_index) = stack.pop() {
93 closure.insert(source_index);
94 for transition_index in self.transition_indices_from(source_index) {
95 let (_, transition_segment, target_index) = self.transitions_index(transition_index);
96 if transition_segment.is_empty() {
97 if !closure.contains(&target_index) {
98 stack.push(target_index);
99 }
100 }
101 }
102 }
103 let result = Box::new(closure.into_iter());
104 result
105 }
106}
107
108impl<S: Clone + Ord, T: Clone + Ord> Enfa<S, T> {
109 pub fn transitions_insert(&mut self, transition: (StateIndex, Segment<T>, StateIndex)) -> TransitionIndex {
111 let (source_index, transition_segment, target_index) = transition;
112 if self.index_to_state.get(&source_index).is_none() {
113 panic!("source state index out of bounds");
114 }
115 if self.index_to_state.get(&target_index).is_none() {
116 panic!("target state index out of bounds");
117 }
118 let transition_index = self.next_transition_index.into();
119 self.next_transition_index += 1;
120 if let Some(transitions) = self.transition_to_index.get_mut(&source_index) {
121 transitions.update(&transition_segment, |targets| {
122 if let Some(mut targets) = targets {
123 if targets.get(&target_index).is_some() {
124 panic!("transition segments must not overlap");
125 }
126 targets.insert(target_index, transition_index);
127 Some(targets)
128 } else {
129 Some(map![target_index => transition_index])
130 }
131 });
132 } else {
133 self.transition_to_index.insert(source_index, segment_map![transition_segment.clone() => map![target_index => transition_index]]);
134 }
135 self.index_to_transition.insert(transition_index, (source_index, transition_segment, target_index));
136 transition_index
137 }
138}
139
140impl<S: Ord, T: Ord> Enfa<S, T> {
141 pub fn transitions_contains(&self, transition: (StateIndex, &T, StateIndex)) -> Option<TransitionIndex> {
143 let (source_index, transition, target_index) = transition;
144 self.transition_to_index.get(&source_index).and_then(|transitions| transitions.get(transition).and_then(|targets| targets.get(&target_index))).copied()
145 }
146
147 pub fn transitions_index(&self, transition_index: TransitionIndex) -> (StateIndex, &Segment<T>, StateIndex) {
149 let (source_index, transition, target_index) = self.index_to_transition.get(&transition_index).expect("transition index out of bounds");
150 (*source_index, transition, *target_index)
151 }
152
153 pub fn transitions_slice<'a>(&'a self, transition_indices: impl IntoIterator<Item = TransitionIndex> + 'a) -> Box<dyn Iterator<Item = (StateIndex, &Segment<T>, StateIndex)> + 'a> {
155 Box::new(transition_indices.into_iter().map(move |transition_index| self.transitions_index(transition_index)))
156 }
157
158 pub fn transition_indices<'a>(&'a self) -> Box<dyn Iterator<Item = TransitionIndex> + 'a> {
160 Box::new(self.index_to_transition.keys().copied())
161 }
162
163 pub fn transition_indices_from<'a>(&'a self, state_index: StateIndex) -> Box<dyn Iterator<Item = TransitionIndex> + 'a> {
165 if self.index_to_state.get(&state_index).is_none() {
166 panic!("state index out of bounds");
167 }
168 if let Some(transitions_from) = self.transition_to_index.get(&state_index) {
169 Box::new(transitions_from.iter().flat_map(|(_, targets_from)| targets_from.iter().map(|(_, transition_index_from)| transition_index_from)).copied())
170 } else {
171 Box::new(iter::empty())
172 }
173 }
174
175 pub fn initial_index(&self) -> StateIndex {
177 self.initial_index
178 }
179
180 pub fn is_final(&self, state_index: StateIndex) -> bool {
182 self.final_indices.contains(&state_index)
183 }
184
185 pub fn set_final(&mut self, state_index: StateIndex) {
187 self.final_indices.insert(state_index);
188 }
189
190 pub fn final_indices<'a>(&'a self) -> Box<dyn Iterator<Item = StateIndex> + 'a> {
192 Box::new(self.final_indices.iter().copied())
193 }
194}
195
196impl<S: Clone + Ord, T: Clone + Ord> From<&Nfa<S, T>> for Enfa<S, T> {
197 fn from(nfa: &Nfa<S, T>) -> Enfa<S, T> {
199 let initial = nfa.states_index(nfa.initial_index());
200 let mut enfa = Enfa::new(initial.clone());
201 for state_index in nfa.state_indices() {
202 let state = nfa.states_index(state_index);
203 enfa.states_insert(state.clone());
204 }
205 for transition_index in nfa.transition_indices() {
206 let (source_index, transition, target_index) = nfa.transitions_index(transition_index);
207 let source_index = states_contains_from(&enfa, nfa, source_index).expect("state does not exist");
208 let target_index = states_contains_from(&enfa, nfa, target_index).expect("state does not exist");
209 enfa.transitions_insert((source_index, transition.clone(), target_index));
210 }
211 for final_index in nfa.final_indices() {
212 let final_index = states_contains_from(&enfa, nfa, final_index).expect("state does not exist");
213 enfa.set_final(final_index);
214 }
215 enfa
216 }
217}
218
219impl<S: Clone + Ord, T: Clone + Ord> From<&Dfa<S, T>> for Enfa<S, T> {
220 fn from(dfa: &Dfa<S, T>) -> Enfa<S, T> {
222 let initial = dfa.states_index(dfa.initial_index());
223 let mut enfa = Enfa::new(initial.clone());
224 for state_index in dfa.state_indices() {
225 let state = dfa.states_index(state_index);
226 enfa.states_insert(state.clone());
227 }
228 for transition_index in dfa.transition_indices() {
229 let (source_index, transition, target_index) = dfa.transitions_index(transition_index);
230 let source_index = states_contains_from(&enfa, dfa, source_index).expect("state does not exist");
231 let target_index = states_contains_from(&enfa, dfa, target_index).expect("state does not exist");
232 enfa.transitions_insert((source_index, transition.clone(), target_index));
233 }
234 for final_index in dfa.final_indices() {
235 let final_index = states_contains_from(&enfa, dfa, final_index).expect("state does not exist");
236 enfa.set_final(final_index);
237 }
238 enfa
239 }
240}
241
242impl<S: Clone + Ord, T: Clone + Ord> Subsume<Enfa<S, T>> for Enfa<S, T> {
243 fn subsume(&mut self, enfa: &Enfa<S, T>) {
245 for state_index in enfa.state_indices() {
246 let state = enfa.states_index(state_index);
247 self.states_insert(state.clone());
248 }
249 for transition_index in enfa.transition_indices() {
250 let (source_index, transition, target_index) = enfa.transitions_index(transition_index);
251 let source_index = states_contains_from(self, enfa, source_index).expect("state does not exist");
252 let target_index = states_contains_from(self, enfa, target_index).expect("state does not exist");
253 self.transitions_insert((source_index, transition.clone(), target_index));
254 }
255 }
256}
257
258impl<S: Clone + Ord, T: Clone + Ord> Subsume<Nfa<S, T>> for Enfa<S, T> {
259 fn subsume(&mut self, nfa: &Nfa<S, T>) {
261 for state_index in nfa.state_indices() {
262 let state = nfa.states_index(state_index);
263 self.states_insert(state.clone());
264 }
265 for transition_index in nfa.transition_indices() {
266 let (source_index, transition, target_index) = nfa.transitions_index(transition_index);
267 let source_index = states_contains_from(self, nfa, source_index).expect("state does not exist");
268 let target_index = states_contains_from(self, nfa, target_index).expect("state does not exist");
269 self.transitions_insert((source_index, transition.clone(), target_index));
270 }
271 }
272}
273
274impl<S: Clone + Ord, T: Clone + Ord> Subsume<Dfa<S, T>> for Enfa<S, T> {
275 fn subsume(&mut self, dfa: &Dfa<S, T>) {
277 for state_index in dfa.state_indices() {
278 let state = dfa.states_index(state_index);
279 self.states_insert(state.clone());
280 }
281 for transition_index in dfa.transition_indices() {
282 let (source_index, transition, target_index) = dfa.transitions_index(transition_index);
283 let source_index = states_contains_from(self, dfa, source_index).expect("state does not exist");
284 let target_index = states_contains_from(self, dfa, target_index).expect("state does not exist");
285 self.transitions_insert((source_index, transition.clone(), target_index));
286 }
287 }
288}
289
290impl<S: Ord, T: Ord> StatesContains<S> for Enfa<S, T> {
291 fn states_contains(&self, state: &S) -> Option<StateIndex> {
292 self.states_contains(state)
293 }
294}
295
296impl<S: Ord, T: Ord> StatesIndex<S> for Enfa<S, T> {
297 fn states_index(&self, state_index: StateIndex) -> &S {
298 self.states_index(state_index)
299 }
300}
301
302impl<S: Ord, T: Ord> StatesSlice<S> for Enfa<S, T> {
303 fn states_slice<'a>(&'a self, state_indices: impl IntoIterator<Item = StateIndex> + 'a) -> Box<dyn Iterator<Item = &S> + 'a> {
304 self.states_slice(state_indices)
305 }
306}
307
308#[cfg(test)]
309mod tests {
310 use std::{
311 collections::BTreeSet as Set,
312 fmt::Debug,
313 };
314 use segment_map::Segment;
315 use crate::Enfa;
316
317 #[test]
318 fn test_epsilon() {
319 let expected = Expected::<_, i32> {
320 initial: 0,
321 transitions: set![
322 (0, Segment::empty(), 1)
323 ],
324 finals: set![1]
325 };
326 let mut actual = Enfa::new(0);
327 let s0 = actual.initial_index();
328 let s1 = actual.states_insert(1);
329 actual.transitions_insert((s0, Segment::empty(), s1));
330 actual.set_final(s1);
331 assert_eq(expected, actual);
332 }
333
334 #[test]
335 fn test_symbol() {
336 let expected = Expected {
337 initial: 0,
338 transitions: set![
339 (0, Segment::singleton(A), 1)
340 ],
341 finals: set![1]
342 };
343 let mut actual = Enfa::new(0);
344 let s0 = actual.initial_index();
345 let s1 = actual.states_insert(1);
346 actual.transitions_insert((s0, Segment::singleton(A), s1));
347 actual.set_final(s1);
348 assert_eq(expected, actual);
349 }
350
351 #[test]
352 fn test_alternation() {
353 let expected = Expected {
354 initial: 0,
355 transitions: set![
356 (0, Segment::empty(), 2),
357 (0, Segment::empty(), 4),
358 (2, Segment::empty(), 3),
359 (4, Segment::singleton(A), 5),
360 (3, Segment::empty(), 1),
361 (5, Segment::empty(), 1)
362 ],
363 finals: set![1]
364 };
365 let mut actual = Enfa::new(0);
366 let s0 = actual.initial_index();
367 let s1 = actual.states_insert(1);
368 let s2 = actual.states_insert(2);
369 let s3 = actual.states_insert(3);
370 let s4 = actual.states_insert(4);
371 let s5 = actual.states_insert(5);
372 actual.transitions_insert((s0, Segment::empty(), s2));
373 actual.transitions_insert((s0, Segment::empty(), s4));
374 actual.transitions_insert((s2, Segment::empty(), s3));
375 actual.transitions_insert((s4, Segment::singleton(A), s5));
376 actual.transitions_insert((s3, Segment::empty(), s1));
377 actual.transitions_insert((s5, Segment::empty(), s1));
378 actual.set_final(s1);
379 assert_eq(expected, actual);
380 }
381
382 #[test]
383 fn test_concatenation() {
384 let expected = Expected {
385 initial: 0,
386 transitions: set![
387 (0, Segment::empty(), 2),
388 (2, Segment::singleton(A), 3),
389 (3, Segment::empty(), 4),
390 (4, Segment::empty(), 5),
391 (5, Segment::empty(), 1)
392 ],
393 finals: set![1]
394 };
395 let mut actual = Enfa::new(0);
396 let s0 = actual.initial_index();
397 let s1 = actual.states_insert(1);
398 let s2 = actual.states_insert(2);
399 let s3 = actual.states_insert(3);
400 let s4 = actual.states_insert(4);
401 let s5 = actual.states_insert(5);
402 actual.transitions_insert((s0, Segment::empty(), s2));
403 actual.transitions_insert((s2, Segment::singleton(A), s3));
404 actual.transitions_insert((s3, Segment::empty(), s4));
405 actual.transitions_insert((s4, Segment::empty(), s5));
406 actual.transitions_insert((s5, Segment::empty(), s1));
407 actual.set_final(s1);
408 assert_eq(expected, actual);
409 }
410
411 #[test]
412 fn test_repetition() {
413 let expected = Expected {
414 initial: 0,
415 transitions: set![
416 (0, Segment::empty(), 1),
417 (0, Segment::empty(), 2),
418 (2, Segment::singleton(A), 3),
419 (3, Segment::empty(), 2),
420 (3, Segment::empty(), 1)
421 ],
422 finals: set![1]
423 };
424 let mut actual = Enfa::new(0);
425 let s0 = actual.initial_index();
426 let s1 = actual.states_insert(1);
427 let s2 = actual.states_insert(2);
428 let s3 = actual.states_insert(3);
429 actual.transitions_insert((s0, Segment::empty(), s1));
430 actual.transitions_insert((s0, Segment::empty(), s2));
431 actual.transitions_insert((s2, Segment::singleton(A), s3));
432 actual.transitions_insert((s3, Segment::empty(), s2));
433 actual.transitions_insert((s3, Segment::empty(), s1));
434 actual.set_final(s1);
435 assert_eq(expected, actual);
436 }
437
438 struct Expected<S, T> {
439 initial: S,
440 transitions: Set<(S, Segment<T>, S)>,
441 finals: Set<S>,
442 }
443
444 fn assert_eq<S: Clone + Debug + Ord, T: Clone + Debug + Ord>(expected: Expected<S, T>, actual: Enfa<S, T>) {
445 assert_eq!(expected.initial, actual.states_index(actual.initial_index()).clone(), "initial");
446 assert_eq!(expected.transitions, actual.transitions_slice(actual.transition_indices()).map(|(source, transition, target)| (actual.states_index(source).clone(), transition.clone(), actual.states_index(target).clone())).collect(), "transitions");
447 assert_eq!(expected.finals, actual.states_slice(actual.final_indices()).cloned().collect(), "finals");
448 }
449
450 static A: i32 = 0;
451}