* @param a input automaton
* @return resulting automaton
*/
@Override
public Automaton op(Automaton a) {
Automaton b = a.clone();
b.setDeterministic(false);
Map<State, Set<State>> normal_prevs = new HashMap<State, Set<State>>();
Map<State, Set<State>> special_prevs = new HashMap<State, Set<State>>();
findPrevs(b, normal_prevs, special_prevs);
Set<State> pre = findPreSet(b);
Set<State> post = findPostSet(b, special_prevs);
boolean initial_accept = post.contains(b.getInitialState());
State initial = new State();
b.setInitialState(initial);
for (State s : pre) {
for (Transition t : new ArrayList<Transition>(s.getTransitions())) {
char min = t.getMin();
char max = t.getMax();
if (min <= '\u0020') {
min = '\u0021';
}
if (min <= max) {
initial.addTransition(new Transition(min, max, t.getDest()));
}
}
}
State accept = new State();
accept.setAccept(true);
for (State s : b.getAcceptStates()) {
s.setAccept(false);
}
if (initial_accept) {
initial.setAccept(true);
}
for (State s : post) {
Set<State> prevset = normal_prevs.get(s);
if (prevset != null) {
for (State p : prevset) {
for (Transition t : new ArrayList<Transition>(p.getTransitions())) {
if (t.getDest() == s) {
char min = t.getMin();
char max = t.getMax();
if (min <= '\u0020') {
min = '\u0021';
}
if (min <= max) {
p.addTransition(new Transition(min, max, accept));
}
}
}
}
}
}
b.minimize();
return b;
}