/** * * Copyright 1999-2012 Carnegie Mellon University. * Portions Copyright 2002 Sun Microsystems, Inc. * Portions Copyright 2002 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.fst.operations; import java.util.ArrayList; import edu.cmu.sphinx.fst.Arc; import edu.cmu.sphinx.fst.Fst; import edu.cmu.sphinx.fst.State; import edu.cmu.sphinx.fst.semiring.Semiring; /** * Extend an Fst to a single final state and undo operations. * * @author John Salatas */ public class ExtendFinal { /** * Default Contructor */ private ExtendFinal() { } /** * Extends an Fst to a single final state. * * It adds a new final state with a 0.0 (Semiring's 1) final wight and * connects the current final states to it using epsilon transitions with * weight equal to the original final state's weight. * * @param fst the Fst to extend */ public static void apply(Fst fst) { Semiring semiring = fst.getSemiring(); ArrayList<State> fStates = new ArrayList<State>(); int numStates = fst.getNumStates(); for (int i = 0; i < numStates; i++) { State s = fst.getState(i); if (s.getFinalWeight() != semiring.zero()) { fStates.add(s); } } // Add a new single final State newFinal = new State(semiring.one()); fst.addState(newFinal); for (State s : fStates) { // add epsilon transition from the old final to the new one s.addArc(new Arc(0, 0, s.getFinalWeight(), newFinal)); // set old state's weight to zero s.setFinalWeight(semiring.zero()); } } /** * Undo of the extend operation * @param fst fst to work with */ public static void undo(Fst fst) { State f = null; int numStates = fst.getNumStates(); for (int i = 0; i < numStates; i++) { State s = fst.getState(i); if (s.getFinalWeight() != fst.getSemiring().zero()) { f = s; break; } } if (f == null) { System.err.println("Final state not found."); return; } for (int i = 0; i < numStates; i++) { State s = fst.getState(i); for (int j = 0; j < s.getNumArcs(); j++) { Arc a = s.getArc(j); if (a.getIlabel() == 0 && a.getOlabel() == 0 && a.getNextState().getId() == f.getId()) { s.setFinalWeight(a.getWeight()); } } } fst.deleteState(f); } }