Example #1
0
 public Matcher(FST fst)
 {
     _FST = fst;
 }
Example #2
0
        public void Concatenate(FST rhs)
        {
            List <int> previouslyFinalStates = GetFinalStates();

            if (previouslyFinalStates.Count == 0)
            {
                throw new Exception("Automaton does not have any final states");
            }

            if (!StateExists(_StartState))
            {
                throw new Exception("Automaton does not have a start state");
            }

            if (!rhs.StateExists(rhs._StartState))
            {
                throw new Exception("RHS Automaton does not have a start state");
            }

            bool lhsStartWasFinal = IsFinal(_StartState);
            bool rhsStartWasFinal = rhs.IsFinal(rhs._StartState);

            // the mapping from the state IDs of the RHS automaton. Key is the
            //  original RHS state ID, Value is the new state ID in the source automaton
            Dictionary <int, int> stateMapping = new Dictionary <int, int>();

            // all previously final states become non-final unless the RHS start state is final
            if (!rhsStartWasFinal)
            {
                foreach (int pf in previouslyFinalStates)
                {
                    SetFinal(pf, false);
                }
            }

            // copy over the states
            foreach (KeyValuePair <int, State> rhsState in rhs._States)
            {
                int newState = AddState();
                stateMapping.Add(rhsState.Value.Id, newState);
                // final states in the RHS automaton remain final
                if (rhsState.Value.IsFinal)
                {
                    SetFinal(newState, true);
                }
            }

            // now that all states exist, copy over the RHS transitions
            foreach (KeyValuePair <int, State> rhsState in rhs._States)
            {
                foreach (FSTTransition t in rhsState.Value.Transitions)
                {
                    AddTransition(stateMapping[t.Source], stateMapping[t.Target],
                                  new Label(t.Input), new Label(t.Output));
                }
            }

            // next, link the two automatons.

            // first, each transition which ends in a previously final state is
            //  copied into a transition to the previous start state of RHS
            int newRhsStart = stateMapping[rhs._StartState];

            foreach (KeyValuePair <int, State> lhsState in _States)
            {
                State testState = lhsState.Value;

                List <FSTTransition> transitions = testState.Transitions;
                // Take care with this iteration as the loop adds to the state's transitions
                for (int transition = transitions.Count - 1; transition >= 0; --transition)
                {
                    FSTTransition link = transitions[transition];
                    if (previouslyFinalStates.Contains(link.Target))
                    {
                        testState.AddTransition(newRhsStart, new Label(link.Input), new Label(link.Output));
                    }
                }
            }

            if (lhsStartWasFinal)
            {
                // need to introduce an eps transition to the rhs start state
                AddTransition(_StartState, newRhsStart,
                              new Label(Label.SpecialSymbolEpsilon),
                              new Label(Label.SpecialSymbolEpsilon));
            }

            Clean();
        }