/* * (C) Copyright 2001 Arnaud Bailly (arnaud.oqube@gmail.com), * Yves Roos (yroos@lifl.fr) and others. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package rationals.transformations; import rationals.Automaton; import rationals.Builder; import rationals.NoSuchStateException; import rationals.State; import rationals.Transition; import java.util.*; /** * Determinization of an automaton. * * @author yroos * @version $Id: ToDFA.java 7 2006-08-31 23:01:30Z oqube $ */ public class ToDFA<L, Tr extends Transition<L>, T extends Builder<L, Tr, T>> implements UnaryTransformation<L, Tr, T> { public Automaton<L, Tr, T> transform(Automaton<L, Tr, T> a) { Automaton<L, Tr, T> ret = new Automaton<>(); Map<Set<State>, State> bmap = new HashMap<>(); List<Set<State>>todo = new ArrayList<>(); Set<Set<State>>done = new HashSet<>(); Set<State> as = TransformationsToolBox.epsilonClosure(a.initials(), a); State from = ret.addState(true, TransformationsToolBox.containsATerminalState(as)); bmap.put(as, from); todo.add(as); do { Set<State> sts = todo.remove(0); from = bmap.get(sts); if (done.contains(sts)) continue; done.add(sts); /* get transition sets */ Map<L, Set<State>> tam = TransformationsToolBox.mapAlphabet(a.delta(sts), a); /* unsynchronizable transitions in A */ for (Iterator<Map.Entry<L, Set<State>>> i = tam.entrySet().iterator(); i.hasNext();) { Map.Entry<L, Set<State>> me = i.next(); L l = me.getKey(); as = (Set<State>) me.getValue(); Set<State> asc = TransformationsToolBox.epsilonClosure(as, a); State to = (State) bmap.get(asc); if (to == null) { to = ret.addState(false, TransformationsToolBox .containsATerminalState(asc)); bmap.put(asc, to); } todo.add(asc); try { ret.addTransition(new Transition<L>(from, l, to)); } catch (NoSuchStateException e) { assert false; } } } while (!todo.isEmpty()); return ret; } /* public Automaton transform(Automaton a) { a = new EpsilonTransitionRemover().transform(a); Automaton b = new Automaton(); Map map = new HashMap(); LinkedList l = new LinkedList(); Set done = new HashSet(); Set e = a.initials(); boolean t = TransformationsToolBox.containsATerminalState(e); map.put(e, b.addState(true, t)); l.add(e); while (!l.isEmpty()) { Set e1 = (Set) l.removeFirst(); done.add(e1); State ep1 = (State) map.get(e1); Iterator j = a.alphabet().iterator(); Object label = null; while (j.hasNext()) { label = j.next(); Iterator i = e1.iterator(); Set e2 = a.getStateFactory().stateSet(); while (i.hasNext()) { Iterator k = a.delta((State) i.next(), label).iterator(); while (k.hasNext()) { e2.add(((Transition) k.next()).end()); } } State ep2; if (!e2.isEmpty()) { if (!map.containsKey(e2)) { t = TransformationsToolBox.containsATerminalState(e2); map.put(e2, b.addState(false, t)); } ep2 = (State) map.get(e2); try { b.addTransition(new Transition(ep1, label, ep2)); } catch (NoSuchStateException x) { } if (!done.contains(e2)) l.add(e2); } } } return b; } */ }