public static Automaton Repeat(Automaton a, int min, int max) { if (min > max) { return(BasicAutomata.MakeEmpty()); } max -= min; a.ExpandSingleton(); Automaton b; if (min == 0) { b = BasicAutomata.MakeEmptyString(); } else if (min == 1) { b = a.Clone(); } else { var @as = new List <Automaton>(); while (min-- > 0) { @as.Add(a); } b = Concatenate(@as); } if (max > 0) { var d = a.Clone(); while (--max > 0) { var c = a.Clone(); foreach (var p in c.GetAcceptStates()) { p.AddEpsilon(d.Initial); } d = c; } foreach (var p in b.GetAcceptStates()) { p.AddEpsilon(d.Initial); } b.IsDeterministic = false; b.ClearHashCode(); b.CheckMinimizeAlways(); } return(b); }
public static void AddEpsilons(Automaton a, ICollection <StatePair> pairs) { a.ExpandSingleton(); var forward = new Dictionary <State, HashSet <State> >(); var back = new Dictionary <State, HashSet <State> >(); foreach (var p in pairs) { var to = forward[p.FirstState]; if (to == null) { to = new HashSet <State>(); forward.Add(p.FirstState, to); } _ = to.Add(p.SecondState); var from = back[p.SecondState]; if (from == null) { from = new HashSet <State>(); back.Add(p.SecondState, from); } _ = from.Add(p.FirstState); } var worklist = new LinkedList <StatePair>(pairs); var workset = new HashSet <StatePair>(pairs); while (worklist.Count != 0) { var p = worklist.RemoveAndReturnFirst(); _ = workset.Remove(p); var to = forward[p.SecondState]; var from = back[p.FirstState]; if (to != null) { foreach (var s in to) { var pp = new StatePair(p.FirstState, s); if (!pairs.Contains(pp)) { pairs.Add(pp); _ = forward[p.FirstState].Add(s); _ = back[s].Add(p.FirstState); _ = worklist.AddLast(pp); _ = workset.Add(pp); if (from != null) { foreach (var q in from) { var qq = new StatePair(q, p.FirstState); if (!workset.Contains(qq)) { _ = worklist.AddLast(qq); _ = workset.Add(qq); } } } } } } } foreach (var p in pairs) { p.FirstState.AddEpsilon(p.SecondState); } a.IsDeterministic = false; a.ClearHashCode(); a.CheckMinimizeAlways(); }