} // end function TableFillingAlg /// <summary> /// Table Filling Algorithm EQ Classes /// </summary> /// <returns>Returns all TF EQ Classes</returns> public static uint[][] TableFillingAlgEqClasses(Finite.DFA D) { var tf = TableFillingAlg(D); var eqClasses = new List<uint[]>((int)D.StatesCount); int?[] State2eqClass = new int?[D.StatesCount]; // iterate table and process false(/double) values for (uint x = 0; x < tf.GetLength(0); x++) { for (uint y = x + 1; y < tf.GetLength(1); y++) { if (!tf[x, y]) { if (State2eqClass[x].HasValue) { eqClasses[State2eqClass[x].Value] = eqClasses[State2eqClass[x].Value].Append(y).ToArray(); State2eqClass[y] = State2eqClass[x]; } else { eqClasses.Add(new uint[] { x, y }); State2eqClass[x] = eqClasses.Count - 1; State2eqClass[y] = eqClasses.Count - 1; } } // end if } // next y } // next x // add all none processed states for (uint i = 0; i < D.StatesCount; i++) if (!State2eqClass[i].HasValue) eqClasses.Add(new uint[] { i }); eqClasses.Sort((first, second) => first[0].CompareTo(second[0])); return eqClasses.ToArray(); } // end function TableFillingAlgEqClasses
public static bool[,] TableFillingAlg(Finite.DFA D) { bool[,] t = new bool[D.StatesCount, D.StatesCount]; // first, mark all states which differ between accepted and not for (uint x = 0; x < t.GetLength(0); x++) for (uint y = 0; y < t.GetLength(0); y++) if (D.IsAcceptedState(x) != D.IsAcceptedState(y)) t[x, y] = true; bool found; // loop while found something new do { found = false; // iterate full table, for each char for (uint x = 0; x < t.GetLength(0); x++) { for (uint y = x + 1; y < t.GetLength(1); y++) { if (!t[x, y]) { // don't work already processed (PERF) foreach (char c in D.Alphabet) { uint xNext = D.GoChar(x, c)[0]; uint yNext = D.GoChar(y, c)[0]; // calculate based on previous iterations // if next states for both x,y has been set to different // set current pair to be different, and enable loop if (t[xNext, yNext]) t[x, y] = t[y, x] = found = true; } // next c } // end if } // next y } // next x } while (found); return t; } // end function TableFillingAlg