コード例 #1
0
ファイル: SST.cs プロジェクト: matejchalk/ARMC
        public static SST <SYMBOL> Union(params SST <SYMBOL>[] taus)
        {
            if (taus.Length == 0)
            {
                throw SSTException.NoSSTsInUnion();
            }
            if (taus.Length == 1)
            {
                return(taus[0]);
            }

            var finalStates = new List <int>(taus.Sum(tau => tau.FinalStates.Count()));
            var moves       = new List <Move <Label <SYMBOL> > >(taus.Length + taus.Sum(tau => tau.Moves.Count()));
            var alphabet    = taus.Select(tau => tau.Alphabet).Aggregate(Set <SYMBOL> .Union);

            int             offset    = 0;
            Func <int, int> translate = state => offset + 1 + state;

            foreach (SST <SYMBOL> tau in taus.Select(tau => tau.Normalize()))
            {
                finalStates.AddRange(tau.FinalStates.Select(translate));
                moves.Add(new Move <Label <SYMBOL> >(0, translate(tau.InitialState), new Label <SYMBOL>(null, null)));
                moves.AddRange(tau.Moves.Select(move => new Move <Label <SYMBOL> >(
                                                    translate(move.SourceState), translate(move.TargetState), move.Label
                                                    )));
                offset += tau.States.Count();
            }

            return(new SST <SYMBOL>(0, finalStates, moves, alphabet));
        }
コード例 #2
0
ファイル: SST.cs プロジェクト: matejchalk/ARMC
        /// <summary>
        /// Compose transducers T1 and T2, resulting in transducer equivalent to applying T2 after T1.
        /// </summary>
        public static SST <SYMBOL> Compose(SST <SYMBOL> tau1, SST <SYMBOL> tau2)
        {
            if (tau1.Algebra != tau2.Algebra)
            {
                throw SSTException.IncompatibleAlphabets();
            }

            LabelAlgebra <SYMBOL> algebra = tau1.Algebra;
            var stack       = new Stack <Tuple <int, int> >();
            var finalStates = new List <int>();
            var moves       = new List <Move <Label <SYMBOL> > >();
            var stateDict   = new Dictionary <Tuple <int, int>, int>();
            int id          = 0;

            var init = new Tuple <int, int>(tau1.InitialState, tau2.InitialState);

            stateDict[init] = id++;
            stack.Push(init);

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

                foreach (Move <Label <SYMBOL> > move1 in tau1.GetMovesFrom(state1))
                {
                    foreach (Move <Label <SYMBOL> > move2 in tau2.GetMovesFrom(state2))
                    {
                        Label <SYMBOL> newLabel = algebra.Combine(move1.Label, move2.Label);
                        if (!algebra.IsSatisfiable(newLabel))
                        {
                            continue;
                        }

                        var targetPair = new Tuple <int, int>(move1.TargetState, move2.TargetState);
                        int targetState;
                        if (!stateDict.TryGetValue(targetPair, out targetState))
                        {
                            stateDict[targetPair] = targetState = id++;
                            stack.Push(targetPair);
                            if (tau1.IsFinalState(move1.TargetState) && tau2.IsFinalState(move2.TargetState))
                            {
                                finalStates.Add(targetState);
                            }
                        }
                        moves.Add(new Move <Label <SYMBOL> >(stateDict[sourcePair], targetState, newLabel));
                    }
                }
            }

            return(new SST <SYMBOL>(0, finalStates, moves));
        }
コード例 #3
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));
        }