private static Tuple<PDA<A, S>, PDA<A, S>> ConvertDPDAsToEmptyStack(PDA<A, S> pda1, PDA<A, S> pda2, A furtherAlphabetSymbol)
        {
            if (pda1.AcceptanceCondition.IsEmptyStack() && pda2.AcceptanceCondition.IsEmptyStack())
            {
                return new Tuple<PDA<A, S>, PDA<A, S>>(pda1, pda2);
            }

            if (pda1.AcceptanceCondition.IsFinalState() && pda2.AcceptanceCondition.IsEmptyStack())
            {
                var newPda1 = PDATransformer<A, S>.ToDPDAWithEmptyStack(pda1, furtherAlphabetSymbol);
                var newPda2 = PDATransformer<A, S>.ToDPDAWithAddedAlphabetSymbol(pda2, furtherAlphabetSymbol);
                return new Tuple<PDA<A, S>, PDA<A, S>>(newPda1, newPda2);
            }

            if (pda1.AcceptanceCondition.IsEmptyStack() && pda2.AcceptanceCondition.IsFinalState())
            {
                var newPda1 = PDATransformer<A, S>.ToDPDAWithAddedAlphabetSymbol(pda1, furtherAlphabetSymbol);
                var newPda2 = PDATransformer<A, S>.ToDPDAWithEmptyStack(pda2, furtherAlphabetSymbol);
                return new Tuple<PDA<A, S>, PDA<A, S>>(newPda1, newPda2);
            }

            if (pda1.AcceptanceCondition.IsFinalState() && pda2.AcceptanceCondition.IsFinalState())
            {
                var newPda1 = PDATransformer<A, S>.ToDPDAWithEmptyStack(pda1, furtherAlphabetSymbol);
                var newPda2 = PDATransformer<A, S>.ToDPDAWithEmptyStack(pda2, furtherAlphabetSymbol);
                return new Tuple<PDA<A, S>, PDA<A, S>>(newPda1, newPda2);
            }

            throw new InvalidOperationException("the given pdas have wrong configuration");
        }
        public void ToDPDAWithAddedAlphabetSymbolTest()
        {
            var dpda = new PDA <char, char>(new AcceptanceCondition.EmptyStack(), true, 'Z', false, "ZYX");

            dpda.AddState(1, false);
            dpda.AddState(2, false);

            dpda.AddTransition().From(0).To(0).Read('a').Pop('Z').Push("XZ");
            dpda.AddTransition().From(0).To(0).Read('a').Pop('X').Push("XX");
            dpda.AddTransition().From(0).To(0).Read('a').Pop('Y').Push("XY");
            dpda.AddTransition().From(0).To(0).Read('b').Pop('Z').Push("YZ");
            dpda.AddTransition().From(0).To(0).Read('b').Pop('X').Push("YX");
            dpda.AddTransition().From(0).To(0).Read('b').Pop('Y').Push("YY");

            dpda.AddTransition().From(0).To(1).Read('x').Pop('Z').Push("Z");
            dpda.AddTransition().From(0).To(1).Read('x').Pop('X').Push("X");
            dpda.AddTransition().From(0).To(1).Read('x').Pop('Y').Push("Y");

            dpda.AddTransition().From(1).To(1).Read('a').Pop('X').Push("");
            dpda.AddTransition().From(1).To(1).Read('b').Pop('Y').Push("");

            dpda.AddTransition().From(1).To(2).Read().Pop('Z').Push();

            var act = PDATransformer <char, char> .ToDPDAWithAddedAlphabetSymbol(dpda, '$');

            act.CreateRunner();

            Assert.IsFalse(act.AcceptsWord("").Accepts());
            Assert.IsFalse(act.AcceptsWord("ax").Accepts());
            Assert.IsFalse(act.AcceptsWord("aaxa").Accepts());
            Assert.IsFalse(act.AcceptsWord("xa").Accepts());
            Assert.IsFalse(act.AcceptsWord("axaa").Accepts());
            Assert.IsFalse(act.AcceptsWord("ax$").Accepts());
            Assert.IsFalse(act.AcceptsWord("aaxa$").Accepts());
            Assert.IsFalse(act.AcceptsWord("xa$").Accepts());
            Assert.IsFalse(act.AcceptsWord("axaa$").Accepts());
            Assert.IsFalse(act.AcceptsWord("$").Accepts());

            Assert.IsTrue(act.AcceptsWord("x$").Accepts());
            Assert.IsTrue(act.AcceptsWord("axa$").Accepts());
            Assert.IsTrue(act.AcceptsWord("aaxaa$").Accepts());
            Assert.IsTrue(act.AcceptsWord("aaaxaaa$").Accepts());
        }