package rationals.transformations; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import rationals.Automaton; import rationals.NoSuchStateException; import rationals.State; import rationals.Transition; import rationals.properties.ContainsEpsilon; /** * Compute the concatenation of two automata. * <ul> * <li>C = A . B</li> * <li>S(C) = S(A) U S(B)</li> * <li>S0(C) = * <ul> * <li>S0(A), if not A contains epsilon,</li> * <li>S0(A) U SO(B), otherwise</li> * </ul> * </li> * <li>T(C) = * <ul> * <li>T(B), if not B contains epsilon,</li> * <li>T(A) U T(B), otherwise</li> * </ul> * </li> * <li>D(C) = D(A) U D(B) U { (s1,a,s2) | (s,a,s2) in D(B), s in S0(B),s1 in * T(A) } - {(s,a,s2) in D(B), s in S0(B) }</li> * </ul> * * @author nono * @version $Id: Concatenation.java 2 2006-08-24 14:41:48Z oqube $ */ public class Concatenation implements BinaryTransformation { public Automaton transform(Automaton a, Automaton b) { Automaton ap = new Normalizer().transform(a); Automaton bp = new Normalizer().transform(b); ContainsEpsilon ce = new ContainsEpsilon(); boolean ace = ce.test(a); boolean bce = ce.test(b); if (ap.states().size() == 0 && ace) return b; if (bp.states().size() == 0 && bce) return a; State junc = null; /* junction state */ Automaton c = new Automaton(); Map map = new HashMap(); /* add all states from ap */ Iterator i = ap.states().iterator(); while (i.hasNext()) { State e = (State) i.next(); State n; if (e.isInitial()) { n = c.addState(true, ace && bce); } else if(!e.isTerminal()) n = c.addState(false, e.isTerminal() && bce); else continue; map.put(e, n); } /* add states from bp */ i = bp.states().iterator(); while (i.hasNext()) { State e = (State) i.next(); State n; if (!e.isInitial()) { n = c.addState(false, e.isTerminal()); map.put(e, n); } } /* create junction state */ junc = c.addState(ace,bce); i = ap.delta().iterator(); while (i.hasNext()) { Transition t = (Transition) i.next(); try { if (t.end().isTerminal()) c.addTransition(new Transition((State) map.get(t.start()), t.label(), junc)); else c.addTransition(new Transition((State) map.get(t.start()), t.label(), (State) map.get(t.end()))); } catch (NoSuchStateException x) { } } i = bp.delta().iterator(); while (i.hasNext()) { Transition t = (Transition) i.next(); try { if (t.start().isInitial()) c.addTransition(new Transition(junc, t.label(), (State) map .get(t.end()))); else c.addTransition(new Transition((State) map.get(t.start()), t.label(), (State) map.get(t.end()))); } catch (NoSuchStateException x) { } } return c; } }