rationals.converters.ToRExpression Maven / Gradle / Ivy
Show all versions of org.semanticweb.hermit Show documentation
/*______________________________________________________________________________
*
* Copyright 2004 Arnaud Bailly - NORSYS/LIFL
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* (1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* (2) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* (3) The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*______________________________________________________________________________
*
* Created on Sep 13, 2004
*
*/
package rationals.converters;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import rationals.Automaton;
import rationals.Couple;
import rationals.NoSuchStateException;
import rationals.State;
import rationals.Transition;
import rationals.properties.isNormalized;
import rationals.transformations.Normalizer;
/**
* This Converter takes an Automaton and generates an equivalent Regular
* expression.
*
* This conversion applies classical conversion algorithm based on state
* removal.
* cf. Algorithm BMC (Brozowski et al.) from J.sakarovitch "Elements de theorie
* des automates", sec. 2
*
* @author nono
* @version $Id: ToRExpression.java 2 2006-08-24 14:41:48Z oqube $
*/
public class ToRExpression implements ToString {
private Map /* < Key, String > */keys = new HashMap();
/*
* (non-Javadoc)
*
* @see rationals.converters.ToString#toString(rationals.Automaton)
*/
public String toString(Automaton a) {
if(a == null)
return "0";
Automaton ret = (Automaton)a.clone();
if (!new isNormalized().test(a))
ret = new Normalizer().transform(a);
/* special case for empty automaton */
if (ret.initials().isEmpty())
return "0";
/* add all transitions from start to end state */
State init = (State)ret.initials().iterator().next();
State fini = (State)ret.terminals().iterator().next();
String re = "";
for(Iterator i = ret.deltaFrom(init,fini).iterator();i.hasNext();) {
Transition tr = (Transition)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 it = ret.states().iterator();
while (it.hasNext()) {
State st = (State) it.next();
if (st.isInitial() || st.isTerminal())
continue;
re = "";
/* first handle self transitions */
Iterator it2 = ret.delta(st).iterator();
while (it2.hasNext()) {
Transition t1 = (Transition) 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 to = ret.delta(st); /* outgoing */
Set from = ret.deltaMinusOne(st); /* incoming */
it2 = from.iterator();
while (it2.hasNext()) {
/* beware : this is reverse transition */
Transition t1 = (Transition) it2.next();
if (t1.end().equals(st)) /* skip self transitions */
continue;
Iterator it3 = to.iterator();
while (it3.hasNext()) {
Transition t2 = (Transition) 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(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
*
*/