예제 #1
0
        public override SSA <SYMBOL> Collapse(SSA <SYMBOL> m)
        {
            m = m.RemoveEpsilons();

            Dictionary <int, Set <int> > labels = MakeLabels(m);

            if (heuristic.HasValue)
            {
                /* remove ignored states from labels */
                foreach (int state in new List <int>(labels.Keys))
                {
                    labels[state] -= ignoredLabels;
                }
            }

            return(m.Collapse((_, q1, q2) => labels[q1] == labels[q2]));
        }
예제 #2
0
파일: SST.cs 프로젝트: matejchalk/ARMC
        /// <summary>
        /// Applies this transducer to automaton M in order to create a new automaton
        /// that accepts the translations of all words in L(M).
        /// </summary>
        public SSA <SYMBOL> Apply(SSA <SYMBOL> m)
        {
            if (this.Algebra.Alphabet != m.Algebra.Alphabet)
            {
                throw SSTException.IncompatibleAlphabets();
            }

            m = m.RemoveEpsilons();

            Automaton <Label <SYMBOL> > tau = this.automaton;
            var stack       = new Stack <Tuple <int, int> >();
            var finalStates = new List <int>();
            var moves       = new List <Move <Predicate <SYMBOL> > >();
            var stateDict   = new Dictionary <Tuple <int, int>, int>();
            int id          = 0;

            var init = new Tuple <int, int>(tau.InitialState, m.InitialState);

            stateDict[init] = id++;              // initial state will be 0
            stack.Push(init);

            Action <Tuple <int, int>, Tuple <int, int>, Predicate <SYMBOL> > addMove = (sourcePair, targetPair, label) => {
                int targetState;
                if (!stateDict.TryGetValue(targetPair, out targetState))
                {
                    stateDict[targetPair] = targetState = id++;
                    stack.Push(targetPair);
                }
                moves.Add(new Move <Predicate <SYMBOL> >(stateDict[sourcePair], targetState, label));
            };

            while (stack.Count > 0)
            {
                Tuple <int, int> sourcePair = stack.Pop();
                int tauState = sourcePair.Item1;
                int mState   = sourcePair.Item2;

                foreach (Move <Label <SYMBOL> > tauMove in tau.GetMovesFrom(tauState))
                {
                    if (tauMove.Label.Input == null)
                    {
                        addMove(
                            sourcePair,
                            new Tuple <int, int>(tauMove.TargetState, mState),
                            tauMove.Label.IsIdentity ? null : tauMove.Label.Output
                            );
                        continue;
                    }

                    foreach (Move <Predicate <SYMBOL> > mMove in m.GetMovesFrom(mState))
                    {
                        if (!m.Algebra.IsSatisfiable(tauMove.Label.Input & mMove.Label))
                        {
                            continue;
                        }
                        Predicate <SYMBOL> newLabel;
                        if (tauMove.Label.IsIdentity)
                        {
                            newLabel = tauMove.Label.Input & mMove.Label;
                        }
                        else
                        {
                            newLabel = tauMove.Label.Output;
                            if (newLabel != null && !m.Algebra.IsSatisfiable(newLabel))
                            {
                                continue;
                            }
                        }
                        addMove(
                            sourcePair,
                            new Tuple <int, int>(tauMove.TargetState, mMove.TargetState),
                            newLabel
                            );
                    }
                }
            }

            foreach (var pair in stateDict)
            {
                if (tau.IsFinalState(pair.Key.Item1) && m.IsFinalState(pair.Key.Item2))
                {
                    finalStates.Add(pair.Value);
                }
            }

            return(new SSA <SYMBOL>(0, finalStates, moves, m.Algebra.Alphabet));
        }
예제 #3
0
        public override void Refine(SSA <SYMBOL> m, SSA <SYMBOL> x)
        {
            int offset = predicateAutomata.Sum(pred => pred.States.Count());

            x = x.RemoveEpsilons().Normalize(offset);

            predicateAutomata.Add(x);

            if (heuristic.HasValue)
            {
                var xStates = new Set <int>(x.States);

                /* find important states (appear in labels) */
                Dictionary <int, Set <int> > labels = MakeLabels(m);
                var importantStates = new Set <int>();
                foreach (int mState in m.States)
                {
                    foreach (int xState in labels[mState])
                    {
                        if (xState < offset || xState >= xStates.Count + offset)
                        {
                            continue;
                        }
                        importantStates.Add(xState);
                    }
                }

                if (((Config.PredHeuristic)heuristic) == Config.PredHeuristic.KeyStates)
                {
                    /* try to find one key state among important states */
                    foreach (int state in importantStates)
                    {
                        /* try ignoring all but one state */
                        ignoredLabels += xStates;
                        ignoredLabels.Remove(state);
                        /* check if the collapsed automaton still intersects */
                        if (SSA <SYMBOL> .ProductIsEmpty(Collapse(m), x))
                        {
                            return;
                        }
                        /* failed, restore temporarily ignored states */
                        ignoredLabels -= xStates;
                    }

                    /* couldn't find just one key state, try to find two */
                    foreach (int state1 in importantStates)
                    {
                        foreach (int state2 in importantStates.Where(s => s != state1))
                        {
                            ignoredLabels += xStates;
                            ignoredLabels.Remove(state1);
                            ignoredLabels.Remove(state2);
                            if (SSA <SYMBOL> .ProductIsEmpty(Collapse(m), x))
                            {
                                return;
                            }
                            ignoredLabels -= xStates;
                        }
                    }

                    /* fall back on important states heuristic */
                }

                /* ignore all unimportant states */
                ignoredLabels += xStates - importantStates;
            }
        }