Ejemplo n.º 1
0
        /// <summary>
        /// Builds this inverse graph from the specified DFA
        /// </summary>
        /// <param name="dfa">A DFA</param>
        public DFAInverse(DFA dfa)
        {
            reachable = new List <DFAState>();
            inverses  = new Dictionary <DFAState, List <DFAState> >();
            finals    = new List <DFAState>();

            // transitive closure of the first state
            reachable.Add(dfa.States[0]);
            inverses.Add(dfa.States[0], new List <DFAState>());
            for (int i = 0; i != reachable.Count; i++)
            {
                DFAState current = reachable[i];
                foreach (DFAState next in current.Children)
                {
                    if (!reachable.Contains(next))
                    {
                        reachable.Add(next);
                        inverses.Add(next, new List <DFAState>());
                    }
                    inverses[next].Add(current);
                }
                if (current.Items.Count != 0)
                {
                    finals.Add(current);
                }
            }
        }
Ejemplo n.º 2
0
Archivo: DFA.cs Proyecto: sebgod/hime
        /// <summary>
        /// Creates a new state in this DFA
        /// </summary>
        /// <returns>The create state</returns>
        public DFAState CreateState()
        {
            DFAState state = new DFAState(states.Count);

            states.Add(state);
            return(state);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Closes the specified list of states through inverse transitions
        /// </summary>
        /// <param name="states">The list of states to close</param>
        /// <returns>The closure</returns>
        public List <DFAState> CloseByAntecedents(IEnumerable <DFAState> states)
        {
            List <DFAState> result = new List <DFAState>(states);

            // transitive closure of the final states by their antecedents
            // final states are all reachable
            for (int i = 0; i != result.Count; i++)
            {
                DFAState state = result[i];
                if (!inverses.ContainsKey(state))
                {
                    continue;
                }
                foreach (DFAState antecedent in inverses[state])
                {
                    if (!result.Contains(antecedent) && reachable.Contains(antecedent))
                    {
                        // this antecedent is reachable and not yet in the closure
                        // => add it to the closure
                        result.Add(antecedent);
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 4
0
Archivo: DFA.cs Proyecto: sebgod/hime
        /// <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);
        }
Ejemplo n.º 5
0
Archivo: DFA.cs Proyecto: sebgod/hime
        /// <summary>
        /// Initializes this dfa as equivalent to the given nfa
        /// </summary>
        /// <param name="nfa">A nfa</param>
        public DFA(NFA nfa)
        {
            states = new List <DFAState>();

            List <NFAStateSet> nfaStateSets = new List <NFAStateSet>();
            // Create the first NFA set, add the entry and close it
            NFAStateSet nfaInit = new NFAStateSet();

            nfaStateSets.Add(nfaInit);
            nfaInit.Add(nfa.StateEntry);
            nfaInit.Close();
            // Create the initial state for the DFA
            DFAState dfaInit = new DFAState(0);

            states.Add(dfaInit);

            // For each set in the list of the NFA states
            for (int i = 0; i != nfaStateSets.Count; i++)
            {
                // Normalize transitions
                nfaStateSets[i].Normalize();

                // Get the transitions for the set
                Dictionary <CharSpan, NFAStateSet> transitions = nfaStateSets[i].GetTransitions();
                // For each transition
                foreach (CharSpan value in transitions.Keys)
                {
                    // The child by the transition
                    NFAStateSet next = transitions[value];
                    // Search for the child in the existing sets
                    bool found = false;
                    for (int j = 0; j != nfaStateSets.Count; j++)
                    {
                        // An existing equivalent set is already present
                        if (nfaStateSets[j].Equals(next))
                        {
                            states[i].AddTransition(value, states[j]);
                            found = true;
                            break;
                        }
                    }
                    // The child is not already present
                    if (!found)
                    {
                        // Add to the sets list
                        nfaStateSets.Add(next);
                        // Create the corresponding DFA state
                        DFAState newState = new DFAState(states.Count);
                        states.Add(newState);
                        // Setup transition
                        states[i].AddTransition(value, newState);
                    }
                }
                // Add finals
                states[i].AddItems(nfaStateSets[i].GetFinals());
            }
        }
Ejemplo n.º 6
0
 private int GetDFAStates_GetGroupIndexOf(DFAState state)
 {
     for (int i = 0; i != groups.Count; i++)
     {
         if (groups[i].Contains(state))
         {
             return(i);
         }
     }
     return(-1);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Gets the group of the given state in this partition
 /// </summary>
 /// <param name="state">A state</param>
 /// <returns>The corresponding group</returns>
 private DFAStateGroup AddState_GetGroupOf(DFAState state)
 {
     foreach (DFAStateGroup group in groups)
     {
         if (group.Contains(state))
         {
             return(group);
         }
     }
     return(null);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Determines if the two states have the same marks
 /// </summary>
 /// <param name="left">The left state</param>
 /// <param name="right">The right state</param>
 /// <returns>True if the two states have the same marks</returns>
 private bool DFAPartition_SameFinals(DFAState left, DFAState right)
 {
     if (left.Items.Count != right.Items.Count)
     {
         return(false);
     }
     foreach (FinalItem Final in left.Items)
     {
         if (!right.Items.Contains(Final))
         {
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 9
0
Archivo: DFA.cs Proyecto: sebgod/hime
        /// <summary>
        /// Extracts the sub-DFA that leads to the specified state
        /// </summary>
        /// <param name="state">A state in this DFA</param>
        /// <returns>The sub-DFA for the specified state</returns>
        public DFA ExtractSubTo(DFAState state)
        {
            if (state == null)
            {
                throw new System.ArgumentException("The specified state must not be null");
            }
            if (!states.Contains(state))
            {
                throw new System.ArgumentException("The specified state is not in this DFA");
            }
            List <DFAState> targets = new List <DFAState>(1);

            targets.Add(state);
            return(ExtractSubTo(targets));
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Gets the new dfa states produced by this partition
        /// </summary>
        /// <returns>The dfa states produced by this partition</returns>
        public List <DFAState> GetDFAStates()
        {
            // For each group in the partition
            foreach (DFAStateGroup group in groups)
            {
                bool found = false;
                foreach (DFAState state in group.States)
                {
                    if (state.ID == 0)
                    {
                        groups.Remove(group);
                        groups.Insert(0, group);
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }

            List <DFAState> states = new List <DFAState>();

            // For each group in the partition
            // Create the coresponding state and add the finals
            foreach (DFAStateGroup group in groups)
            {
                // Create a new state
                DFAState newState = new DFAState(states.Count);
                // Add the terminal from the group to the new state
                newState.AddItems(group.Representative.Items);
                states.Add(newState);
            }
            // Do linkage
            for (int i = 0; i != groups.Count; i++)
            {
                foreach (CharSpan Key in groups[i].Representative.Transitions)
                {
                    states[i].AddTransition(Key, states[GetDFAStates_GetGroupIndexOf(groups[i].Representative.GetChildBy(Key))]);
                }
            }
            return(states);
        }
Ejemplo n.º 11
0
Archivo: DFA.cs Proyecto: sebgod/hime
        /// <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));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Adds a state to this partition, coming from the given old partition
        /// </summary>
        /// <param name="state">The state to add</param>
        /// <param name="old">The old partition</param>
        public void AddState(DFAState state, DFAPartition old)
        {
            bool added = false;

            // For each group in the resulting groups set
            foreach (DFAStateGroup group in groups)
            {
                // If the current state can be in this resulting group according to the old partition :
                if (AddState_SameGroup(group.Representative, state, old))
                {
                    // Add the state to the group
                    group.AddState(state);
                    added = true;
                }
            }
            // The state cannot be in any groups : create a new group
            if (!added)
            {
                groups.Add(new DFAStateGroup(state));
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Determines whether two states should be in the same group
 /// </summary>
 /// <param name="s1">A state</param>
 /// <param name="s2">Another state</param>
 /// <param name="old">The old partition</param>
 /// <returns></returns>
 private static bool AddState_SameGroup(DFAState s1, DFAState s2, DFAPartition old)
 {
     if (s1.Transitions.Count != s2.Transitions.Count)
     {
         return(false);
     }
     // For each transition from state 1
     foreach (CharSpan key in s1.Transitions)
     {
         // If state 2 does not have a transition with the same value : not same group
         if (!s2.HasTransition(key))
         {
             return(false);
         }
         // Here State1 and State2 have both a transition of the same value
         // If the target of these transitions are in the same group in the old partition : same transition
         if (old.AddState_GetGroupOf(s1.GetChildBy(key)) != old.AddState_GetGroupOf(s2.GetChildBy(key)))
         {
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Adds a transition from this state
 /// </summary>
 /// <param name="value">The value on the transition</param>
 /// <param name="next">The next state by the transition</param>
 public void AddTransition(CharSpan value, DFAState next)
 {
     transitions.Add(value, next);
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Determines whether the given state is in this group
 /// </summary>
 /// <param name="state">A state</param>
 /// <returns>True of the state is in this group</returns>
 public bool Contains(DFAState state)
 {
     return(states.Contains(state));
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Adds a state to this group
 /// </summary>
 /// <param name="state">The state to add</param>
 public void AddState(DFAState state)
 {
     states.Add(state);
 }
Ejemplo n.º 17
0
 /// <summary>
 /// Initializes this group with a representative state
 /// </summary>
 /// <param name="init">The representative state</param>
 public DFAStateGroup(DFAState init)
 {
     states = new List <DFAState>();
     states.Add(init);
 }