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 Enfa,
18 Dfa,
19 StatesContains,
20 StatesIndex,
21 StatesSlice,
22 states_contains_from,
23 states_contains_closure_from,
24};
25
26#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
28pub struct Nfa<S, T> {
29 state_to_index: Map<S, StateIndex>,
30 index_to_state: Map<StateIndex, S>,
31 next_state_index: u128,
32 transition_to_index: Map<StateIndex, SegmentMap<T, Map<StateIndex, TransitionIndex>>>,
33 index_to_transition: Map<TransitionIndex, (StateIndex, Segment<T>, StateIndex)>,
34 next_transition_index: u128,
35 initial_index: StateIndex,
36 final_indices: Set<StateIndex>
37}
38
39impl<S: Clone + Ord, T: Clone + Ord> Nfa<S, T> {
40 pub fn new(initial: S) -> Nfa<S, T> {
42 Nfa {
43 state_to_index: map![initial.clone() => 0.into()],
44 index_to_state: map![0.into() => initial],
45 next_state_index: 1,
46 transition_to_index: Map::new(),
47 index_to_transition: Map::new(),
48 next_transition_index: 0,
49 initial_index: 0.into(),
50 final_indices: Set::new(),
51 }
52 }
53
54 pub fn states_insert(&mut self, state: S) -> StateIndex {
56 if let Some(&state_index) = self.state_to_index.get(&state) {
57 state_index
58 } else {
59 let state_index = self.next_state_index.into();
60 self.next_state_index += 1;
61 self.state_to_index.insert(state.clone(), state_index);
62 self.index_to_state.insert(state_index, state);
63 state_index
64 }
65 }
66}
67
68impl<S: Ord, T: Ord> Nfa<S, T> {
69 pub fn states_contains(&self, state: &S) -> Option<StateIndex> {
71 self.state_to_index.get(state).copied()
72 }
73
74 pub fn states_index(&self, state_index: StateIndex) -> &S {
76 self.index_to_state.get(&state_index).expect("state index out of bounds")
77 }
78
79 pub fn states_slice<'a>(&'a self, state_indices: impl IntoIterator<Item = StateIndex> + 'a) -> Box<dyn Iterator<Item = &S> + 'a> {
81 Box::new(state_indices.into_iter().map(move |state_index| self.states_index(state_index)))
82 }
83
84 pub fn state_indices<'a>(&'a self) -> Box<dyn Iterator<Item = StateIndex> + 'a> {
86 Box::new(self.index_to_state.keys().copied())
87 }
88}
89
90impl<S: Clone + Ord, T: Clone + Ord> Nfa<S, T> {
91 pub fn transitions_insert(&mut self, transition: (StateIndex, Segment<T>, StateIndex)) -> TransitionIndex {
93 let (source_index, transition_segment, target_index) = transition;
94 if self.index_to_state.get(&source_index).is_none() {
95 panic!("source state index out of bounds");
96 }
97 if self.index_to_state.get(&target_index).is_none() {
98 panic!("target state index out of bounds");
99 }
100 let transition_index = self.next_transition_index.into();
101 self.next_transition_index += 1;
102 if let Some(transitions) = self.transition_to_index.get_mut(&source_index) {
103 transitions.update(&transition_segment, |targets| {
104 if let Some(mut targets) = targets {
105 if targets.get(&target_index).is_some() {
106 panic!("transition segments must not overlap");
107 }
108 targets.insert(target_index, transition_index);
109 Some(targets)
110 } else {
111 Some(map![target_index => transition_index])
112 }
113 });
114 } else {
115 self.transition_to_index.insert(source_index, segment_map![transition_segment.clone() => map![target_index => transition_index]]);
116 }
117 self.index_to_transition.insert(transition_index, (source_index, transition_segment, target_index));
118 transition_index
119 }
120}
121
122impl<S: Ord, T: Ord> Nfa<S, T> {
123 pub fn transitions_contains(&self, transition: (StateIndex, &T, StateIndex)) -> Option<TransitionIndex> {
125 let (source_index, transition_element, target_index) = transition;
126 self.transition_to_index.get(&source_index).and_then(|transitions| transitions.get(transition_element).and_then(|targets| targets.get(&target_index)).copied())
127 }
128
129 pub fn transitions_index(&self, transition_index: TransitionIndex) -> (StateIndex, &Segment<T>, StateIndex) {
131 let (source_index, transition, target_index) = self.index_to_transition.get(&transition_index).expect("transition index out of bounds");
132 (*source_index, transition, *target_index)
133 }
134
135 pub fn transitions_slice<'a>(&'a self, transition_indices: impl IntoIterator<Item = TransitionIndex> + 'a) -> Box<dyn Iterator<Item = (StateIndex, &Segment<T>, StateIndex)> + 'a> {
137 Box::new(transition_indices.into_iter().map(move |transition_index| self.transitions_index(transition_index)))
138 }
139
140 pub fn transition_indices<'a>(&'a self) -> Box<dyn Iterator<Item = TransitionIndex> + 'a> {
142 Box::new(self.index_to_transition.keys().copied())
143 }
144
145 pub fn transition_indices_from<'a>(&'a self, state_index: StateIndex) -> Box<dyn Iterator<Item = TransitionIndex> + 'a> {
147 if self.index_to_state.get(&state_index).is_none() {
148 panic!("state index out of bounds");
149 }
150 if let Some(transitions_from) = self.transition_to_index.get(&state_index) {
151 Box::new(transitions_from.iter().flat_map(|(_, targets_from)| targets_from.iter().map(|(_, transition_index_from)| transition_index_from)).copied())
152 } else {
153 Box::new(iter::empty())
154 }
155 }
156
157 pub fn initial_index(&self) -> StateIndex {
159 self.initial_index
160 }
161
162 pub fn is_final(&self, state_index: StateIndex) -> bool {
164 self.final_indices.contains(&state_index)
165 }
166
167 pub fn set_final(&mut self, state_index: StateIndex) {
169 self.final_indices.insert(state_index);
170 }
171
172 pub fn final_indices<'a>(&'a self) -> Box<dyn Iterator<Item = StateIndex> + 'a> {
174 Box::new(self.final_indices.iter().copied())
175 }
176}
177
178impl<S: Clone + Ord, T: Clone + Ord> From<&Enfa<S, T>> for Nfa<Set<S>, T> {
179 fn from(enfa: &Enfa<S, T>) -> Nfa<Set<S>, T> {
181 let initial_closure_indices: Set<StateIndex> = enfa.closure_indices(enfa.initial_index()).collect();
182 let initial_closure = enfa.states_slice(initial_closure_indices.iter().copied()).cloned().collect();
183 let mut stack = vec![initial_closure_indices];
184 let mut nfa = Nfa::new(initial_closure);
185 while let Some(source_closure_indices) = stack.pop() {
186 let source_index = states_contains_closure_from(&nfa, enfa, source_closure_indices.iter().copied()).expect("closure does not exist");
187 for &source_closure_index in &source_closure_indices {
188 if enfa.is_final(source_closure_index) {
189 nfa.set_final(source_index);
190 }
191 for transition_index in enfa.transition_indices_from(source_closure_index) {
192 let (_, transition, target_index) = enfa.transitions_index(transition_index);
193 if !transition.is_empty() {
194 let target_closure_indices: Set<StateIndex> = enfa.closure_indices(target_index).collect();
195 if let Some(target_index) = states_contains_closure_from(&nfa, enfa, target_closure_indices.iter().copied()) {
196 nfa.transitions_insert((source_index, transition.clone(), target_index));
197 } else {
198 let target_closure = enfa.states_slice(target_closure_indices.iter().copied()).cloned().collect();
199 stack.push(target_closure_indices);
200 let target_index = nfa.states_insert(target_closure);
201 nfa.transitions_insert((source_index, transition.clone(), target_index));
202 }
203 }
204 }
205 }
206 }
207 nfa
208 }
209}
210
211impl<S: Clone + Ord, T: Clone + Ord> From<&Dfa<S, T>> for Nfa<S, T> {
212 fn from(dfa: &Dfa<S, T>) -> Nfa<S, T> {
214 let initial = dfa.states_index(dfa.initial_index());
215 let mut nfa = Nfa::new(initial.clone());
216 for state_index in dfa.state_indices() {
217 let state = dfa.states_index(state_index);
218 nfa.states_insert(state.clone());
219 }
220 for transition_index in dfa.transition_indices() {
221 let (source_index, transition, target_index) = dfa.transitions_index(transition_index);
222 let source_index = states_contains_from(&nfa, dfa, source_index).expect("state does not exist");
223 let target_index = states_contains_from(&nfa, dfa, target_index).expect("state does not exist");
224 nfa.transitions_insert((source_index, transition.clone(), target_index));
225 }
226 for final_index in dfa.final_indices() {
227 let final_index = states_contains_from(&nfa, dfa, final_index).expect("state does not exist");
228 nfa.set_final(final_index);
229 }
230 nfa
231 }
232}
233
234impl<S: Clone + Ord, T: Clone + Ord> Subsume<Enfa<S, T>> for Nfa<Set<S>, T> {
235 fn subsume(&mut self, enfa: &Enfa<S, T>) {
237 let initial_closure_indices: Set<StateIndex> = enfa.closure_indices(enfa.initial_index()).collect();
238 let initial_closure = enfa.states_slice(initial_closure_indices.iter().copied()).cloned().collect();
239 let mut stack = vec![initial_closure_indices];
240 self.states_insert(initial_closure);
241 while let Some(source_closure_indices) = stack.pop() {
242 let source_index = states_contains_closure_from(self, enfa, source_closure_indices.iter().copied()).expect("closure does not exist");
243 for &source_closure_index in &source_closure_indices {
244 if enfa.is_final(source_closure_index) {
245 self.set_final(source_index);
246 }
247 for transition_index in enfa.transition_indices_from(source_closure_index) {
248 let (_, transition, target_index) = enfa.transitions_index(transition_index);
249 if !transition.is_empty() {
250 let target_closure_indices: Set<StateIndex> = enfa.closure_indices(target_index).collect();
251 if let Some(target_index) = states_contains_closure_from(self, enfa, target_closure_indices.iter().copied()) {
252 self.transitions_insert((source_index, transition.clone(), target_index));
253 } else {
254 let target_closure = enfa.states_slice(target_closure_indices.iter().copied()).cloned().collect();
255 stack.push(target_closure_indices);
256 let target_index = self.states_insert(target_closure);
257 self.transitions_insert((source_index, transition.clone(), target_index));
258 }
259 }
260 }
261 }
262 }
263 }
264}
265
266impl<S: Clone + Ord, T: Clone + Ord> Subsume<Nfa<S, T>> for Nfa<S, T> {
267 fn subsume(&mut self, nfa: &Nfa<S, T>) {
269 for state_index in nfa.state_indices() {
270 let state = nfa.states_index(state_index);
271 self.states_insert(state.clone());
272 }
273 for transition_index in nfa.transition_indices() {
274 let (source_index, transition, target_index) = nfa.transitions_index(transition_index);
275 let source_index = states_contains_from(self, nfa, source_index).expect("state does not exist");
276 let target_index = states_contains_from(self, nfa, target_index).expect("state does not exist");
277 self.transitions_insert((source_index, transition.clone(), target_index));
278 }
279 }
280}
281
282impl<S: Clone + Ord, T: Clone + Ord> Subsume<Dfa<S, T>> for Nfa<S, T> {
283 fn subsume(&mut self, dfa: &Dfa<S, T>) {
285 for state_index in dfa.state_indices() {
286 let state = dfa.states_index(state_index);
287 self.states_insert(state.clone());
288 }
289 for transition_index in dfa.transition_indices() {
290 let (source_index, transition, target_index) = dfa.transitions_index(transition_index);
291 let source_index = states_contains_from(self, dfa, source_index).expect("state does not exist");
292 let target_index = states_contains_from(self, dfa, target_index).expect("state does not exist");
293 self.transitions_insert((source_index, transition.clone(), target_index));
294 }
295 }
296}
297
298impl<S: Ord, T: Ord> StatesContains<S> for Nfa<S, T> {
299 fn states_contains(&self, state: &S) -> Option<StateIndex> {
300 self.states_contains(state)
301 }
302}
303
304impl<S: Ord, T: Ord> StatesIndex<S> for Nfa<S, T> {
305 fn states_index(&self, state_index: StateIndex) -> &S {
306 self.states_index(state_index)
307 }
308}
309
310impl<S: Ord, T: Ord> StatesSlice<S> for Nfa<S, T> {
311 fn states_slice<'a>(&'a self, state_indices: impl IntoIterator<Item = StateIndex> + 'a) -> Box<dyn Iterator<Item = &S> + 'a> {
312 self.states_slice(state_indices)
313 }
314}
315
316#[cfg(test)]
317mod tests {
318 use std::{
319 collections::BTreeSet as Set,
320 fmt::Debug,
321 };
322 use segment_map::Segment;
323 use crate::{
324 Nfa,
325 Enfa,
326 };
327
328 #[test]
329 fn test_epsilon() {
330 let expected = Expected::<_, i32> {
331 initial: set![0, 1],
332 transitions: set![],
333 finals: set![set![0, 1]]
334 };
335 let mut actual = Nfa::new(set![0, 1]);
336 let s0 = actual.initial_index();
337 actual.set_final(s0);
338 assert_eq(expected, actual);
339 }
340
341 #[test]
342 fn test_symbol() {
343 let expected = Expected {
344 initial: set![0],
345 transitions: set![
346 (set![0], Segment::singleton(A), set![1])
347 ],
348 finals: set![set![1]]
349 };
350 let mut actual = Nfa::new(set![0]);
351 let s0 = actual.initial_index();
352 let s1 = actual.states_insert(set![1]);
353 actual.transitions_insert((s0, Segment::singleton(A), s1));
354 actual.set_final(s1);
355 assert_eq(expected, actual);
356 }
357
358 #[test]
359 fn test_alternation() {
360 let expected = Expected {
361 initial: set![0, 1, 2, 3, 4],
362 transitions: set![
363 (set![0, 1, 2, 3, 4], Segment::singleton(A), set![1, 5])
364 ],
365 finals: set![set![0, 1, 2, 3, 4], set![1, 5]]
366 };
367 let mut actual = Nfa::new(set![0, 1, 2, 3, 4]);
368 let s01234 = actual.initial_index();
369 let s15 = actual.states_insert(set![1, 5]);
370 actual.transitions_insert((s01234, Segment::singleton(A), s15));
371 actual.set_final(s01234);
372 actual.set_final(s15);
373 assert_eq(expected, actual);
374 }
375
376 #[test]
377 fn test_concatenation() {
378 let expected = Expected {
379 initial: set![0, 2],
380 transitions: set![
381 (set![0, 2], Segment::singleton(A), set![1, 3, 4, 5])
382 ],
383 finals: set![set![1, 3, 4, 5]]
384 };
385 let mut actual = Nfa::new(set![0, 2]);
386 let s02 = actual.initial_index();
387 let s1345 = actual.states_insert(set![1, 3, 4, 5]);
388 actual.transitions_insert((s02, Segment::singleton(A), s1345));
389 actual.set_final(s1345);
390 assert_eq(expected, actual);
391 }
392
393 #[test]
394 fn test_repetition() {
395 let expected = Expected {
396 initial: set![0, 1, 2],
397 transitions: set![
398 (set![0, 1, 2], Segment::singleton(A), set![1, 2, 3]),
399 (set![1, 2, 3], Segment::singleton(A), set![1, 2, 3])
400 ],
401 finals: set![set![0, 1, 2], set![1, 2, 3]]
402 };
403 let mut actual = Nfa::new(set![0, 1, 2]);
404 let s012 = actual.initial_index();
405 let s123 = actual.states_insert(set![1, 2, 3]);
406 actual.transitions_insert((s012, Segment::singleton(A), s123));
407 actual.transitions_insert((s123, Segment::singleton(A), s123));
408 actual.set_final(s012);
409 actual.set_final(s123);
410 assert_eq(expected, actual);
411 }
412
413 #[test]
414 fn test_nondeterminism() {
415 let expected = Expected {
416 initial: set![0, 2, 4],
417 transitions: set![
418 (set![0, 2, 4], Segment::singleton(A), set![1, 3]),
419 (set![0, 2, 4], Segment::singleton(A), set![1, 5])
420 ],
421 finals: set![set![1, 3], set![1, 5]]
422 };
423 let mut actual = Nfa::new(set![0, 2, 4]);
424 let s024 = actual.initial_index();
425 let s13 = actual.states_insert(set![1, 3]);
426 let s15 = actual.states_insert(set![1, 5]);
427 actual.transitions_insert((s024, Segment::singleton(A), s13));
428 actual.transitions_insert((s024, Segment::singleton(A), s15));
429 actual.set_final(s13);
430 actual.set_final(s15);
431 assert_eq(expected, actual);
432 }
433
434 #[test]
435 fn test_nondeterminism_segments() {
436 let expected = Expected {
437 initial: set![0],
438 transitions: set![
439 (set![0], Segment::closed_open(A, C), set![1]),
440 (set![0], Segment::closed_open(B, D), set![2])
441 ],
442 finals: set![set![1], set![2]]
443 };
444 let mut actual = Nfa::new(set![0]);
445 let s0 = actual.initial_index();
446 let s1 = actual.states_insert(set![1]);
447 let s2 = actual.states_insert(set![2]);
448 let t0 = actual.transitions_insert((s0, Segment::closed_open(A, C), s1));
449 let t1 = actual.transitions_insert((s0, Segment::closed_open(B, D), s2));
450 actual.set_final(s1);
451 actual.set_final(s2);
452 assert_eq!(Some(t0), actual.transitions_contains((s0, &A, s1)));
453 assert_eq!(Some(t0), actual.transitions_contains((s0, &B, s1)));
454 assert_eq!(None, actual.transitions_contains((s0, &C, s1)));
455 assert_eq!(None, actual.transitions_contains((s0, &D, s1)));
456 assert_eq!(None, actual.transitions_contains((s0, &A, s2)));
457 assert_eq!(Some(t1), actual.transitions_contains((s0, &B, s2)));
458 assert_eq!(Some(t1), actual.transitions_contains((s0, &C, s2)));
459 assert_eq!(None, actual.transitions_contains((s0, &D, s2)));
460 assert_eq(expected, actual);
461 }
462
463 #[test]
464 fn test_from_enfa_epsilon() {
465 let expected = Expected::<_, i32> {
466 initial: set![0, 1],
467 transitions: set![],
468 finals: set![set![0, 1]]
469 };
470 let mut enfa = Enfa::new(0);
471 let s0 = enfa.initial_index();
472 let s1 = enfa.states_insert(1);
473 enfa.transitions_insert((s0, Segment::empty(), s1));
474 enfa.set_final(s1);
475 let actual = Nfa::from(&enfa);
476 assert_eq(expected, actual);
477 }
478
479 #[test]
480 fn test_from_enfa_symbol() {
481 let expected = Expected {
482 initial: set![0],
483 transitions: set![
484 (set![0], Segment::singleton(A), set![1])
485 ],
486 finals: set![set![1]]
487 };
488 let mut enfa = Enfa::new(0);
489 let s0 = enfa.initial_index();
490 let s1 = enfa.states_insert(1);
491 enfa.transitions_insert((s0, Segment::singleton(A), s1));
492 enfa.set_final(s1);
493 let actual = Nfa::from(&enfa);
494 assert_eq(expected, actual);
495 }
496
497 #[test]
498 fn test_from_enfa_alternation() {
499 let expected = Expected {
500 initial: set![0, 1, 2, 3, 4],
501 transitions: set![
502 (set![0, 1, 2, 3, 4], Segment::singleton(A), set![1, 5])
503 ],
504 finals: set![set![0, 1, 2, 3, 4], set![1, 5]]
505 };
506 let mut enfa = Enfa::new(0);
507 let s0 = enfa.initial_index();
508 let s1 = enfa.states_insert(1);
509 let s2 = enfa.states_insert(2);
510 let s3 = enfa.states_insert(3);
511 let s4 = enfa.states_insert(4);
512 let s5 = enfa.states_insert(5);
513 enfa.transitions_insert((s0, Segment::empty(), s2));
514 enfa.transitions_insert((s0, Segment::empty(), s4));
515 enfa.transitions_insert((s2, Segment::empty(), s3));
516 enfa.transitions_insert((s4, Segment::singleton(A), s5));
517 enfa.transitions_insert((s3, Segment::empty(), s1));
518 enfa.transitions_insert((s5, Segment::empty(), s1));
519 enfa.set_final(s1);
520 let actual = Nfa::from(&enfa);
521 assert_eq(expected, actual);
522 }
523
524 #[test]
525 fn test_from_enfa_concatenation() {
526 let expected = Expected {
527 initial: set![0, 2],
528 transitions: set![
529 (set![0, 2], Segment::singleton(A), set![1, 3, 4, 5])
530 ],
531 finals: set![set![1, 3, 4, 5]]
532 };
533 let mut enfa = Enfa::new(0);
534 let s0 = enfa.initial_index();
535 let s1 = enfa.states_insert(1);
536 let s2 = enfa.states_insert(2);
537 let s3 = enfa.states_insert(3);
538 let s4 = enfa.states_insert(4);
539 let s5 = enfa.states_insert(5);
540 enfa.transitions_insert((s0, Segment::empty(), s2));
541 enfa.transitions_insert((s2, Segment::singleton(A), s3));
542 enfa.transitions_insert((s3, Segment::empty(), s4));
543 enfa.transitions_insert((s4, Segment::empty(), s5));
544 enfa.transitions_insert((s5, Segment::empty(), s1));
545 enfa.set_final(s1);
546 let actual = Nfa::from(&enfa);
547 assert_eq(expected, actual);
548 }
549
550 #[test]
551 fn test_from_enfa_repetition() {
552 let expected = Expected {
553 initial: set![0, 1, 2],
554 transitions: set![
555 (set![0, 1, 2], Segment::singleton(A), set![1, 2, 3]),
556 (set![1, 2, 3], Segment::singleton(A), set![1, 2, 3])
557 ],
558 finals: set![set![0, 1, 2], set![1, 2, 3]]
559 };
560 let mut enfa = Enfa::new(0);
561 let s0 = enfa.initial_index();
562 let s1 = enfa.states_insert(1);
563 let s2 = enfa.states_insert(2);
564 let s3 = enfa.states_insert(3);
565 enfa.transitions_insert((s0, Segment::empty(), s1));
566 enfa.transitions_insert((s0, Segment::empty(), s2));
567 enfa.transitions_insert((s2, Segment::singleton(A), s3));
568 enfa.transitions_insert((s3, Segment::empty(), s2));
569 enfa.transitions_insert((s3, Segment::empty(), s1));
570 enfa.set_final(s1);
571 let actual = Nfa::from(&enfa);
572 assert_eq(expected, actual);
573 }
574
575 struct Expected<S, T> {
576 initial: S,
577 transitions: Set<(S, Segment<T>, S)>,
578 finals: Set<S>,
579 }
580
581 fn assert_eq<S: Clone + Debug + Ord, T: Clone + Debug + Ord>(expected: Expected<S, T>, actual: Nfa<S, T>) {
582 assert_eq!(expected.initial, actual.states_index(actual.initial_index()).clone(), "initial");
583 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");
584 assert_eq!(expected.finals, actual.states_slice(actual.final_indices()).cloned().collect(), "finals");
585 }
586
587 static A: i32 = 0;
588 static B: i32 = 2;
589 static C: i32 = 4;
590 static D: i32 = 6;
591}