1use bit_set::BitSet;
2use std::fmt::Display;
3use std::io::Write;
4
5pub use self::Etrans::{No, One, Two, More};
6
7pub enum Etrans {
17 No,
18 One(usize),
19 Two(usize, usize),
20 More(Vec<usize>)
21}
22
23impl Etrans {
24 pub fn push(&mut self, item: usize) {
25 match *self {
26 No => *self = One(item),
27 One(x) => *self = Two(x, item),
28 Two(x, y) => *self = More(vec![x, y, item]),
29 More(ref mut v) => v.push(item)
30 }
31 }
32}
33
34pub trait StateData {
35 fn no_data() -> Self;
36 fn combine(a: Self, b: Self) -> Self;
37 fn is_final(&self) -> bool;
38}
39
40pub trait State {
41 type Data: StateData;
42 type Iter: Iterator<Item = usize>;
43
44 fn new() -> Self;
45 fn etransition<'a>(&'a self) -> &'a Etrans;
46 fn transition(&self, c: u8) -> Self::Iter;
47 fn data(&self) -> Self::Data;
48}
49
50pub struct Automaton<T> where T: State {
51 pub states: Vec<T>,
52 pub initial: usize
53}
54
55impl<T: State> Automaton<T> {
56 pub fn create_state(&mut self) -> usize {
58 self.states.push(T::new());
59 self.states.len() - 1
60 }
61
62 pub fn moves(&self, st: &BitSet, c: u8) -> Vec<usize> {
63 let mut ret = Vec::with_capacity(st.len());
64
65 for s in st.iter() {
66 for dst in self.states[s].transition(c) {
67 ret.push(dst);
68 }
69 }
70
71 ret
72 }
73
74 #[inline(always)]
75 pub fn eclosure_(&self, st: usize) -> (BitSet, T::Data) {
76 self.eclosure(&[st])
77 }
78
79 pub fn eclosure(&self, st: &[usize]) -> (BitSet, T::Data) {
80 let mut ret = BitSet::with_capacity(self.states.len());
81 let mut ret_action = T::Data::no_data();
82 let mut stack = Vec::with_capacity(st.len());
83
84 macro_rules! add {
85 ($state: expr) => {
86 if !ret.contains($state) {
87 ret.insert($state);
88 stack.push($state);
89
90 ret_action = T::Data::combine(
91 self.states[$state].data(),
92 ret_action
93 );
94 }
95 }
96 }
97
98 for &s in st.iter() {
99 add!(s);
100 }
101
102 while !stack.is_empty() {
103 let st = stack.pop().unwrap();
104 let st = &self.states[st];
105
106 match *st.etransition() {
107 No => (),
108 One(i) => add!(i),
109 Two(i, j) => { add!(i) ; add!(j) }
110 More(ref v) => {
111 for &i in v.iter() {
112 add!(i);
113 }
114 }
115 }
116 }
117
118 (ret, ret_action)
119 }
120
121 #[allow(dead_code)]
122 #[allow(unused_must_use)]
123 pub fn todot(&self, out: &mut Write) where T::Data: Display + Eq {
126 writeln!(out, "digraph automata {{");
127 writeln!(out, "\trankdir = LR;");
128 writeln!(out, "\tsize = \"4,4\";");
129 writeln!(out, "\tnode [shape=box]; {};", self.initial);
130 writeln!(out, "\tnode [shape=doublecircle];");
131 write!(out, "\t");
132
133 for st in 0 .. self.states.len() {
135 if self.states[st].data() != T::Data::no_data() {
136 write!(out, "{} ", st);
137 }
138 }
139
140 writeln!(out, ";\n");
141 writeln!(out, "\tnode [shape=circle];");
142
143 for st in 0 .. self.states.len() {
144 for ch in 0 .. 256 {
145 for dst in self.states[st].transition(ch as u8) {
146 let mut esc = String::new();
147 esc.extend((ch as u8 as char).escape_default());
148 writeln!(out, "\t{} -> {} [label=\"{}\"];", st, dst, esc);
149 }
150 }
151
152 match *self.states[st].etransition() {
153 One(s) => {
154 writeln!(out, "\t{} -> {} [label=\"e\"];", st, s);
155 }
156 Two(s, t) => {
157 writeln!(out, "\t{} -> {} [label=\"e\"];", st, s);
158 writeln!(out, "\t{} -> {} [label=\"e\"];", st, t);
159 }
160 More(ref v) => {
161 for i in v.iter() {
162 writeln!(out, "\t{} -> {} [label=\"e\"];", st, *i);
163 }
164 }
165 _ => ()
166 }
167 }
168
169 writeln!(out, "}}");
170 }
171}