private void Check() { var nStates = states.Count; var starts = new List <DfaState <int> >(); //find roots that cover all the states { var reached = new bool[states.Count]; for (var i = 0; i < nStates; i++) { var src = states[i]; foreach (var dest in src.SuccessorStates) { if (cycleNumbers[src.StateNumber] != cycleNumbers[dest.StateNumber]) { Debug.Assert(dest.StateNumber < src.StateNumber); reached[dest.StateNumber] = true; } } } for (var i = nStates - 2; i >= 0; --i) { if (cycleNumbers[i] >= 0 && cycleNumbers[i] == cycleNumbers[i + 1] && reached[i + 1]) { reached[i] = true; } } for (var i = 0; i < nStates; i++) { if (i == 0 || cycleNumbers[i] < 0 || cycleNumbers[i] != cycleNumbers[i - 1]) { if (!reached[i]) { starts.Add(states[i]); } } } } var auzInfo = new DfaAuxiliaryInformation <int>(starts); var gotCycles = auzInfo.GetCycleNumbers(); Assert.Equal(nStates, gotCycles.Length); for (var i = 0; i < nStates; i++) { if (cycleNumbers[i] < 0) { Assert.True(gotCycles[i] < 0); } else { Assert.True(gotCycles[i] >= 0); if (i > 0) { Assert.Equal(cycleNumbers[i] == cycleNumbers[i - 1], gotCycles[i] == gotCycles[i - 1]); } } } }
public void Test() { var builder = new DfaBuilder <JavaToken?>(null); foreach (JavaToken tok in Enum.GetValues(typeof(JavaToken))) { builder.AddPattern(tok.Pattern(), tok); } var start = builder.Build(new HashSet <JavaToken?>(Enum.GetValues(typeof(JavaToken)).Cast <JavaToken?>()), null); var auxInfo = new DfaAuxiliaryInformation <JavaToken?>(new[] { start }); //calculate destinies the slow way var states = auxInfo.GetStatesByNumber(); var slowDestinies = new List <ISet <JavaToken?> >(states.Count); var numStates = states.Count; for (var i = 0; i < numStates; i++) { slowDestinies.Add(new HashSet <JavaToken?>()); var state = states[i]; if (state.IsAccepting) { slowDestinies[i].Add(state.Match); } } //AtomicBoolean again = new AtomicBoolean(true); var again = true; while (again) { again = false; for (var i = 0; i < numStates; ++i) { var set = slowDestinies[i]; var state = states[i]; state.EnumerateTransitions((f, l, target) => { var targetSet = slowDestinies[target.StateNumber]; var a = true; foreach (var token in targetSet) { if (!set.Add(token)) { a = false; } } if (a) { again = true; } }); } } /* * PrettyPrinter p = new PrettyPrinter(true); * PrintWriter pw = new PrintWriter(System.out); * p.print(pw, start); * pw.flush(); */ var destinies = auxInfo.GetDestinies(); for (var i = 0; i < numStates; ++i) { var set = slowDestinies[i]; JavaToken?wantDestiny = null; if (set.Count == 1) { wantDestiny = set.FirstOrDefault(); } Assert.Equal(/*"State " + i + " destiny",*/ wantDestiny, destinies[i]); } }