示例#1
0
        //public AutomatonModel ConvertNdfaToDfa(AutomatonModel ndfa)
        //{
        //    var dfa = new AutomatonModel();

        //    //Find epsilon transitions for each state
        //    var stateToEpsilonN = new Dictionary<StateModel, List<StateModel>>();
        //    foreach (var state in ndfa.States)
        //    {
        //        FindEpsilonN(ndfa, stateToEpsilonN, state);
        //    }
        //    //FindEpsilonN only adds the E* which have an actual E transitions
        //    //but does not consider the state itself then, hence the loop below
        //    foreach (var state in ndfa.States)
        //    {
        //        if (!stateToEpsilonN.ContainsKey(state))
        //        {
        //            stateToEpsilonN.Add(state, new List<StateModel> { state });
        //        }
        //    }

        //    dfa = BuildDfa(ndfa, stateToEpsilonN);
        //    return dfa;
        //}

        private AutomatonModel BuildDfa(AutomatonModel ndfa, Dictionary <StateModel, List <StateModel> > stateToEpsilonN)
        {
            var initialState = ndfa.States.FirstOrDefault(x => x.IsInitial);

            if (initialState == null)
            {
                throw new Exception("No initial state found.");
            }

            var initList = new List <StateModel> {
                initialState
            };
            var stack = new Stack <List <StateModel> >();

            stack.Push(initList);

            var dfa          = new AutomatonModel();
            var stackHistory = new List <IntermediateDfaStateModel>();

            FindNewStates(stack, stackHistory, stateToEpsilonN, ndfa, dfa);
            stackHistory = stackHistory.DistinctBy(s => s.Name).ToList();
            FindNewTransitions(stackHistory, ndfa, dfa, stateToEpsilonN);

            dfa.Alphabet = ndfa.Alphabet;
            return(dfa);
        }
示例#2
0
        /// <summary>
        /// Reworked assignment five
        /// </summary>
        /// <param name="ndfa"></param>
        /// <returns></returns>
        public AutomatonModel ConvertNdfaToDfa(AutomatonModel ndfa)
        {
            var dfa       = new AutomatonModel();
            var newStates = new Dictionary <StateModel, List <StateModel> >();
            List <StateModel> stateHistory          = new List <StateModel>();
            Queue <IntermediateDfaStateModel> stack = new Queue <IntermediateDfaStateModel>();
            StateModel currentState = new StateModel();

            var initialState = ndfa.States.FirstOrDefault(x => x.IsInitial);

            if (initialState == null)
            {
                throw new Exception("No initial state found.");
            }
            stateHistory.Add(initialState);

            stack.Enqueue(new IntermediateDfaStateModel
            {
                Name   = initialState.Name,
                States = new List <StateModel> {
                    initialState
                }
            });
            dfa.States.Add(initialState);
            dfa.Alphabet = ndfa.Alphabet;

            TraverseNfa(stack, stateHistory, ndfa, dfa);

            return(dfa);
        }
示例#3
0
        public List <string> GetAllWords(AutomatonModel automaton)
        {
            _words = new List <string>();

            var initialState = automaton.States.FirstOrDefault(x => x.IsInitial);

            _words = FindWords(automaton, new List <StateModel>(), initialState, "");

            return(_words);
        }
示例#4
0
        private bool HasOneFinalState(AutomatonModel automaton)
        {
            var finalStatesCount = automaton.States.Count(i => i.IsFinal);

            if (finalStatesCount > 1)
            {
                return(false);
            }
            return(true);
        }
示例#5
0
        public GraphVizFileModel ConvertAutomatonToGenericFile(AutomatonModel automaton)
        {
            var graphVizFile = new GraphVizFileModel();

            //ALPHABET
            string alphabetLine = "";

            foreach (var letter in automaton.Alphabet)
            {
                alphabetLine += letter;
            }
            graphVizFile.Lines.Add(alphabet + " " + alphabetLine);

            //STATES
            string statesLine = "";

            for (int index = 0; index < automaton.States.Count; index++)
            {
                var automatonState = automaton.States[index];
                if (index == automaton.States.Count - 1)
                {
                    statesLine += automatonState.Name;
                }
                else
                {
                    statesLine += automatonState.Name + ",";
                }
            }
            graphVizFile.Lines.Add(states + " " + statesLine);

            //FINAL
            var finalStates = automaton.States.Where(x => x.IsFinal);
            var finalLine   = "";

            foreach (var finalState in finalStates)
            {
                finalLine += finalState.Name;
            }
            graphVizFile.Lines.Add(final + " " + finalLine);

            //TRANSITIONS
            graphVizFile.Lines.Add("transitions:");
            foreach (var automatonTransition in automaton.Transitions)
            {
                var transitionLine =
                    $"{automatonTransition.BeginState.Name},{automatonTransition.Value} --> {automatonTransition.EndState.Name}";
                graphVizFile.Lines.Add(transitionLine);
            }

            //END.
            graphVizFile.Lines.Add("end.");

            return(graphVizFile);
        }
        public AutomatonModel GetAutomaton(string input)
        {
            _automaton = new AutomatonModel();

            var nodes = ParseRegularExpression(input);

            _automaton  = NodesToAutomaton(nodes);
            _stateCount = 0;

            return(_automaton);
        }
示例#7
0
        private void TryAddTransitionOnItself(AutomatonModel automaton, TransitionModel transition, string newWord)
        {
            var moreTransitions = automaton.Transitions.Where(
                x =>
                x.BeginState == x.EndState &&
                x.BeginState == transition.EndState);

            if (moreTransitions.Count() > 0)
            {
                foreach (var moreTransition in moreTransitions)
                {
                    _words.Add(GetNewWord(newWord, moreTransition));
                }
            }
        }
示例#8
0
        public string IsStringAcceptedInFile(string input, AutomatonModel automaton)
        {
            var inFile = automaton.Words.FirstOrDefault(t => t.Key == input);

            if (inFile.Key == null)
            {
                return("NaN");
            }
            if (inFile.Value)
            {
                return("True");
            }
            else if (!inFile.Value)
            {
                return("False");
            }
            return("NaN");
        }
示例#9
0
 private bool HasOutputsEqualAlphabetCount(AutomatonModel automaton)
 {
     foreach (var automatonState in automaton.States)
     {
         int outputCount = 0;
         foreach (var automatonTransition in automaton.Transitions)
         {
             if (automatonTransition.BeginState == automatonState)
             {
                 outputCount++;
             }
         }
         if (outputCount != automaton.Alphabet.Count)
         {
             return(false);
         }
     }
     return(true);
 }
示例#10
0
 private bool StatesHaveOutputsWithAllLetters(AutomatonModel automaton)
 {
     foreach (var automatonState in automaton.States)
     {
         List <char> letters = new List <char>();
         foreach (var automatonTransition in automaton.Transitions)
         {
             if (automatonTransition.BeginState == automatonState)
             {
                 letters.Add(Convert.ToChar(automatonTransition.Value));
             }
         }
         var sequenceEqual = letters.OrderBy(t => t).SequenceEqual(automaton.Alphabet.OrderBy(t => t));
         if (!sequenceEqual)
         {
             return(false);
         }
     }
     return(true);
 }
示例#11
0
        public GraphVizFileModel ConvertToGraphVizFile(AutomatonModel automaton)
        {
            var file = new GraphVizFileModel();

            file.Lines.Add("digraph myAutomaton {");
            file.Lines.Add("rankdir=LR;");
            file.Lines.Add("\"\"[shape = none]");

            //Add initials
            foreach (var automatonState in automaton.States)
            {
                if (automatonState.IsFinal && automatonState.IsInitial)
                {
                    file.Lines.Add($"\"{automatonState.Name}\" [shape=doublecircle]");
                    file.Lines.Add($"\"\" -> \"{automatonState.Name}\"");
                }
                else if (automatonState.IsFinal)
                {
                    file.Lines.Add($"\"{automatonState.Name}\" [shape=doublecircle]");
                }
                else if (automatonState.IsInitial)
                {
                    file.Lines.Add($"\"{automatonState.Name}\" [shape=circle]");
                    file.Lines.Add($"\"\" -> \"{automatonState.Name}\"");
                }
                else
                {
                    file.Lines.Add($"\"{automatonState.Name}\" [shape=circle]");
                }
            }

            //add transitions
            foreach (var transition in automaton.Transitions)
            {
                file.Lines.Add($"\"{transition.BeginState.Name}\" -> \"{transition.EndState.Name}\" [label=\"{transition.Value}\"]");
            }

            file.Lines.Add("}");

            return(file);
        }
示例#12
0
        public bool IsAutomatonDfa(AutomatonModel automaton)
        {
            //conditions:
            //outputs of all states are equal to alphabet count
            //outputs of all states have all alphabet values
            //only one final state
            if (!HasOneFinalState(automaton))
            {
                return(false);
            }
            if (!HasOutputsEqualAlphabetCount(automaton))
            {
                return(false);
            }
            if (!StatesHaveOutputsWithAllLetters(automaton))
            {
                return(false);
            }

            return(true);
        }
示例#13
0
        private void FindEpsilonN(AutomatonModel ndfa, Dictionary <StateModel, List <StateModel> > stateToEpsilonN, StateModel state)
        {
            foreach (var transition in ndfa.Transitions)
            {
                if (transition.BeginState == state && transition.Value == "ε")
                {
                    if (stateToEpsilonN.ContainsKey(state))
                    {
                        stateToEpsilonN[state].Add(transition.EndState);
                    }
                    else
                    {
                        stateToEpsilonN.Add(state, new List <StateModel> {
                            state, transition.EndState
                        });
                    }

                    FindEpsilonN(ndfa, stateToEpsilonN, transition.EndState);
                }
            }
        }
示例#14
0
        private List <string> FindWords(AutomatonModel automaton, List <StateModel> passedStates, StateModel state,
                                        string word)
        {
            foreach (var transition in automaton.Transitions)
            {
                if (transition.BeginState == state)
                {
                    var newWord         = GetNewWord(word, transition);
                    var newPassedStates = new List <StateModel>(passedStates)
                    {
                        state
                    };

                    if (!IsLoop(passedStates, state))
                    {
                        if (transition.EndState.IsFinal)
                        {
                            _words.Add(newWord);
                            TryAddTransitionOnItself(automaton, transition, newWord);
                        }
                        else
                        {
                            FindWords(automaton, newPassedStates, transition.EndState, newWord);
                        }
                    }
                    else
                    {
                        if (transition.EndState.IsFinal)
                        {
                            _words.Add(newWord);
                            TryAddTransitionOnItself(automaton, transition, newWord);
                        }
                    }
                }
            }
            return(_words);
        }
示例#15
0
        private StateModel AddHistoryToDfa(AutomatonModel dfa, IntermediateDfaStateModel newHistoryItem)
        {
            var newState = new StateModel()
            {
                Name = newHistoryItem.Name,
            };

            if (dfa.States.All(s => s.Name != newState.Name))
            {
                dfa.States.Add(newState);
            }
            else
            {
                newState = dfa.States.Find(s => s.Name == newState.Name);
            }

            dfa.Transitions.Add(new TransitionModel
            {
                BeginState = newHistoryItem.OriginatingState,
                EndState   = newState,
                Value      = newHistoryItem.Value
            });
            return(newState);
        }
示例#16
0
        public bool IsAcceptedStringByPda(string input, AutomatonModel automaton)
        {
            Stack <string>         stack  = new Stack <string>();
            List <char>            values = new List <char>();
            List <TransitionModel> possibleTransitions = new List <TransitionModel>();
            StateModel             currentState        = new StateModel();

            _isAcceptedStringFound = false;

            currentState = automaton.States.FirstOrDefault(s => s.IsInitial);


            if (string.IsNullOrEmpty(input) ||
                string.IsNullOrWhiteSpace(input))
            {
                return(IsEmptyWordAccepted(automaton, currentState, stack, false));
            }

            foreach (var c in input)
            {
                values.Add(c);
            }
            return(TraversePda(automaton, values, currentState, stack, false));
        }
示例#17
0
        public void IsAutomatonDfaWithNonDfa_Test()
        {
            // arrange
            DfaService dfaService = new DfaService();

            AutomatonModel automaton = new AutomatonModel()
            {
                IsDfaInFile = true
            };

            var stateZ = new StateModel()
            {
                IsFinal = false, IsInitial = true, Name = "z"
            };
            var stateA = new StateModel()
            {
                IsFinal = false, IsInitial = false, Name = "a"
            };
            var stateB = new StateModel()
            {
                IsFinal = true, IsInitial = false, Name = "b"
            };

            List <StateModel> states = new List <StateModel> {
                stateB, stateA, stateZ
            };
            List <TransitionModel> transitions = new List <TransitionModel>()
            {
                new TransitionModel()
                {
                    BeginState = stateZ, EndState = stateA, Value = "a"
                },
                new TransitionModel()
                {
                    BeginState = stateZ, EndState = stateZ, Value = "b"
                },
                new TransitionModel()
                {
                    BeginState = stateZ, EndState = stateB, Value = "b"
                },

                new TransitionModel()
                {
                    BeginState = stateA, EndState = stateZ, Value = "b"
                },
                new TransitionModel()
                {
                    BeginState = stateA, EndState = stateB, Value = "a"
                },

                new TransitionModel()
                {
                    BeginState = stateB, EndState = stateB, Value = "b"
                },
                new TransitionModel()
                {
                    BeginState = stateB, EndState = stateZ, Value = "a"
                },
            };
            var alphabet = new List <char>()
            {
                'a', 'b'
            };

            automaton.States      = states;
            automaton.Transitions = transitions;
            automaton.Alphabet    = alphabet;

            var expected = false;

            // act
            var actual = dfaService.IsAutomatonDfa(automaton);

            // assert
            Assert.AreEqual(expected, actual);
        }
示例#18
0
        private void TraverseNfa(Queue <IntermediateDfaStateModel> queue, List <StateModel> stateHistory, AutomatonModel ndfa, AutomatonModel dfa)
        {
            IntermediateDfaStateModel currentStates = new IntermediateDfaStateModel();

            if (queue.Any())
            {
                currentStates = queue.Dequeue();
            }
            else
            {
                return;
            }
            var originatingState = dfa.States.Find(s => s.Name == currentStates.Name);

            foreach (var letter in ndfa.Alphabet)
            {
                IntermediateDfaStateModel newHistoryItem = new IntermediateDfaStateModel();

                foreach (var currentState in currentStates.States)
                {
                    foreach (var state in ndfa.States)
                    {
                        foreach (var transition in ndfa.Transitions)
                        {
                            if (currentState == state &&
                                transition.Value == letter.ToString() &&
                                transition.BeginState == currentState)
                            {
                                //create history item
                                //add each state to states list and add statename like += to history name
                                newHistoryItem.States.Add(transition.EndState);
                                newHistoryItem.Name            += transition.EndState.Name;
                                newHistoryItem.Value            = transition.Value;
                                newHistoryItem.OriginatingState = originatingState;
                            }
                            else if (currentState == state &&
                                     transition.Value == _empty &&
                                     transition.BeginState == currentState)
                            {
                                IntermediateDfaStateModel epsilonHistoryItem = FindEpsilonTransitions(originatingState, currentState, transition.EndState, letter, ndfa, dfa);

                                if (epsilonHistoryItem.Name == null)
                                {
                                    continue;
                                }

                                newHistoryItem.States.AddRange(epsilonHistoryItem.States);
                                newHistoryItem.Name            += epsilonHistoryItem.Name;
                                newHistoryItem.Value            = epsilonHistoryItem.Value;
                                newHistoryItem.OriginatingState = originatingState;
                            }
                        }
                    }
                    //build new state and transition of the dfa
                    //also add the new state to the stack
                }
                if (newHistoryItem.Name == null)
                {
                    continue;
                }

                var newState = AddHistoryToDfa(dfa, newHistoryItem);
                if (stateHistory.All(s => s.Name != newState.Name))
                {
                    queue.Enqueue(newHistoryItem);
                    stateHistory.Add(newState);
                }
            }
            //from the history add to stack
            //and also create new state with transition


            if (queue.Any())
            {
                TraverseNfa(queue, stateHistory, ndfa, dfa);
            }
            else
            {
                //check also if a final state exists
                //Im not entirely sure about the theory for dfa's
                //but i made only one final state possible.
                //either the last processed one or
                //if the first processed state was initial already
                if (dfa.States.Any(s => s.IsFinal))
                {
                    return;
                }
                var lastState = dfa.States.LastOrDefault();
                if (lastState != null)
                {
                    lastState.IsFinal = true;
                }
            }
        }
示例#19
0
        private List <TransitionModel> ReadPdaTransitions(GraphVizFileModel graphVizFileModel, int lower, int upper, AutomatonModel automaton)
        {
            var transitions = new List <TransitionModel>();

            for (int i = lower; i < upper; i++)
            {
                var transition = new TransitionModel();

                var transitionString = graphVizFileModel.Lines[i];
                var beginStateString = transitionString.Substring(0, transitionString.IndexOf(',')).Trim();

                string valueString = "", leftStackString = "", rightStackString = "";
                if (transitionString.Contains("["))
                {
                    valueString =
                        transitionString.Substring(transitionString.IndexOf(',') + 1, transitionString.IndexOf('[') - 2)
                        .Trim();
                    leftStackString = transitionString.Substring(transitionString.IndexOf('[') + 1,
                                                                 transitionString.IndexOf(',')).ToLower();

                    rightStackString = transitionString.Substring(transitionString.IndexOf(',', transitionString.IndexOf(',') + 1) + 1, 1).ToLower();
                }
                else
                {
                    valueString =
                        transitionString.Substring(transitionString.IndexOf(',') + 1, transitionString.IndexOf(',') + 3)
                        .Trim();
                    leftStackString  = "_";
                    rightStackString = "_";
                }
                var endStateString = transitionString.Substring(transitionString.IndexOf('>') + 1).Trim();

                foreach (var state in automaton.States)
                {
                    if (state.Name.Equals(beginStateString) && i == lower)
                    {
                        transition.BeginState = state;
                        state.IsInitial       = true;
                    }
                    else if (state.Name.Equals(beginStateString))
                    {
                        transition.BeginState = state;
                    }
                    if (state.Name.Equals(endStateString))
                    {
                        transition.EndState = state;
                    }
                    if (transition.BeginState != null && transition.EndState != null)
                    {
                        break;
                    }
                }
                valueString = valueString.ToLower();
                if (valueString.Equals("_"))
                {
                    valueString = "ε";
                }
                if (leftStackString.Equals("_"))
                {
                    leftStackString = "ε";
                }
                if (rightStackString.Equals("_"))
                {
                    rightStackString = "ε";
                }

                transition.PushStack = rightStackString;
                transition.PopStack  = leftStackString;
                transition.Value     = valueString;
                transitions.Add(transition);
            }
            return(transitions);
        }
示例#20
0
        public AutomatonModel ParseGraphVizFile(GraphVizFileModel graphVizFileModel)
        {
            string states   = "states:";
            string final    = "final:";
            string alphabet = "alphabet:";
            string stack    = "stack:";

            var automaton = new AutomatonModel();

            foreach (var line in graphVizFileModel.Lines)
            {
                if (line.Contains(alphabet))
                {
                    var chars = GetSubstring(line, alphabet);
                    foreach (var c in chars)
                    {
                        automaton.Alphabet.Add(char.ToLower(c));
                    }
                }
                else if (line.Contains(stack))
                {
                    var chars = GetSubstring(line, stack);
                    foreach (var c in chars)
                    {
                        automaton.AccecptedStack.Add(char.ToLower(c).ToString());
                    }
                    automaton.IsPda = true;
                }
                else if (line.Contains(states))
                {
                    var sub   = GetSubstring(line, states);
                    var chars = SplitOnComma(sub);
                    foreach (var c in chars)
                    {
                        var state = new StateModel()
                        {
                            Name = c.ToUpper()
                        };
                        automaton.States.Add(state);
                    }
                }
                else if (line.Contains(final))
                {
                    var sub   = GetSubstring(line, final);
                    var chars = SplitOnComma(sub);
                    foreach (var c in chars)
                    {
                        foreach (var state in automaton.States)
                        {
                            if (c.Equals(state.Name))
                            {
                                state.IsFinal = true;
                            }
                        }
                    }
                }
                else if (line.Contains("transitions"))
                {
                    var lower = graphVizFileModel.Lines.IndexOf(line) + 1;
                    //todo: change upper to next "end."
                    var upper = FindUpperLimit(graphVizFileModel.Lines.IndexOf(line), graphVizFileModel.Lines);

                    var transitions = new List <TransitionModel>();
                    transitions = !automaton.IsPda ?
                                  ReadRegularAutomatonTransitions(graphVizFileModel, lower, upper, automaton) :
                                  ReadPdaTransitions(graphVizFileModel, lower, upper, automaton);

                    automaton.Transitions = transitions;
                    //break;
                }
                else if (line.Contains("words"))
                {
                    var lower = graphVizFileModel.Lines.IndexOf(line) + 1;
                    var upper = FindUpperLimit(graphVizFileModel.Lines.IndexOf(line), graphVizFileModel.Lines);
                    automaton.Words = ReadWords(graphVizFileModel, lower, upper);
                }
                else if (line.Contains("dfa"))
                {
                    var last = line[line.Length - 1];
                    automaton.IsDfaInFile = last == 'y';
                }
                else if (line.Contains("finite"))
                {
                    var last = line[line.Length - 1];
                    automaton.IsFiniteInFile = last == 'y';
                }
            }
            return(automaton);
        }
示例#21
0
        public void IsAcceptedString_Test()
        {
            //arrange
            LanguageCheckService languageCheckService = new LanguageCheckService();

            AutomatonModel automaton = new AutomatonModel()
            {
                IsDfaInFile = false
            };

            var stateZ = new StateModel()
            {
                IsFinal = false, IsInitial = true, Name = "z"
            };
            var stateA = new StateModel()
            {
                IsFinal = false, IsInitial = false, Name = "a"
            };
            var stateB = new StateModel()
            {
                IsFinal = true, IsInitial = false, Name = "b"
            };

            List <StateModel> states = new List <StateModel> {
                stateB, stateA, stateZ
            };
            List <TransitionModel> transitions = new List <TransitionModel>()
            {
                new TransitionModel()
                {
                    BeginState = stateZ, EndState = stateA, Value = "a"
                },
                new TransitionModel()
                {
                    BeginState = stateZ, EndState = stateZ, Value = "b"
                },

                new TransitionModel()
                {
                    BeginState = stateA, EndState = stateZ, Value = "b"
                },
                new TransitionModel()
                {
                    BeginState = stateA, EndState = stateB, Value = "a"
                },

                new TransitionModel()
                {
                    BeginState = stateB, EndState = stateB, Value = "b"
                },
                new TransitionModel()
                {
                    BeginState = stateB, EndState = stateZ, Value = "a"
                },
            };
            var alphabet = new List <char>()
            {
                'a', 'b'
            };

            automaton.States      = states;
            automaton.Transitions = transitions;
            automaton.Alphabet    = alphabet;

            //accepted
            var word1 = "aab";
            var word2 = "baab";
            var word3 = "abaa";
            var word4 = "abaab";

            //not accepted
            var word5 = "abb";
            var word6 = "ba";
            var word7 = "aaa";

            var expected_word1 = true;
            var expected_word2 = true;
            var expected_word3 = true;
            var expected_word4 = true;

            var expected_word5 = false;
            var expected_word6 = false;
            var expected_word7 = false;

            //act

            //accepted
            var actual_word1 = languageCheckService.IsAcceptedString(word1, automaton);
            var actual_word2 = languageCheckService.IsAcceptedString(word2, automaton);
            var actual_word3 = languageCheckService.IsAcceptedString(word3, automaton);
            var actual_word4 = languageCheckService.IsAcceptedString(word4, automaton);

            //not accepted
            var actual_word5 = languageCheckService.IsAcceptedString(word5, automaton);
            var actual_word6 = languageCheckService.IsAcceptedString(word6, automaton);
            var actual_word7 = languageCheckService.IsAcceptedString(word7, automaton);

            //assert
            Assert.AreEqual(expected_word1, actual_word1);
            Assert.AreEqual(expected_word2, actual_word2);
            Assert.AreEqual(expected_word3, actual_word3);
            Assert.AreEqual(expected_word4, actual_word4);

            Assert.AreEqual(expected_word5, actual_word5);
            Assert.AreEqual(expected_word6, actual_word6);
            Assert.AreEqual(expected_word7, actual_word7);
        }
示例#22
0
        private bool TraversePda(AutomatonModel automaton, List <char> values, StateModel currentState, Stack <string> stack, bool localIsAcceptedStringFound)
        {
            string empty = "ε";
            List <TransitionModel> possibleTransitions;

            //if there is stack but empty transition can remove stack we still have
            //to check the top of stack and see if transition can remove it
            //then another recursion, there are possibly more stack items
            if (stack.Any() &&
                !values.Any())
            {
                possibleTransitions = automaton.Transitions.Where(s => s.BeginState == currentState && s.Value == empty).ToList();
                if (!possibleTransitions.Any())
                {
                    return(false);
                }

                foreach (var possibleTransition in possibleTransitions)
                {
                    if (possibleTransition.PopStack != empty &&
                        possibleTransition.PushStack == empty)
                    {
                        if (stack.Any() &&
                            stack.Peek() == possibleTransition.PopStack)
                        {
                            stack.Pop();
                        }
                        else
                        {
                            //if multiple stack letters are possible its not automatically false.
                            if (stack.Any() &&
                                automaton.AccecptedStack.Contains(stack.Peek()))
                            {
                                continue;
                            }
                            return(false);
                        }


                        if (!stack.Any() &&
                            possibleTransition.EndState.IsFinal)
                        {
                            _isAcceptedStringFound = true;
                        }

                        TraversePda(automaton, values, possibleTransition.EndState, stack, false);
                    }
                }
            }

            //check if values empty = processed all inputs
            //+ if the currentstate is an endstate
            //+ stack is empty
            if (!values.Any() &&
                currentState.IsFinal &&
                !stack.Any())
            {
                _isAcceptedStringFound = true;
                return(_isAcceptedStringFound);
            }

            foreach (var value in values)
            {
                possibleTransitions = automaton.Transitions.Where(s => s.BeginState == currentState).ToList();
                foreach (var possibleTransition in possibleTransitions)
                {
                    //must conisder also emtpyt
                    //must check if final state when word complete
                    //accepted string: final state & stack empty
                    if (possibleTransition.Value == value.ToString())
                    {
                        //pop/push = empty and stack empty
                        if (possibleTransition.PopStack == empty &&
                            possibleTransition.PushStack == empty &&
                            !stack.Any())
                        {
                            return(_isAcceptedStringFound);
                        }
                        //[_, x] case 1
                        else if (possibleTransition.PopStack == empty &&
                                 possibleTransition.PushStack != empty)
                        {
                            if (_isAcceptedStringFound)
                            {
                                return(true);
                            }

                            stack.Push(possibleTransition.PushStack);
                            //var newStack = GetNewPushedStack(stack, possibleTransition.PushStack);
                            var newValues = GetNewValues(values);
                            TraversePda(automaton, newValues, possibleTransition.EndState, stack, false);
                        }
                        //[x,_] case 1
                        else if (possibleTransition.PopStack != empty &&
                                 possibleTransition.PushStack == empty)
                        {
                            if (_isAcceptedStringFound)
                            {
                                return(true);
                            }

                            if (stack.Any() &&
                                stack.Peek() == possibleTransition.PopStack)
                            {
                                stack.Pop();
                            }
                            else
                            {
                                return(false);
                            }

                            var newValues = GetNewValues(values);
                            TraversePda(automaton, newValues, possibleTransition.EndState, stack, false);
                        }
                        //[x,x]
                        if (possibleTransition.PopStack == possibleTransition.PushStack &&
                            possibleTransition.PopStack != empty &&
                            possibleTransition.PushStack != empty &&
                            stack.Any())
                        {
                            if (_isAcceptedStringFound)
                            {
                                return(true);
                            }

                            var newValues = GetNewValues(values);
                            TraversePda(automaton, newValues, possibleTransition.EndState, stack, false);
                        }
                    }
                    else if (possibleTransition.Value == empty)
                    {
                        if (_isAcceptedStringFound)
                        {
                            return(true);
                        }

                        // case 3
                        if (stack.Any())
                        {
                            if (stack.Peek() == possibleTransition.PopStack)
                            {
                                stack.Pop();
                            }
                            else if (possibleTransition.PopStack == empty) // pop stack is empty = traverse w/o removing values
                            {
                                //do nothing
                            }
                            else
                            {
                                return(false);
                            }
                            TraversePda(automaton, values, possibleTransition.EndState, stack, false);
                        }
                        //case 4
                        else
                        {
                            if (possibleTransition.PopStack == empty &&
                                possibleTransition.PushStack == empty)
                            {
                                TraversePda(automaton, values, possibleTransition.EndState, stack, false);
                            }
                            else if (possibleTransition.PopStack == empty &&
                                     possibleTransition.PushStack != empty)
                            {
                                stack.Push(possibleTransition.PushStack);
                                TraversePda(automaton, values, possibleTransition.EndState, stack, false);
                            }
                        }
                    }
                }


                //  if (!stack.Any() && value == values[values.Count - 1]) return true; //doesnt consider end state
            }

            return(_isAcceptedStringFound);
        }
示例#23
0
        private void FindNewStates(Stack <List <StateModel> > stack, List <IntermediateDfaStateModel> stackHistory, Dictionary <StateModel, List <StateModel> > stateToEpsilonN, AutomatonModel ndfa, AutomatonModel dfa)
        {
            List <StateModel> currentStates;

            if (stack.Any())
            {
                currentStates = stack.Pop();
            }
            else
            {
                return;
            }

            foreach (var currentState in currentStates)
            {
                foreach (var state in ndfa.States)
                {
                    foreach (var letter in ndfa.Alphabet)
                    {
                        foreach (var transition in ndfa.Transitions)
                        {
                            //check if state is in epsilon transition
                            if (currentState == state &&
                                state == transition.BeginState &&
                                letter.ToString() == transition.Value)
                            {
                                AddToStackHistory(stackHistory, currentStates);
                                var epsilonStates         = stateToEpsilonN[transition.EndState];
                                var newStatesForRecursion = new List <StateModel>();
                                var newState = new StateModel();

                                foreach (var epsilonState in epsilonStates)
                                {
                                    newStatesForRecursion.Add(epsilonState);
                                    newState.Name += epsilonState.Name + ",";
                                }
                                if (newState.Name.EndsWith(","))
                                {
                                    newState.Name = newState.Name.TrimEnd(',');
                                }



                                //TODO: eventually add something extra for final state
                                if ((state.IsInitial || state.IsFinal) &&
                                    dfa.States.All(s => s.Name != state.Name))
                                {
                                    dfa.States.Add(state);
                                }
                                else if (transition.EndState.IsFinal &&
                                         dfa.States.All(s => s.Name != transition.EndState.Name))
                                {
                                    dfa.States.Add(transition.EndState);
                                    stackHistory.Add(new IntermediateDfaStateModel()
                                    {
                                        Name   = transition.EndState.Name,
                                        States = new List <StateModel> {
                                            transition.EndState
                                        }
                                    });
                                }

                                if (dfa.States.All(s => s.Name != newState.Name))
                                {
                                    dfa.States.Add(newState);
                                    stack.Push(newStatesForRecursion);
                                }
                                FindNewStates(stack, stackHistory, stateToEpsilonN, ndfa, dfa);

                                //dfa.Transitions.Add(new TransitionModel
                                //{
                                //    BeginState = state,
                                //    EndState = newState,
                                //    Value = letter.ToString()
                                //});
                            }
                        }
                    }
                }
            }
        }
示例#24
0
        private void FindNewTransitions(List <IntermediateDfaStateModel> stackHistory, AutomatonModel ndfa, AutomatonModel dfa, Dictionary <StateModel, List <StateModel> > stateToEpsilonN)
        {
            //check each transition in original automaton for each letter
            //beginstate must be in stackhistory and endstate is E*
            //then the transition is beginstate = stackhistory combined and end state is E*
            //there must be verified if the transition in the new automaton already exists
            foreach (var history in stackHistory)
            {
                foreach (var historyState in history.States)
                {
                    foreach (var transition in ndfa.Transitions)
                    {
                        foreach (var letter in ndfa.Alphabet)
                        {
                            if (historyState == transition.BeginState &&
                                transition.Value == letter.ToString())
                            {
                                var epsilonStates = stateToEpsilonN[transition.EndState];
                                if (history.States.Count == 1)
                                {
                                    if (historyState.IsInitial ||
                                        historyState.IsFinal)
                                    {
                                        var endStateName = "";
                                        foreach (var epsilonState in epsilonStates)
                                        {
                                            if (epsilonState == epsilonStates[epsilonStates.Count - 1])
                                            {
                                                endStateName += epsilonState.Name;
                                            }
                                            else
                                            {
                                                endStateName += epsilonState.Name + ",";
                                            }
                                        }
                                        var endState = new StateModel {
                                            Name = endStateName
                                        };

                                        var trans = new TransitionModel
                                        {
                                            BeginState = historyState,
                                            EndState   = endState,
                                            Value      = letter.ToString()
                                        };

                                        if (dfa.States.All(s => s.Name != historyState.Name))
                                        {
                                            dfa.States.Add(historyState);
                                        }
                                        if (dfa.States.All(s => s.Name != endState.Name))
                                        {
                                            dfa.States.Add(endState);
                                        }
                                        dfa.Transitions.Add(trans);
                                    }
                                }
                                else if (history.States.Count > 1)
                                {
                                    var beginStateName = "";
                                    foreach (var state in history.States)
                                    {
                                        if (state == history.States[history.States.Count - 1])
                                        {
                                            beginStateName += state.Name;
                                        }
                                        else
                                        {
                                            beginStateName += state.Name + ",";
                                        }
                                    }
                                    var beginState = new StateModel {
                                        Name = beginStateName
                                    };

                                    var endStateName = "";
                                    foreach (var epsilonState in epsilonStates)
                                    {
                                        if (epsilonState == epsilonStates[epsilonStates.Count - 1])
                                        {
                                            endStateName += epsilonState.Name;
                                        }
                                        else
                                        {
                                            endStateName += epsilonState.Name + ",";
                                        }
                                    }
                                    var endState = new StateModel {
                                        Name = endStateName
                                    };

                                    var trans = new TransitionModel
                                    {
                                        BeginState = beginState,
                                        EndState   = endState,
                                        Value      = letter.ToString()
                                    };
                                    if (dfa.States.All(s => s.Name != endState.Name))
                                    {
                                        dfa.States.Add(endState);
                                    }
                                    if (dfa.States.All(s => s.Name != beginState.Name))
                                    {
                                        dfa.States.Add(beginState);
                                    }
                                    dfa.Transitions.Add(trans);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#25
0
        public bool IsAcceptedString(string input, AutomatonModel automaton)
        {
            List <StateModel>      currentStates       = automaton.States.Where(x => x.IsInitial).ToList();
            List <StateModel>      nextStates          = new List <StateModel>();
            List <char>            values              = new List <char>();
            List <TransitionModel> possibleTransitions = new List <TransitionModel>();

            foreach (var c in input)
            {
                values.Add(c);
            }

            for (int i = 0; i < values.Count; i++)
            {
                var value = values[i];
                possibleTransitions = automaton.Transitions.Where(s => currentStates.Contains(s.BeginState)).ToList();
                for (int index = 0; index < possibleTransitions.Count; index++)
                {
                    var possibleTransition = possibleTransitions[index];
                    //check if transition is possible and if its the last one
                    if (possibleTransition.Value == value.ToString())
                    {
                        nextStates.Add(possibleTransition.EndState);
                    }
                    else if (possibleTransition.Value == "ε")
                    {
                        //check if epsilon endState has a transition with value[index]
                        //if yes add to nextstates
                        var transitionsAfterEpsilon =
                            automaton.Transitions.Where(
                                transition =>
                                transition.BeginState == possibleTransition.EndState &&
                                transition.Value == Convert.ToString(values[i]))
                            .ToList();

                        if (transitionsAfterEpsilon.Any())
                        {
                            foreach (var transition in transitionsAfterEpsilon)
                            {
                                nextStates.Add(transition.BeginState);
                            }
                        }
                    }

                    if (possibleTransition.EndState.IsFinal &&
                        i == values.Count - 1 &&
                        nextStates.Any())
                    {
                        return(true);
                    }
                }
                //if yes then check the next state;
                if (!nextStates.Any())
                {
                    return(false);
                }

                currentStates.Clear();
                currentStates = new List <StateModel>(nextStates);
                nextStates.Clear();
            }
            return(false);
        }
示例#26
0
        private IntermediateDfaStateModel FindEpsilonTransitions(StateModel originatingState, StateModel currentState, StateModel transitionEndState, char letter, AutomatonModel ndfa, AutomatonModel dfa)
        {
            IntermediateDfaStateModel historyItem = new IntermediateDfaStateModel();

            foreach (var transition in ndfa.Transitions)
            {
                if (transition.BeginState == transitionEndState &&
                    transition.Value == letter.ToString())
                {
                    //create the new history item and return
                    historyItem.States.Add(transition.EndState);
                    historyItem.Name            += transition.EndState.Name;
                    historyItem.Value            = transition.Value;
                    historyItem.OriginatingState = originatingState;
                }
                else if (transition.BeginState == transitionEndState &&
                         transition.Value == _empty)
                {
                    //continue recursion
                }
            }
            return(historyItem);
        }
示例#27
0
        public void ConvertNdfaToDfa_Test2()
        {
            //arrange
            DfaService dfaService = new DfaService();

            AutomatonModel ndfa = new AutomatonModel();

            StateModel state1 = new StateModel()
            {
                IsFinal = false, IsInitial = true, Name = "1"
            };
            StateModel state2 = new StateModel()
            {
                IsFinal = false, IsInitial = false, Name = "2"
            };
            StateModel state3 = new StateModel()
            {
                IsFinal = true, IsInitial = false, Name = "3"
            };
            StateModel state4 = new StateModel()
            {
                IsFinal = false, IsInitial = false, Name = "4"
            };

            ndfa.States.Add(state1);
            ndfa.States.Add(state2);
            ndfa.States.Add(state3);
            ndfa.States.Add(state4);

            TransitionModel trans1 = new TransitionModel()
            {
                BeginState = state1, EndState = state2, Value = "a"
            };
            TransitionModel trans2 = new TransitionModel()
            {
                BeginState = state1, EndState = state4, Value = "c"
            };
            TransitionModel trans3 = new TransitionModel()
            {
                BeginState = state2, EndState = state1, Value = "ε"
            };
            TransitionModel trans4 = new TransitionModel()
            {
                BeginState = state2, EndState = state3, Value = "b"
            };
            TransitionModel trans5 = new TransitionModel()
            {
                BeginState = state3, EndState = state2, Value = "a"
            };
            TransitionModel trans6 = new TransitionModel()
            {
                BeginState = state4, EndState = state3, Value = "ε"
            };
            TransitionModel trans7 = new TransitionModel()
            {
                BeginState = state4, EndState = state3, Value = "c"
            };

            ndfa.Transitions.Add(trans1);
            ndfa.Transitions.Add(trans2);
            ndfa.Transitions.Add(trans3);
            ndfa.Transitions.Add(trans4);
            ndfa.Transitions.Add(trans5);
            ndfa.Transitions.Add(trans6);
            ndfa.Transitions.Add(trans7);

            ndfa.Alphabet.Add('a');
            ndfa.Alphabet.Add('b');
            ndfa.Alphabet.Add('c');

            int expected_nr_transitions     = 8;
            int expected_transitions_with_a = 4;
            int expected_transitions_with_b = 1;
            int expected_transitions_with_c = 3;
            int expected_nr_states          = 4;

            //act
            var dfa = dfaService.ConvertNdfaToDfa(ndfa);

            int actual_nr_transitions     = dfa.Transitions.Count;
            int actual_transitions_with_a = dfa.Transitions.Where(t => t.Value == "a").ToList().Count;
            int actual_transitions_with_b = dfa.Transitions.Where(t => t.Value == "b").ToList().Count;
            int actual_transitions_with_c = dfa.Transitions.Where(t => t.Value == "c").ToList().Count;
            int actual_nr_states          = dfa.States.Count;

            //assert
            Assert.AreEqual(expected_nr_states, actual_nr_states);
            Assert.AreEqual(expected_nr_transitions, actual_nr_transitions);
            Assert.AreEqual(expected_transitions_with_a, actual_transitions_with_a);
            Assert.AreEqual(expected_transitions_with_b, actual_transitions_with_b);
            Assert.AreEqual(expected_transitions_with_c, actual_transitions_with_c);
        }
示例#28
0
        private List <TransitionModel> ReadRegularAutomatonTransitions(GraphVizFileModel graphVizFileModel, int lower, int upper, AutomatonModel automaton)
        {
            var transitions = new List <TransitionModel>();

            for (int i = lower; i < upper; i++)
            {
                var transition = new TransitionModel();

                var transitionString = graphVizFileModel.Lines[i];
                var beginStateString = transitionString.Substring(0, transitionString.IndexOf(',')).Trim();
                var valueString      =
                    transitionString.Substring(transitionString.IndexOf(',') + 1, transitionString.IndexOf('-') - 2)
                    .Trim();
                var endStateString = transitionString.Substring(transitionString.IndexOf('>') + 1).Trim();

                foreach (var state in automaton.States)
                {
                    if (state.Name.Equals(beginStateString) && i == lower)
                    {
                        transition.BeginState = state;
                        state.IsInitial       = true;
                    }
                    else if (state.Name.Equals(beginStateString))
                    {
                        transition.BeginState = state;
                    }
                    if (state.Name.Equals(endStateString))
                    {
                        transition.EndState = state;
                    }
                    if (transition.BeginState != null && transition.EndState != null)
                    {
                        break;
                    }
                }
                valueString = valueString.ToLower();
                if (valueString.Equals("_"))
                {
                    valueString = "ε";
                }
                transition.Value = valueString;

                transitions.Add(transition);
            }
            return(transitions);
        }
        private AutomatonModel BuildAutomaton(NodeModel currentNode, NodeModel previousNode, StateModel leftState, StateModel rightState)
        {
            if (currentNode == null)
            {
                return(null);
            }

            #region dot
            if (currentNode.Value == Dot)
            {
                if (previousNode == null) //initial aut.
                {
                    var state1 = new StateModel {
                        IsInitial = true, IsFinal = false, Name = _stateCount++.ToString()
                    };
                    var state2 = new StateModel {
                        IsInitial = false, IsFinal = false, Name = _stateCount++.ToString()
                    };
                    var state3 = new StateModel {
                        IsInitial = false, IsFinal = true, Name = _stateCount++.ToString()
                    };

                    var dotAutomaton = new AutomatonModel()
                    {
                        States = { state1, state2, state3 },
                    };
                    _automaton = dotAutomaton;

                    if (IsOperandOrAsterix(currentNode.LeftChild.Value))
                    {
                        BuildAutomaton(currentNode.LeftChild, currentNode, state1, state2);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel
                        {
                            BeginState = state1, EndState = state2, Value = currentNode.LeftChild.Value
                        });
                    }

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, state2, state3);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel
                        {
                            BeginState = state2, EndState = state3, Value = currentNode.RightChild.Value
                        });
                    }
                }
                else
                {
                    var middleState = new StateModel {
                        Name = _stateCount++.ToString()
                    };
                    _automaton.States.Add(middleState);

                    if (IsOperandOrAsterix(currentNode.LeftChild.Value))
                    {
                        BuildAutomaton(currentNode.LeftChild, currentNode, leftState, middleState);
                    }
                    else
                    {
                        if (currentNode.LeftChild != null)
                        {
                            var trans = new TransitionModel
                            {
                                BeginState = leftState,
                                EndState   = middleState,
                                Value      = currentNode.LeftChild.Value
                            };
                            _automaton.Transitions.Add(trans);
                        }
                    }

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, middleState, rightState);
                    }
                    else // in the value
                    {
                        if (currentNode.RightChild != null)
                        {
                            var trans = new TransitionModel()
                            {
                                BeginState = middleState,
                                EndState   = rightState,
                                Value      = currentNode.RightChild.Value
                            };
                            _automaton.Transitions.Add(trans);
                        }
                    }
                }
            }
            #endregion

            #region asterix
            else if (currentNode.Value == Asterix)
            {
                if (previousNode == null) //initial aut.
                {
                    var state1 = new StateModel {
                        IsFinal = false, IsInitial = true, Name = _stateCount++.ToString()
                    };
                    var state2 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var state3 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var state4 = new StateModel {
                        IsFinal = true, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var trans1 = new TransitionModel {
                        BeginState = state1, EndState = state2, Value = "ε"
                    };
                    var trans3 = new TransitionModel {
                        BeginState = state3, EndState = state4, Value = "ε"
                    };
                    var trans4 = new TransitionModel {
                        BeginState = state1, EndState = state4, Value = "ε"
                    };
                    var trans5 = new TransitionModel {
                        BeginState = state3, EndState = state2, Value = "ε"
                    };

                    var asterixAutomaton = new AutomatonModel()
                    {
                        States      = { state1, state2, state3, state4 },
                        Transitions = { trans1, trans3, trans4, trans5 }
                    };
                    _automaton = asterixAutomaton;

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, state2, state3);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel()
                        {
                            BeginState = state2, EndState = state3, Value = currentNode.RightChild.Value
                        });
                    }
                }
                else
                {
                    var state1 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var state2 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var state3 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };
                    var state4 = new StateModel {
                        IsFinal = false, IsInitial = false, Name = _stateCount++.ToString()
                    };

                    var transLeftTo1 = new TransitionModel {
                        BeginState = leftState, EndState = state1, Value = "ε"
                    };
                    var trans4ToRight = new TransitionModel {
                        BeginState = state4, EndState = rightState, Value = "ε"
                    };
                    var trans1To2 = new TransitionModel {
                        BeginState = state1, EndState = state2, Value = "ε"
                    };
                    var trans1To4 = new TransitionModel {
                        BeginState = state1, EndState = state4, Value = "ε"
                    };
                    var trans3To2 = new TransitionModel {
                        BeginState = state3, EndState = state2, Value = "ε"
                    };
                    var trans3To4 = new TransitionModel {
                        BeginState = state3, EndState = state4, Value = "ε"
                    };

                    _automaton.States.Add(state1);
                    _automaton.States.Add(state2);
                    _automaton.States.Add(state3);
                    _automaton.States.Add(state4);

                    _automaton.Transitions.Add(transLeftTo1);
                    _automaton.Transitions.Add(trans4ToRight);
                    _automaton.Transitions.Add(trans1To2);
                    _automaton.Transitions.Add(trans1To4);
                    _automaton.Transitions.Add(trans3To2);
                    _automaton.Transitions.Add(trans3To4);

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, state2, state3);
                    }
                    else
                    {
                        if (currentNode.RightChild != null)
                        {
                            _automaton.Transitions.Add(new TransitionModel()
                            {
                                BeginState = state2,
                                EndState   = state3,
                                Value      = currentNode.RightChild.Value
                            });
                        }
                    }
                }
            }
            #endregion

            #region or
            else if (currentNode.Value == Or)
            {
                if (previousNode == null)
                {
                    var state1 = new StateModel {
                        IsInitial = true, IsFinal = false, Name = _stateCount++.ToString()
                    };
                    var state2 = new StateModel {
                        IsInitial = false, IsFinal = true, Name = _stateCount++.ToString()
                    };
                    var orAutomaton = new AutomatonModel
                    {
                        States = { state1, state2 }
                    };

                    _automaton = orAutomaton;

                    if (IsOperandOrAsterix(currentNode.LeftChild.Value))
                    {
                        BuildAutomaton(currentNode.LeftChild, currentNode, state1, state2);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel
                        {
                            BeginState = state1, EndState = state2, Value = currentNode.LeftChild.Value
                        });
                    }

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, state1, state2);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel
                        {
                            BeginState = state1, EndState = state2, Value = currentNode.RightChild.Value
                        });
                    }
                }
                else
                {
                    if (IsOperandOrAsterix(currentNode.LeftChild.Value))
                    {
                        BuildAutomaton(currentNode.LeftChild, currentNode, leftState, rightState);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel()
                        {
                            BeginState = leftState,
                            EndState   = rightState,
                            Value      = currentNode.LeftChild.Value
                        });
                    }

                    if (IsOperandOrAsterix(currentNode.RightChild.Value))
                    {
                        BuildAutomaton(currentNode.RightChild, currentNode, leftState, rightState);
                    }
                    else
                    {
                        _automaton.Transitions.Add(new TransitionModel()
                        {
                            BeginState = leftState,
                            EndState   = rightState,
                            Value      = currentNode.RightChild.Value
                        });
                    }
                }
            }
            #endregion

            return(_automaton);
        }
示例#30
0
        private bool IsEmptyWordAccepted(AutomatonModel automaton, StateModel currentState, Stack <string> stack, bool localIsAcceptedStringFound)
        {
            string empty = "ε";
            List <TransitionModel> possibleTransitions;

            if (currentState.IsFinal &&
                !stack.Any())
            {
                //check if final is start and see if transition exists
                //where push/pop = empty
                //else false
                if (currentState.IsFinal &&
                    currentState.IsInitial)
                {
                    possibleTransitions = automaton.Transitions.Where(s =>
                                                                      s.BeginState == currentState &&
                                                                      s.BeginState == s.EndState &&
                                                                      s.PopStack == empty &&
                                                                      s.PushStack == empty)
                                          .ToList();

                    if (possibleTransitions.Any())
                    {
                        _isAcceptedStringFound = true;
                    }
                    else
                    {
                        return(false);
                    }
                }

                _isAcceptedStringFound = true;
            }


            possibleTransitions = automaton.Transitions.Where(s => s.BeginState == currentState).ToList();
            foreach (var possibleTransition in possibleTransitions)
            {
                if (possibleTransition.Value == empty)
                {
                    if (possibleTransition.PopStack == empty &&
                        possibleTransition.PushStack == empty &&
                        !stack.Any())
                    {
                        if (possibleTransition.EndState.IsFinal)
                        {
                            _isAcceptedStringFound = true;
                        }
                        else
                        {
                            IsEmptyWordAccepted(automaton, possibleTransition.EndState, stack, false);
                        }
                    }
                    else if (possibleTransition.PopStack == empty &&
                             possibleTransition.PushStack != empty)
                    {
                        if (_isAcceptedStringFound)
                        {
                            return(true);
                        }

                        stack.Push(possibleTransition.PushStack);
                        IsEmptyWordAccepted(automaton, possibleTransition.EndState, stack, false);
                    }
                    //[x,_] case 1
                    else if (possibleTransition.PopStack != empty &&
                             possibleTransition.PushStack == empty)
                    {
                        if (_isAcceptedStringFound)
                        {
                            return(true);
                        }

                        if (stack.Any() &&
                            stack.Peek() == possibleTransition.PopStack)
                        {
                            stack.Pop();
                        }
                        else
                        {
                            return(false);
                        }

                        IsEmptyWordAccepted(automaton, possibleTransition.EndState, stack, false);
                    }
                }
            }


            return(_isAcceptedStringFound);
        }