/* * (C) Copyright 2005 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.transductions; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import rationals.Automaton; import rationals.NoSuchStateException; import rationals.State; import rationals.Transition; import rationals.transformations.InverseMorphism; import rationals.transformations.Mix; import rationals.transformations.Morphism; /** * This class implements a rational transduction by using * Nivat's theorem instead of computing images directly. * Nivat's theorem states that any rational transduction <code>t: X* -> Y*</code> * may be decomposed by means of: * <ul> * <li>an alphabet Z ;</li> * <li> two alphabetic morphisms <code>m:Z* -> X*</code> and <code>n:Z* -> Y*</code>;</li> * <li> a regular language <code>K \in Z*</code>.</li> * </ul> * Then we have: * <code>t(u) = n(m-1(u) \inter K)</code>. * * @author nono * @see J.Berstel, "Rational Transductions and Context-free languages", Teubner B.G., 1979 */ public class TransducerNivat extends Automaton implements Transduction { /* * input morphism */ private Map input = new HashMap(); /* * output morphism */ private Map output = new HashMap(); /** * The label of a transition in a transducer is a couple of letters, * possibliy null. * * @throws ClassCastException if transition is not a TransducerTransition * @see rationals.transductions.TransducerRelation * @see rationals.Rational#addTransition(rationals.Transition) */ public void addTransition(Transition transition) throws NoSuchStateException { // check transition's object is a couple TransducerRelation rel = (TransducerRelation)transition.label(); /* update input and output automata */ input.put(transition.label(),rel.getIn()); output.put(transition.label(),rel.getOut()); super.addTransition(transition); } /* (non-Javadoc) * @see rationals.transductions.Transduction#image(rationals.Automaton) */ public Automaton image(Automaton a) { Morphism m1 = new Morphism(output); InverseMorphism m2 = new InverseMorphism(input); /* * compute inverse morphism */ Automaton b = m2.transform(a); /* * compute intersection with this language */ b = new Mix().transform(b,this); /* * compute output morphism */ b = m1.transform(b); return b; } /* (non-Javadoc) * @see rationals.transductions.Transduction#image(java.util.List) */ public Automaton image(List word) { // create an automaton from word and pass it to image(Automaton) Automaton a = Automaton.labelAutomaton(word); return image(a); } /* (non-Javadoc) * @see rationals.transductions.Transduction#image(java.lang.Object[]) */ public Automaton image(Object[] word) { // create an automaton from word and pass it to image(Automaton) Automaton a = Automaton.labelAutomaton((List)Arrays.asList(word)); return image(a); } /* (non-Javadoc) * @see rationals.transductions.Transduction#inverse(java.util.List) */ public Set inverse(List word) { // TODO Auto-generated method stub return null; } }