/// <summary> /// Splits the given partition with this group /// </summary> /// <param name="current">The current partition</param> /// <returns>The resulting partition</returns> public DFAPartition Split(DFAPartition current) { DFAPartition partition = new DFAPartition(); foreach (DFAState state in states) { partition.AddState(state, current); } return(partition); }
/// <summary> /// Refines this partition into another one /// </summary> /// <returns>The refined partition</returns> public DFAPartition Refine() { DFAPartition newPartition = new DFAPartition(); // For each group in the current partition // Split the group and add the resulting groups to the new partition foreach (DFAStateGroup group in groups) { newPartition.groups.AddRange(group.Split(this).groups); } return(newPartition); }
/// <summary> /// Gets the minimal automaton equivalent to this ine /// </summary> /// <returns>The minimal DFA</returns> public DFA Minimize() { DFAPartition current = new DFAPartition(this); DFAPartition newPartition = current.Refine(); while (newPartition.GroupCount != current.GroupCount) { current = newPartition; newPartition = current.Refine(); } return(new DFA(newPartition.GetDFAStates())); }
/// <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)); } }
/// <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); }