Esempio n. 1
0
            public ReachabilityAutomaton(PushdownAutomaton <S, T> pda, bool allstatesarepositive = false)
            {
                this.pda          = pda;
                this.q0           = (allstatesarepositive ? 0 : pda.automaton.MaxState + 1);
                this.__newStateId = (allstatesarepositive ? pda.automaton.MaxState + 1 : pda.automaton.MaxState + 2);
                this.start        = new Tuple <int, int>(this.q0, pda.automaton.InitialState);
                this.Q.Add(this.q0);
                this.Q.UnionWith(pda.automaton.States);
                this.F.UnionWith(pda.automaton.GetFinalStates());
                foreach (var s in pda.stackSymbols)
                {
                    pushMap[s] = new HashSet <Trans>();
                    popMap[s]  = new HashSet <Move <Sequence <T> > >();
                }
                AddPush(this.start, pda.initialStackSymbol);

                #region  initialize transitions
                foreach (int q in pda.automaton.States)
                {
                    foreach (var move in pda.automaton.GetMovesFrom(q))
                    {
                        if (move.Label.PushSymbols.IsEmpty)
                        {
                            AddPop(q, move.TargetState, move.Label.PopSymbol, move.Label.Input);
                        }
                        else
                        {
                            int s = q;
                            int t = GetNewStateId();
                            this.Q.Add(t);
                            var symbs = move.Label.PushSymbols.ToArray();
                            S   a     = move.Label.PopSymbol;
                            var st    = MkTrans(s, t);
                            //first add the pop move s --(a-)--> t to intermediate new state t
                            AddPop(s, t, a, move.Label.Input);
                            //next add the intermediate push symbols, starting from the last
                            for (int i = symbs.Length - 1; i > 0; i--)
                            {
                                s = t;
                                t = GetNewStateId();
                                this.Q.Add(t);
                                st = MkTrans(s, t);
                                AddPush(st, symbs[i]);
                            }
                            //add the top push symbol to the original target state of the move
                            AddPush(MkTrans(t, move.TargetState), symbs[0]);
                        }
                    }
                }
                #endregion

                #region initialize epsilon relation as the initial reflexive relation over states
                foreach (int q in Q)
                {
                    var qq   = new Trans(q, q);
                    var set1 = new HashSet <int>();
                    set1.Add(q);
                    forward[q] = set1;
                    var set2 = new HashSet <int>();
                    set2.Add(q);
                    inverse[q]     = set2;
                    witnessMap[qq] = Sequence <T> .Empty;
                    epsilons.Add(qq);
                }
                #endregion
            }
Esempio n. 2
0
        PushdownAutomaton <S, T> Intersect1(IMinimalAutomaton <T> nfa)
        {
            //depth first product construction, PDA may have epsilon moves
            var stateIdMap  = new Dictionary <Pair, int>();
            int nextStateId = 1;
            var stack       = new SimpleStack <Pair>();
            var moves       = new List <Move <PushdownLabel <S, T> > >();
            var states      = new List <int>();
            var finalstates = new List <int>();

            #region  GetState: push the pair to stack if the state id was new and update final states as needed
            Func <Pair, int> GetState = (pair) =>
            {
                int id;
                if (!stateIdMap.TryGetValue(pair, out id))
                {
                    id               = nextStateId;
                    nextStateId     += 1;
                    stateIdMap[pair] = id;
                    stack.Push(pair);
                    states.Add(id);
                    if (this.automaton.IsFinalState(pair.Item1) && nfa.IsFinalState(pair.Item2))
                    {
                        finalstates.Add(id);
                    }
                }
                return(id);
            };
            #endregion

            var initPair  = new Pair(this.automaton.InitialState, nfa.InitialState);
            int initState = GetState(initPair);

            #region compute the product transitions with depth-first search
            while (stack.IsNonempty)
            {
                var sourcePair = stack.Pop();
                var source     = stateIdMap[sourcePair];
                var pda_state  = sourcePair.Item1;
                var aut_state  = sourcePair.Item2;
                foreach (var pda_move in this.automaton.GetMovesFrom(pda_state))
                {
                    if (pda_move.IsEpsilon || pda_move.Label.InputIsEpsilon)
                    {
                        var targetPair = new Pair(pda_move.TargetState, aut_state);
                        int target     = GetState(targetPair);
                        moves.Add(Move <PushdownLabel <S, T> > .Create(source, target, pda_move.Label));
                    }
                    else
                    {
                        //assuming here that the automaton does not have epsilons
                        foreach (var aut_move in nfa.GetMovesFrom(aut_state))
                        {
                            if (aut_move.IsEpsilon)
                            {
                                throw new AutomataException(AutomataExceptionKind.AutomatonIsNotEpsilonfree);
                            }

                            var cond = nfa.Algebra.MkAnd(aut_move.Label, pda_move.Label.Input);
                            //if the joint condition is not satisfiable then the
                            //joint move does effectively not exist
                            if (nfa.Algebra.IsSatisfiable(cond))
                            {
                                var targetPair = new Pair(pda_move.TargetState, aut_move.TargetState);
                                int target     = GetState(targetPair);
                                var label      = new PushdownLabel <S, T>(cond, pda_move.Label.PushAndPop);
                                var jointmove  = Move <PushdownLabel <S, T> > .Create(source, target, label);

                                moves.Add(jointmove);
                            }
                        }
                    }
                }
            }
            #endregion

            //note: automaton creation eliminates unreachable states and deadend states from the product
            var productAutom = Automaton <PushdownLabel <S, T> > .Create(null, initState, finalstates, moves, true, true);

            var product = new PushdownAutomaton <S, T>(nfa.Algebra, productAutom, this.stackSymbols, this.initialStackSymbol);
            return(product);
        }