/// <summary> /// Gets Move of a state. /// </summary> /// <param name="state">state for which to get Move</param> /// <param name="chInputSymbol">Input symbol</param> /// <returns>Set of Move</returns> private Set Move(State state, string sInputSymbol) { Set set = new Set(); State[] arrTrans = state.GetTransitions(sInputSymbol); if (arrTrans != null) { set.AddElementRange(arrTrans); } return(set); }
/// <summary> /// /// </summary> /// <param name="stateStart">start state of the model</param> /// <param name="setProcessed">when function returns, this set contains all the states</param> /// <param name="setAllState">when function returns, this set contains all the input symbols</param> public static void GetAllStateAndInput(State stateStart, HashSet <State> setAllState, HashSet <string> setInputSymbols) { if (stateStart == null) { throw new ArgumentNullException(nameof(stateStart)); } if (setAllState == null) { throw new ArgumentNullException(nameof(setAllState)); } if (setInputSymbols == null) { throw new ArgumentNullException(nameof(setInputSymbols)); } HashSet <State> setUnprocessed = new HashSet <State> { stateStart }; while (setUnprocessed.Count > 0) { State state = setUnprocessed.FirstOrDefault(); setAllState.Add(state); setUnprocessed.Remove(state); foreach (string sSymbol in state.AllKeys) { setInputSymbols.Add(sSymbol); foreach (State stateEpsilon in state.GetTransitions(sSymbol)) { if (!setAllState.Contains(stateEpsilon)) { setUnprocessed.Add(stateEpsilon); } } // end of inner foreach..loop } // end of outer foreach..loop } // end of outer while..loop }
static internal int GetSerializedFsa(State stateStart, Set setAllState, Set setAllSymbols, StringBuilder sb) { int nLineLength = 0; int nMinWidth = 6; string sLine = String.Empty; string sFormat = String.Empty; setAllSymbols.RemoveElement(MetaSymbol.EPSILON); setAllSymbols.AddElement(MetaSymbol.EPSILON); // adds it at the end; // construct header row and format string object[] arrObj = new object[setAllSymbols.Count + 1];// the extra one becuase of the first State column arrObj[0] = "State"; sFormat = "{0,-8}"; for (int i = 0; i < setAllSymbols.Count; i++) { string sSymbol = setAllSymbols[i].ToString(); arrObj[i + 1] = sSymbol; sFormat += " | "; sFormat += "{" + (i + 1).ToString() + ",-" + Math.Max(Math.Max(sSymbol.Length, nMinWidth), sSymbol.ToString().Length) + "}"; } sLine = String.Format(sFormat, arrObj); nLineLength = Math.Max(nLineLength, sLine.Length); sb.AppendLine(("").PadRight(nLineLength, '-')); sb.AppendLine(sLine); sb.AppendLine(("").PadRight(nLineLength, '-')); // construct the rows for transtion int nTransCount = 0; foreach (object objState in setAllState) { State state = (State)objState; arrObj[0] = (state.Equals(stateStart) ? ">" + state.ToString() : state.ToString()); for (int i = 0; i < setAllSymbols.Count; i++) { string sSymbol = setAllSymbols[i].ToString(); State[] arrStateTo = state.GetTransitions(sSymbol); string sTo = String.Empty; if (arrStateTo != null) { nTransCount += arrStateTo.Length; sTo = arrStateTo[0].ToString(); for (int j = 1; j < arrStateTo.Length; j++) { sTo += ", " + arrStateTo[j].ToString(); } } else { sTo = "--"; } arrObj[i + 1] = sTo; } sLine = String.Format(sFormat, arrObj); sb.AppendLine(sLine); nLineLength = Math.Max(nLineLength, sLine.Length); } sFormat = "State Count: {0}, Input Symbol Count: {1}, Transition Count: {2}"; sLine = String.Format(sFormat, setAllState.Count, setAllSymbols.Count, nTransCount); nLineLength = Math.Max(nLineLength, sLine.Length); sb.AppendLine(("").PadRight(nLineLength, '-')); sb.AppendLine(sLine); nLineLength = Math.Max(nLineLength, sLine.Length); setAllSymbols.RemoveElement(MetaSymbol.EPSILON); return(nLineLength); }
/// <summary> /// Partions set of all DFA states into smaller groups (according to the partion rules). /// Please see notes for detail of partioning DFA. /// </summary> /// <param name="setMasterDfa">Set of all DFA states</param> /// <param name="setInputSymbol">Set of all input symbol</param> /// <returns>Array of DFA groups</returns> private ArrayList PartitionDfaGroups(Set setMasterDfa, Set setInputSymbol) { ArrayList arrGroup = new ArrayList(); // array of all set (group) of DFA states. Map map = new Map(); // to keep track of which memeber transition into which group Set setEmpty = new Set(); // first we need to create two partition of the setMasterDfa: // one with all the accepting states and the other one with all the non-accpeting states Set setAccepting = new Set(); // group of all accepting state Set setNonAccepting = new Set(); // group of all non-accepting state foreach (object objState in setMasterDfa) { State state = (State)objState; if (state.AcceptingState == true) { setAccepting.AddElement(state); } else { setNonAccepting.AddElement(state); } } if (setNonAccepting.GetCardinality() > 0) { arrGroup.Add(setNonAccepting); // add this newly created partition to the master list } // for accepting state, there should always be at least one state, if NOT then there must be something wrong somewhere arrGroup.Add(setAccepting); // add this newly created partition to the master list //第一步 分成setAccepting与setNonAccepting 将所有的AcceptingState 加入setAccepting。 // now we iterate through these two partitions and see if they can be further partioned. // we continuew the iteration until no further paritioning is possible. IEnumerator iterInput = setInputSymbol.GetEnumerator(); iterInput.Reset(); while (iterInput.MoveNext()) { string sInputSymbol = iterInput.Current.ToString(); int nPartionIndex = 0; while (nPartionIndex < arrGroup.Count) { Set setToBePartitioned = (Set)arrGroup[nPartionIndex]; nPartionIndex++; if (setToBePartitioned.IsEmpty() || setToBePartitioned.GetCardinality() == 1) { continue; // because we can't partition a set with zero or one memeber in it } foreach (object objState in setToBePartitioned) { State state = (State)objState; State[] arrState = state.GetTransitions(sInputSymbol.ToString()); if (arrState != null) { Debug.Assert(arrState.Length == 1); State stateTransionTo = arrState[0]; // since the state is DFA state, this array should contain only ONE state Set setFound = FindGroup(arrGroup, stateTransionTo); map.Add(setFound, state); } else // no transition exists, so transition to empty set { //setEmpty = new Set(); map.Add(setEmpty, state); // keep a map of which states transtion into which group } } // end of foreach (object objState in setToBePartitioned) if (map.Count > 1) // means some states transition into different groups { arrGroup.Remove(setToBePartitioned); foreach (DictionaryEntry de in map) { Set setValue = (Set)de.Value; arrGroup.Add(setValue); } nPartionIndex = 0; // we want to start from the begining again iterInput.Reset(); // we want to start from the begining again } map.Clear(); } // end of while..loop } // end of foreach (object objString in setInputSymbol) return(arrGroup); } // end of PartitionDfaSet method