Beispiel #1
0
        /// <summary>
        /// Returns the set of all states that can be reached by following epsilon transitions only
        /// </summary>
        /// <param name="nfa"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public Set <TState> EpsilonClosure(INFA <TState, TInput, TTransition> nfa, IEnumerable <TState> group)
        {
            var queue   = new Queue <TState>(group);
            var closure = new Set <TState>();

            while (queue.Count != 0)
            {
                var state = queue.Dequeue();
                closure.Add(state);

                // Targets reachable from the current node not already added to the closure
                var epsilonTargets =
                    nfa.FromSource(state)
                    .Where(t => t.Input.Equals(nfa.Epsilon))
                    .Where(t => !closure.Contains(t.Target))
                    .Select(t => t.Target);

                foreach (var target in epsilonTargets)
                {
                    queue.Enqueue(target);
                }
            }

            return(closure);
        }
Beispiel #2
0
        /// <summary>
        /// Generates and returns the equivalent <see cref="IDFA{TState, TInput, TTransition}"/>
        /// from the supplied <see cref="INFA{TState, TInput, TTransition}"/>
        /// </summary>
        /// <param name="nfa"></param>
        /// <returns></returns>
        public IDFA <TState, TInput, TTransition> DFAFromNFA(INFA <TState, TInput, TTransition> nfa)
        {
            var partial = RemoveDeadStates(EquivalenceMinimization(DFA(nfa)));

            return(new DFA <TState, TInput, TTransition>(
                       partial.Initial,
                       partial.Terminals,
                       partial.Transitions
                       ));
        }
Beispiel #3
0
        /// <summary>
        /// Transforms an <see cref="INFA{TState, TInput, TTransition}"/> to a
        /// <see cref="IDFA{TState, TInput, TTransition}"/> by removing all epsilon
        /// transitions from an NFA by compositing states and transitions under
        /// epsilon closures
        /// </summary>
        /// <param name="nfa"></param>
        /// <returns></returns>
        public PartialDFA DFA(
            INFA <TState, TInput, TTransition> nfa)
        {
            var first            = EpsilonClosure(nfa, Set <TState> .Of(nfa.Initial));
            var groupTransitions = new List <TGroupTransition>();
            var terminalGroups   = new List <Set <TState> >();

            // Create work queue of groups to process
            var unmarkedGroups = new Queue <Set <TState> >();

            unmarkedGroups.Enqueue(first);

            var markedGroups = new Set <Set <TState> >();

            while (unmarkedGroups.Any())
            {
                var group = unmarkedGroups.Dequeue();
                markedGroups.Add(group);

                if (group.Contains(nfa.Terminal))
                {
                    terminalGroups.Add(group);
                }

                // Find new epsilon closed group for each possible input
                foreach (var input in nfa.Inputs.Where(i => !i.Equals(nfa.Epsilon)))
                {
                    var closure = EpsilonClosure(nfa, nfa.Move(group, input));

                    if (!closure.Any())
                    {
                        continue;
                    }

                    // Add unseen groups to unmarked groups
                    if (!unmarkedGroups.Contains(closure) &&
                        !markedGroups.Contains(closure))
                    {
                        unmarkedGroups.Enqueue(closure);
                    }

                    // Add the newly formed transition
                    groupTransitions.Add(GroupTransition(group, input, closure));
                }
            }

            return(Reduce(
                       first,
                       terminalGroups,
                       groupTransitions
                       ));
        }