Exemple #1
0
        /// <summary>
        /// Prunes all the unreachable states from this automaton
        /// </summary>
        public void Prune()
        {
            DFAInverse      inverse = new DFAInverse(this);
            List <DFAState> finals  = inverse.CloseByAntecedents(inverse.Finals);

            // no changes
            if (finals.Count == states.Count)
            {
                return;
            }

            // Prune the transitions
            for (int i = 0; i != finals.Count; i++)
            {
                DFAState        state       = finals[i];
                List <CharSpan> transitions = new List <CharSpan>(state.Transitions);
                foreach (CharSpan key in transitions)
                {
                    DFAState child = state.GetChildBy(key);
                    if (!finals.Contains(child))
                    {
                        // the child should be dropped
                        state.RemoveTransition(key);
                    }
                }
            }

            // prune
            DFAState first = states[0];

            finals.Remove(states[0]);
            states.Clear();
            states.Add(first);
            states.AddRange(finals);
        }
Exemple #2
0
        /// <summary>
        /// Extracts the sub-DFA that leads to any of the specified states
        /// </summary>
        /// <param name="targets">States in this DFA</param>
        /// <returns>The sub-DFA for the specified states</returns>
        public DFA ExtractSubTo(IEnumerable <DFAState> targets)
        {
            if (targets == null)
            {
                throw new System.ArgumentException("The specified collection must not be null");
            }

            // build a list of all the required states
            DFAInverse      inverse   = new DFAInverse(this);
            List <DFAState> originals = inverse.CloseByAntecedents(targets);

            // setup the list
            int index = originals.IndexOf(states[0]);

            if (index == -1)
            {
                throw new System.ArgumentException("The specified states are not reachable from the starting state");
            }
            originals[index] = originals[0];
            originals[0]     = states[0];

            // copies the states
            List <DFAState> copy = new List <DFAState>();

            for (int i = 0; i != originals.Count; i++)
            {
                copy.Add(new DFAState(i));
            }
            for (int i = 0; i != originals.Count; i++)
            {
                DFAState original = originals[i];
                DFAState clone    = copy[i];
                clone.AddItems(original.Items);
                foreach (CharSpan key in original.Transitions)
                {
                    index = originals.IndexOf(original.GetChildBy(key));
                    if (index != -1)
                    {
                        clone.AddTransition(key, copy[index]);
                    }
                }
            }
            return(new DFA(copy));
        }