Example #1
0
        private static bool Accepts(this INfa <char> nfa, string input, IState state, Dictionary <Tuple <IState, string>, bool> cache)
        {
            if (input == string.Empty && nfa.IsAccepting(state))
            {
                return(true);
            }

            var key = Tuple.Create(state, input);

            if (!cache.ContainsKey(key))
            {
                cache[key] = false; // temporarily mark the (state, string) pair as non-accepting to avoid cycles

                // check epsilon transitions
                var result = nfa.EpsilonTransitions(state).Any(nextState => nfa.Accepts(input, nextState, cache));

                // check transitions using the first letter of input
                if (input.Length > 0)
                {
                    var firstLetter    = input[0];
                    var remainingInput = input.Substring(1);

                    var transitions = nfa.Transitions(state).GetValueOrDefault(firstLetter);
                    if (transitions != null)
                    {
                        result = result || transitions.Any(nextState => nfa.Accepts(remainingInput, nextState, cache));
                    }
                }

                cache[key] = result;
            }

            return(cache.GetValueOrDefault(key));
        }
Example #2
0
        private int ConstructStates(Dictionary <IState, int> stateIds, INfa <Symbol> nfa, IState state)
        {
            if (stateIds.ContainsKey(state))
            {
                return(stateIds[state]);
            }

            int stateId = stateIds.Count;

            stateIds[state] = stateId;

            this.epsilonTransitions.Add(null);
            this.transitions.Add(null);
            this.isAccepting.Add(nfa.IsAccepting(state));

            this.epsilonTransitions[stateId] = nfa.EpsilonTransitions(state).Select(target => new ValueState <int>(this.ConstructStates(stateIds, nfa, target)) as IState).ToList();
            this.transitions[stateId]        = nfa.Transitions(state)
                                               .ToDictionary(
                keySelector: kv => kv.Key,
                elementSelector: kv => kv.Value.Select(target => new ValueState <int>(this.ConstructStates(stateIds, nfa, target))).ToList() as IReadOnlyCollection <IState>);

            return(stateId);
        }
Example #3
0
        public static IDfa <bool, Symbol> Convert(INfa <Symbol> nfa)
        {
            HashSet <Symbol> alphabet = GetAlphabet(nfa);
            Dictionary <Util.HashableHashSet <IState>, DfaState> map = new Dictionary <Util.HashableHashSet <IState>, DfaState>();
            HashSet <DfaState> accepting = new HashSet <DfaState>();
            Dictionary <DfaState, Dictionary <Symbol, IState> > trans = new Dictionary <DfaState, Dictionary <Symbol, IState> >();
            Queue <Util.HashableHashSet <IState> > q = new Queue <Util.HashableHashSet <IState> >();

            Util.HashableHashSet <IState> start = new Util.HashableHashSet <IState> {
                nfa.StartingState()
            };
            Util.HashableHashSet <IState> startingClosure = EpsilonClosure(nfa, start);
            map.Add(startingClosure, new DfaState());
            q.Enqueue(startingClosure);
            while (q.Count != 0)
            {
                Util.HashableHashSet <IState> currentSet = q.Dequeue();
                foreach (IState state in currentSet)
                {
                    if (nfa.IsAccepting(state))
                    {
                        accepting.Add(map[currentSet]);
                        break;
                    }
                }

                Dictionary <Symbol, Util.HashableHashSet <IState> > dict = new Dictionary <Symbol, Util.HashableHashSet <IState> >();
                foreach (IState state in currentSet)
                {
                    IReadOnlyDictionary <Symbol, IReadOnlyCollection <IState> > edges = nfa.Transitions(state);
                    foreach (Symbol key in edges.Keys)
                    {
                        if (!dict.ContainsKey(key))
                        {
                            dict.Add(key, new Util.HashableHashSet <IState>());
                        }

                        foreach (IState s in edges[key])
                        {
                            dict[key].Add(s);
                        }
                    }
                }

                foreach (Symbol key in alphabet)
                {
                    if (!dict.ContainsKey(key))
                    {
                        dict.Add(key, new Util.HashableHashSet <IState>());
                    }
                }

                trans.Add(map[currentSet], new Dictionary <Symbol, IState>());
                foreach (Symbol key in dict.Keys)
                {
                    Util.HashableHashSet <IState> neighbour = EpsilonClosure(nfa, dict[key]);
                    if (!map.ContainsKey(neighbour))
                    {
                        map.Add(neighbour, new DfaState());

                        q.Enqueue(neighbour);
                    }

                    trans[map[currentSet]].Add(key, map[neighbour]);
                }
            }

            return(new Dfa <Symbol>(map[startingClosure], accepting, trans));
        }