Пример #1
0
        public static SimulationPath <A, S> RunSimulation(PDA <A, S> pda, A[] word)
        {
            var acceptanceResult = pda.AcceptsWord(word);

            if (!acceptanceResult.Accepts())
            {
                throw new NoAcceptanceException("the pda does not accept the word, therefore, a simulation is not possible");
            }

            var initialNode = SimulationNode <A, S> .InitialNode(
                new Configuration <A, S>(pda.InitialState, new Word <A>(word), CurrentStack <S> .WithSingleSymbol(pda.FirstStackSymbol)),
                pda.AcceptanceCondition);

            var frontChain = new List <SimulationNode <A, S> > {
                initialNode
            };

            while (frontChain.Count() > 0)
            {
                var nodesAcceptedWord = frontChain.Where(node => node.HasAcceptedWord).ToList();
                if (nodesAcceptedWord.Count() > 0)
                {
                    return(SimulationPathFromFinalNode(nodesAcceptedWord.First()));
                }

                foreach (var node in frontChain)
                {
                    node.DoStep();
                }

                frontChain = frontChain.SelectMany(node => node.Children).ToList();
            }
            throw new InvalidOperationException("the given pda does not accept the word, therefore a simulation is not possible");
        }
        //FIXME: create own subclass class for derivation start node
        /// <summary>
        /// converts a derivation of a word in a CFG in 2NF, that was originally created from a PDA, back to a path in this PDA;
        /// this path is generated according to the converting-algorithm of a PDA to a CFG implemented in <see cref="PDAToCFGConverter{A, S}"/>;
        /// if this method is called on a CFG that does not fulfill the described conditions, it produces not useful result
        /// </summary>
        /// <param name="pda">pda</param>
        /// <param name="startSymbol">start symbol of the cfg</param>
        /// <param name="word">word of the derivation</param>
        /// <returns></returns>
        public SimulationPath <A, char> ConvertToPDASimulationPath(PDA <A, char> pda, GrammarSymbol startSymbol, A[] word)
        {
            Assertion.Assert(Symbol == startSymbol, "this method should only be called on the start node; FIXME to make it only availabe there");
            Assertion.Assert(productionFromHere.Rhs.Count() == 1, "the first production should only lead to one element");
            Assertion.Assert(children.Count() == 1, "the start symbol should only have one child");

            var symbol   = productionFromHere.Rhs[0].Name;
            var splitted = PDAToCFGConverter <A, char> .SplitNonTerminalId(symbol);

            var firstNode = Node <A, char> .InitialNode(new Configuration <A, char>(pda.States[splitted.Item1],
                                                                                    new Word <A>(word),
                                                                                    CurrentStack <char> .WithSingleSymbol(splitted.Item2)));

            var nodes = new List <Node <A, char> >()
            {
                firstNode
            };

            children.First().ConvertToPDASimulationPath(nodes, pda);

            return(new SimulationPath <A, char>(nodes));
        }