package rationals.transformations; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import rationals.Automaton; import rationals.NoSuchStateException; import rationals.State; import rationals.Transition; /** * Computes the minimal automaton from a deterministic automaton. * <p /> * This class first determinizes the transformed automaton, then compute * states equivalence classes to create new states and transitions. * * @author nono * @version $Id: Reducer.java 2 2006-08-24 14:41:48Z oqube $ */ public class Reducer implements UnaryTransformation { /* * equivalence on DFA */ private boolean same(State e1, State e2, Automaton a, Map m) { if (!m.get(e1).equals(m.get(e2))) return false; /* iterate over all transitions */ Set tas = a.delta(e1); Set tbs = a.delta(e2); Iterator it = tas.iterator(); while (it.hasNext()) { Transition tr = (Transition) it.next(); State ep1 = tr.end(); /* check transition exists in b */ Set tbsl = a.delta(e2, tr.label()); if (tbsl.isEmpty()) return false; Iterator trb = tbsl.iterator(); while (trb.hasNext()) { Transition tb = (Transition) trb.next(); /* mark transition as visited */ tbs.remove(tb); State ep2 = tb.end(); if (!m.get(ep1).equals(m.get(ep2))) return false; } } if (!tbs.isEmpty()) { return false; } return true; } public Automaton transform(Automaton a) { Automaton b = new ToDFA().transform(a); Map current = new HashMap(); Set s1 = b.getStateFactory().stateSet(); Set s2 = b.getStateFactory().stateSet(); Iterator i = b.states().iterator(); while (i.hasNext()) { State e = (State) i.next(); if (e.isTerminal()) { s1.add(e); current.put(e, s1); } else { s2.add(e); current.put(e, s2); } } Map old; do { old = current; current = new HashMap(); i = old.keySet().iterator(); while (i.hasNext()) { State e1 = (State) i.next(); Set s = b.getStateFactory().stateSet(); Iterator j = current.keySet().iterator(); while (j.hasNext()) { State e2 = (State) j.next(); if (same(e1, e2, b, old)) { s = (Set) current.get(e2); break; } } s.add(e1); current.put(e1, s); } } while (!new HashSet(current.values()) .equals(new HashSet(old.values()))); Automaton c = new Automaton(); Set setSet = new HashSet(current.values()); Iterator sets = setSet.iterator(); Map newStates = new HashMap(); while (sets.hasNext()) { Set set = (Set) sets.next(); boolean term = TransformationsToolBox.containsATerminalState(set); boolean init = TransformationsToolBox.containsAnInitialState(set); newStates.put(set, c.addState(init, term)); } sets = setSet.iterator(); while (sets.hasNext()) { Set set = (Set) sets.next(); State r = (State) set.iterator().next(); State rp = (State) newStates.get(set); Iterator k = b.alphabet().iterator(); while (k.hasNext()) { Object l = k.next(); Set ds = b.delta(r, l); if(ds.isEmpty()) continue; State f = (State) ((Transition) ds.iterator().next()) .end(); State fp = (State) newStates.get(current.get(f)); try { c.addTransition(new Transition(rp, l, fp)); } catch (NoSuchStateException x) { } } } return c; } }