/* * (C) Copyright 2004 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.converters; import rationals.*; import rationals.properties.isNormalized; import rationals.transformations.Normalizer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * This Converter takes an Automaton and generates an equivalent Regular * expression. * <p> * This conversion applies classical conversion algorithm based on state * removal. * cf. Algorithm BMC (Brozowski et al.) from J.sakarovitch "Eléments de théorie * des automates", sec. 2 * * @version $Id: ToRExpression.java 2 2006-08-24 14:41:48Z oqube $ */ public class ToRExpression<Tr extends Transition<String>, T extends Builder<String, Tr, T>> implements ToString<String, Tr, T> { private Map<Couple, String> keys = new HashMap<>(); /* * (non-Javadoc) * * @see rationals.converters.ToString#toString(rationals.Automaton) */ public String toString(Automaton<String, Tr, T> a) { if(a == null) return "0"; Automaton<String, Tr, T> ret = a.clone(); if (!new isNormalized().test(a)) ret = new Normalizer<String, Tr, T>().transform(a); /* special case for empty automaton */ if (ret.initials().isEmpty()) return "0"; /* add all transitions from start to end state */ State init = ret.initials().iterator().next(); State fini = ret.terminals().iterator().next(); String re = ""; for(Iterator<Transition<String>> i = ret.deltaFrom(init,fini).iterator();i.hasNext();) { Transition<String> tr = i.next(); if("".equals(re)) { re = (tr.label() == null) ? "1" : tr.label().toString(); }else re += "+" + ((tr.label() == null) ? "1" : tr.label().toString()); } if(!"".equals(re)) keys.put(new Couple(init,fini), re); Iterator<State> it = ret.states().iterator(); while (it.hasNext()) { State st = it.next(); if (st.isInitial() || st.isTerminal()) continue; re = ""; /* first handle self transitions */ Iterator<Transition<String>> it2 = ret.delta(st).iterator(); while (it2.hasNext()) { Transition<String> t1 = it2.next(); if (!t1.end().equals(st)) continue; re += "+" + t1.label(); } /* clean first '+' */ if (!"".equals(re)) { re = re.substring(1); if (re.length() > 1) re = "(" + re + ")*"; else re = re + "*"; } Set<Transition<String>> to = ret.delta(st); /* outgoing */ Set<Transition<String>> from = ret.deltaMinusOne(st); /* incoming */ it2 = from.iterator(); while (it2.hasNext()) { /* beware : this is reverse transition */ Transition<String> t1 = it2.next(); if (t1.end().equals(st)) /* skip self transitions */ continue; Iterator<Transition<String>> it3 = to.iterator(); while (it3.hasNext()) { Transition<String> t2 = it3.next(); if (t2.end().equals(st)) continue; /* find completed expression from start to end */ State s2 = t2.end(); State s1 = t1.end(); Couple k = new Couple(s1, s2); String oldre = (String) keys.get(k); String nre = t1.label() + "" + re + t2.label(); if (oldre == null) { oldre = nre; } else { oldre += "+" + nre; } try { keys.put(k, oldre); ret.addTransition(new Transition<String>(s1, oldre, s2)); } catch (NoSuchStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /* returns the transition from stat to end */ re = (String) keys.get(new Couple(init,fini)); return re; } } /* * $Log: ToRExpression.java,v $ Revision 1.3 2005/03/23 07:22:42 bailly created * transductions package corrected EpsilonRemover added some tests removed * DirectedGRaph Interface from Automaton * * Revision 1.2 2005/02/02 14:21:10 bailly corrected bad import * * Revision 1.1 2004/09/21 11:50:28 bailly added interface BinaryTest added * class for testing automaton equivalence (isomorphism of normalized automata) * added computation of RE from Automaton * */