예제 #1
0
        private Fst CreateUnsorted()
        {
            var fst = new Fst(new TropicalSemiring());

            var s1 = new State(0f);
            var s2 = new State(0f);
            var s3 = new State(0f);

            // State 0
            fst.AddState(s1);
            s1.AddArc(new Arc(1, 4, 0f, s2));
            s1.AddArc(new Arc(3, 5, 0f, s2));
            s1.AddArc(new Arc(2, 3, 0f, s2));
            s1.AddArc(new Arc(5, 2, 0f, s3));
            s1.AddArc(new Arc(4, 1, 0f, s3));

            // State 1
            fst.AddState(s2);
            s2.AddArc(new Arc(2, 3, 0f, s2));
            s2.AddArc(new Arc(3, 1, 0f, s3));
            s2.AddArc(new Arc(1, 2, 0f, s3));

            // State 2 (final)
            fst.AddState(s3);

            return(fst);
        }
예제 #2
0
        private Fst CreatePo()
        {
            var ts  = new TropicalSemiring();
            var fst = new Fst(ts);

            var s1 = new State(ts.Zero);
            var s2 = new State(ts.Zero);
            var s3 = new State(ts.Zero);
            var s4 = new State(2f);

            // State 0
            fst.AddState(s1);
            s1.AddArc(new Arc(5, 5, 1f, s2));
            s1.AddArc(new Arc(4, 4, 3f, s2));
            fst.SetStart(s1);

            // State 1
            fst.AddState(s2);
            s2.AddArc(new Arc(3, 3, 7f, s2));
            s2.AddArc(new Arc(2, 2, 5f, s3));

            // State 2
            fst.AddState(s3);
            s3.AddArc(new Arc(1, 1, 9f, s4));

            // State 3
            fst.AddState(s4);

            return(fst);
        }
예제 #3
0
        /**
         * /// Get a filter to use for avoiding multiple epsilon paths in the resulting
         * /// Fst
         * ///
         * /// See: M. Mohri, "Weighted automata algorithms", Handbook of Weighted
         * /// Automata. Springer, pp. 213-250, 2009.
         * ///
         * /// @param syms the gilter's input/output symbols
         * /// @param semiring the semiring to use in the operation
         * /// @return the filter
         */
        public static Fst GetFilter(String[] syms, Semiring semiring)
        {
            Fst filter = new Fst(semiring);

            if (syms == null)
            {
                return(filter); //empty one
            }
            int e1Index = syms == null ? 0 : syms.Length;
            int e2Index = syms == null ? 1 : syms.Length + 1;

            filter.Isyms = syms;
            filter.Osyms = syms;

            // State 0
            State s0 = new State(syms.Length + 3);

            s0.FinalWeight = semiring.One;
            State s1 = new State(syms.Length);

            s1.FinalWeight = semiring.One;
            State s2 = new State(syms.Length);

            s2.FinalWeight = semiring.One;
            filter.AddState(s0);
            s0.AddArc(new Arc(e2Index, e1Index, semiring.One, s0));
            s0.AddArc(new Arc(e1Index, e1Index, semiring.One, s1));
            s0.AddArc(new Arc(e2Index, e2Index, semiring.One, s2));
            for (int i = 1; i < syms.Length; i++)
            {
                s0.AddArc(new Arc(i, i, semiring.One, s0));
            }
            filter.SetStart(s0);

            // State 1
            filter.AddState(s1);
            s1.AddArc(new Arc(e1Index, e1Index, semiring.One, s1));
            for (int i = 1; i < syms.Length; i++)
            {
                s1.AddArc(new Arc(i, i, semiring.One, s0));
            }

            // State 2
            filter.AddState(s2);
            s2.AddArc(new Arc(e2Index, e2Index, semiring.One, s2));
            for (int i = 1; i < syms.Length; i++)
            {
                s2.AddArc(new Arc(i, i, semiring.One, s0));
            }

            return(filter);
        }
예제 #4
0
        /**
         * /// 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.Semiring;
            List <State> fStates  = new List <State>();

            int numStates = fst.GetNumStates();

            for (int i = 0; i < numStates; i++)
            {
                State s = fst.GetState(i);
                if (s.FinalWeight != semiring.Zero)
                {
                    fStates.Add(s);
                }
            }

            // Add a new single final
            State newFinal = new State(semiring.One);

            fst.AddState(newFinal);
            foreach (State s in fStates)
            {
                // add epsilon transition from the old final to the new one
                s.AddArc(new Arc(0, 0, s.FinalWeight, newFinal));
                // set old state's weight to zero
                s.FinalWeight = semiring.Zero;
            }
        }
예제 #5
0
        /**
         * /// Reverses an fst
         * ///
         * /// @param fst the fst to reverse
         * /// @return the reversed fst
         */
        public static Fst Get(Fst fst)
        {
            if (fst.Semiring == null)
            {
                return(null);
            }

            ExtendFinal.Apply(fst);

            Semiring semiring = fst.Semiring;

            Fst res = new Fst(fst.GetNumStates());

            res.Semiring = semiring;

            res.Isyms = fst.Osyms;
            res.Osyms = fst.Isyms;

            State[] stateMap  = new State[fst.GetNumStates()];
            int     numStates = fst.GetNumStates();

            for (int i = 0; i < numStates; i++)
            {
                State _is = fst.GetState(i);
                State s   = new State(semiring.Zero);
                res.AddState(s);
                stateMap[_is.GetId()] = s;
                if (_is.FinalWeight != semiring.Zero)
                {
                    res.SetStart(s);
                }
            }

            stateMap[fst.Start.GetId()].FinalWeight = semiring.One;

            for (int i = 0; i < numStates; i++)
            {
                State olds    = fst.GetState(i);
                State news    = stateMap[olds.GetId()];
                int   numArcs = olds.GetNumArcs();
                for (int j = 0; j < numArcs; j++)
                {
                    Arc   olda = olds.GetArc(j);
                    State next = stateMap[olda.NextState.GetId()];
                    Arc   newa = new Arc(olda.Ilabel, olda.Olabel,
                                         semiring.Reverse(olda.Weight), news);
                    next.AddArc(newa);
                }
            }

            ExtendFinal.Undo(fst);
            return(res);
        }
예제 #6
0
        /**
         * /// Removes epsilon transitions from an fst.
         * ///
         * /// It return a new epsilon-free fst and does not modify the original fst
         * ///
         * /// @param fst the fst to remove epsilon transitions from
         * /// @return the epsilon-free fst
         */
        public static Fst Get(Fst fst)
        {
            if (fst == null)
            {
                return(null);
            }

            if (fst.Semiring == null)
            {
                return(null);
            }

            var semiring = fst.Semiring;

            var res = new Fst(semiring);

            var cl = new Dictionary <State, float> [fst.GetNumStates()];
            var oldToNewStateMap = new State[fst.GetNumStates()];
            var newToOldStateMap = new State[fst.GetNumStates()];

            var numStates = fst.GetNumStates();

            for (var i = 0; i < numStates; i++)
            {
                var s = fst.GetState(i);
                // Add non-epsilon arcs
                var newState = new State(s.FinalWeight);
                res.AddState(newState);
                oldToNewStateMap[s.GetId()]        = newState;
                newToOldStateMap[newState.GetId()] = s;
                if (newState.GetId() == fst.Start.GetId())
                {
                    res.SetStart(newState);
                }
            }

            for (var i = 0; i < numStates; i++)
            {
                var s = fst.GetState(i);
                // Add non-epsilon arcs
                var newState = oldToNewStateMap[s.GetId()];
                var numArcs  = s.GetNumArcs();
                for (var j = 0; j < numArcs; j++)
                {
                    var a = s.GetArc(j);
                    if ((a.Ilabel != 0) || (a.Olabel != 0))
                    {
                        newState.AddArc(new Arc(a.Ilabel, a.Olabel, a.Weight, oldToNewStateMap[a.NextState
                                                                                               .GetId()]));
                    }
                }

                // Compute e-Closure
                if (cl[s.GetId()] == null)
                {
                    CalcClosure(fst, s, cl, semiring);
                }
            }

            // augment fst with arcs generated from epsilon moves.
            numStates = res.GetNumStates();
            for (var i = 0; i < numStates; i++)
            {
                var s        = res.GetState(i);
                var oldState = newToOldStateMap[s.GetId()];
                if (cl[oldState.GetId()] != null)
                {
                    foreach (var pathFinalState in cl[oldState.GetId()].Keys)
                    {
                        var s1 = pathFinalState;
                        if (s1.FinalWeight != semiring.Zero)
                        {
                            s.FinalWeight = semiring.Plus(s.FinalWeight,
                                                          semiring.Times(GetPathWeight(oldState, s1, cl),
                                                                         s1.FinalWeight));
                        }
                        var numArcs = s1.GetNumArcs();
                        for (var j = 0; j < numArcs; j++)
                        {
                            var a = s1.GetArc(j);
                            if ((a.Ilabel != 0) || (a.Olabel != 0))
                            {
                                var newArc = new Arc(a.Ilabel, a.Olabel,
                                                     semiring.Times(a.Weight,
                                                                    GetPathWeight(oldState, s1, cl)),
                                                     oldToNewStateMap[a.NextState.GetId()]);
                                s.AddArc(newArc);
                            }
                        }
                    }
                }
            }

            res.Isyms = fst.Isyms;
            res.Osyms = fst.Osyms;

            Connect.Apply(res);

            return(res);
        }
예제 #7
0
        /**
         * /// Determinizes an fst. The result will be an equivalent fst that has the
         * /// property that no state has two transitions with the same input label. For
         * /// this algorithm, epsilon transitions are treated as regular symbols.
         * ///
         * /// @param fst the fst to determinize
         * /// @return the determinized fst
         */
        public static Fst Get(Fst fst)
        {
            if (fst.Semiring == null)
            {
                // semiring not provided
                return(null);
            }

            // initialize the queue and new fst
            Semiring semiring = fst.Semiring;
            Fst      res      = new Fst(semiring);

            res.Isyms = fst.Isyms;
            res.Osyms = fst.Osyms;

            // stores the queue (item in index 0 is next)
            Queue <List <Pair <State, float> > > queue = new Queue <List <Pair <State, float> > >();

            Dictionary <String, State> stateMapper = new Dictionary <String, State>();

            State  s           = new State(semiring.Zero);
            string stateString = "(" + fst.Start + "," + semiring.One + ")";

            queue.Enqueue(new List <Pair <State, float> >());
            queue.Peek().Add(new Pair <State, float>(fst.Start, semiring.One));
            res.AddState(s);
            stateMapper.Add(stateString, s);
            res.SetStart(s);

            while (queue.Count != 0)
            {
                List <Pair <State, float> > p = queue.Dequeue();
                State pnew = GetStateLabel(p, stateMapper);
                //queueRemoveAt(0);
                List <int> labels = GetUniqueLabels(fst, p);
                foreach (int label in labels)
                {
                    float wnew = semiring.Zero;
                    // calc w'
                    foreach (Pair <State, float> ps in p)
                    {
                        State old     = ps.GetLeft();
                        float u       = ps.GetRight();
                        int   numArcs = old.GetNumArcs();
                        for (int j = 0; j < numArcs; j++)
                        {
                            Arc arc = old.GetArc(j);
                            if (label == arc.Ilabel)
                            {
                                wnew = semiring.Plus(wnew,
                                                     semiring.Times(u, arc.Weight));
                            }
                        }
                    }

                    // calc new states
                    // keep residual weights to variable forQueue
                    List <Pair <State, float> > forQueue = new List <Pair <State, float> >();
                    foreach (Pair <State, float> ps in p)
                    {
                        State old        = ps.GetLeft();
                        float u          = ps.GetRight();
                        float wnewRevert = semiring.Divide(semiring.One, wnew);
                        int   numArcs    = old.GetNumArcs();
                        for (int j = 0; j < numArcs; j++)
                        {
                            Arc arc = old.GetArc(j);
                            if (label == arc.Ilabel)
                            {
                                State oldstate           = arc.NextState;
                                Pair <State, float> pair = GetPair(forQueue,
                                                                   oldstate, semiring.Zero);
                                pair.SetRight(semiring.Plus(
                                                  pair.GetRight(),
                                                  semiring.Times(wnewRevert,
                                                                 semiring.Times(u, arc.Weight))));
                            }
                        }
                    }

                    // build new state's id and new elements for queue
                    string qnewid = "";
                    foreach (Pair <State, float> ps in forQueue)
                    {
                        State old  = ps.GetLeft();
                        float unew = ps.GetRight();
                        if (!qnewid.Equals(""))
                        {
                            qnewid = qnewid + ",";
                        }
                        qnewid = qnewid + "(" + old + "," + unew + ")";
                    }

                    if (stateMapper.Get(qnewid) == null)
                    {
                        State qnew = new State(semiring.Zero);
                        res.AddState(qnew);
                        stateMapper.Add(qnewid, qnew);
                        // update new state's weight
                        float fw = qnew.FinalWeight;
                        foreach (Pair <State, float> ps in forQueue)
                        {
                            fw = semiring.Plus(fw, semiring.Times(ps.GetLeft().FinalWeight, ps.GetRight()));
                        }
                        qnew.FinalWeight = fw;

                        queue.Enqueue(forQueue);
                    }
                    pnew.AddArc(new Arc(label, label, wnew, stateMapper[qnewid]));
                }
            }

            return(res);
        }
예제 #8
0
        /**
         * /// Computes the composition of two Fsts. Assuming no epsilon transitions.
         * ///
         * /// Input Fsts are not modified.
         * ///
         * /// @param fst1 the first Fst
         * /// @param fst2 the second Fst
         * /// @param semiring the semiring to use in the operation
         * /// @param sorted
         * /// @return the composed Fst
         */
        public static Fst compose(Fst fst1, Fst fst2, Semiring semiring, Boolean sorted)
        {
            if (!Arrays.AreEqual(fst1.Osyms, fst2.Isyms))
            {
                // symboltables do not match
                return(null);
            }

            Fst res = new Fst(semiring);

            Dictionary <Pair <State, State>, State> stateMap = new Dictionary <Pair <State, State>, State>();
            Queue <Pair <State, State> >            queue    = new Queue <Pair <State, State> >();

            State s1 = fst1.Start;
            State s2 = fst2.Start;

            if ((s1 == null) || (s2 == null))
            {
                Logger.LogInfo <Compose>("Cannot find initial state.");
                return(null);
            }

            Pair <State, State> p = new Pair <State, State>(s1, s2);
            State s = new State(semiring.Times(s1.FinalWeight,
                                               s2.FinalWeight));

            res.AddState(s);
            res.SetStart(s);
            if (stateMap.ContainsKey(p))
            {
                stateMap[p] = s;
            }
            else
            {
                stateMap.Add(p, s);
            }
            queue.Enqueue(p);

            while (queue.Count != 0)
            {
                p  = queue.Dequeue();
                s1 = p.GetLeft();
                s2 = p.GetRight();
                s  = stateMap[p];
                int numArcs1 = s1.GetNumArcs();
                int numArcs2 = s2.GetNumArcs();
                for (int i = 0; i < numArcs1; i++)
                {
                    Arc a1 = s1.GetArc(i);
                    for (int j = 0; j < numArcs2; j++)
                    {
                        Arc a2 = s2.GetArc(j);
                        if (sorted && a1.Olabel < a2.Ilabel)
                        {
                            break;
                        }
                        if (a1.Olabel == a2.Ilabel)
                        {
                            State nextState1             = a1.NextState;
                            State nextState2             = a2.NextState;
                            Pair <State, State> nextPair = new Pair <State, State>(
                                nextState1, nextState2);
                            State nextState = stateMap.Get(nextPair);
                            if (nextState == null)
                            {
                                nextState = new State(semiring.Times(
                                                          nextState1.FinalWeight,
                                                          nextState2.FinalWeight));
                                res.AddState(nextState);
                                if (stateMap.ContainsKey(nextPair))
                                {
                                    stateMap[nextPair] = nextState;
                                }
                                else
                                {
                                    stateMap.Add(nextPair, nextState);
                                }

                                queue.Enqueue(nextPair);
                            }
                            Arc a = new Arc(a1.Ilabel, a2.Olabel,
                                            semiring.Times(a1.Weight, a2.Weight),
                                            nextState);
                            s.AddArc(a);
                        }
                    }
                }
            }

            res.Isyms = fst1.Isyms;
            res.Osyms = fst2.Osyms;

            return(res);
        }
예제 #9
0
        /**
         * /// Calculates the n-best shortest path from the initial to the final state.
         * ///
         * /// @param fst
         * ///            the fst to calculate the nbest shortest paths
         * /// @param n
         * ///            number of best paths to return
         * /// @param determinize
         * ///            if true the input fst will bwe determinized prior the
         * ///            operation
         * /// @return an fst containing the n-best shortest paths
         */
        public static Fst Get(Fst fst, int n, Boolean determinize)
        {
            if (fst == null)
            {
                return(null);
            }

            if (fst.Semiring == null)
            {
                return(null);
            }
            var fstdet = fst;

            if (determinize)
            {
                fstdet = Determinize.Get(fst);
            }
            var semiring = fstdet.Semiring;
            var res      = new Fst(semiring);

            res.Isyms = fstdet.Isyms;
            res.Osyms = fstdet.Osyms;

            var d = ShortestDistance(fstdet);

            ExtendFinal.Apply(fstdet);

            var r = new int[fstdet.GetNumStates()];

            var queue = new PriorityQueue <Pair <State, float> >(new CustomComparer(d, semiring));

            var previous = new HashMap <Pair <State, float>, Pair <State, float> >(fst.GetNumStates());
            var stateMap = new HashMap <Pair <State, float>, State>(fst.GetNumStates());

            var start = fstdet.Start;
            var item  = new Pair <State, float>(start, semiring.One);

            queue.Add(item);
            previous.Put(item, null);

            while (queue.Count != 0)
            {
                var pair = queue.Remove();
                var p    = pair.GetLeft();
                var c    = pair.GetRight();

                var s = new State(p.FinalWeight);
                res.AddState(s);
                stateMap.Put(pair, s);
                if (previous[pair] == null)
                {
                    // this is the start state
                    res.SetStart(s);
                }
                else
                {
                    // add the incoming arc from previous to current
                    var previouState     = stateMap.Get(previous.Get(pair));
                    var previousOldState = previous.Get(pair).GetLeft();
                    for (var j = 0; j < previousOldState.GetNumArcs(); j++)
                    {
                        var a = previousOldState.GetArc(j);
                        if (a.NextState.Equals(p))
                        {
                            previouState.AddArc(new Arc(a.Ilabel, a.Olabel, a.Weight, s));
                        }
                    }
                }

                var stateIndex = p.GetId();
                r[stateIndex]++;

                if ((r[stateIndex] == n) && (p.FinalWeight != semiring.Zero))
                {
                    break;
                }

                if (r[stateIndex] <= n)
                {
                    for (var j = 0; j < p.GetNumArcs(); j++)
                    {
                        var a    = p.GetArc(j);
                        var cnew = semiring.Times(c, a.Weight);
                        var next = new Pair <State, float>(a.NextState, cnew);
                        previous.Put(next, pair);
                        queue.Add(next);
                    }
                }
            }

            return(res);
        }