public static Sfsa Concat(this Sfsa first, Sfsa second) { var firstFinalStates = first.Final; second = Remap(second, first.States); var secondInitialStates = second.Initial; var initialStates = first.Initial.Intersect(first.Final).Any() ? first.Initial.Union(second.Initial) : first.Initial; var transitions = first.Transitions.Union(second.Transitions).ToList(); foreach (var tr in first.Transitions.Where(t => first.Final.Contains(t.To))) { foreach (var state in second.Initial) { transitions.Add((tr.From, tr.Label, state)); } } return(new Sfsa( states: first.States.Union(second.States), initialStates, second.Final, transitions)); }
// Kleene star operation on a finite automaton public static Sfsa Star(this Sfsa automaton) { var initial = NewState(automaton.States); var initialStates = new int[] { initial }; var newTransitions = new List <(int, Range, int)>(); foreach (var state in automaton.Initial) { newTransitions.Add((initial, default, state));
public static Sfsa Union(this Sfsa first, Sfsa second) { second = Remap(second, first.States); return(new Sfsa( states: first.States.Union(second.States), initial: first.Initial.Union(second.Initial), final: first.Final.Union(second.Final), transitions: first.Transitions.Union(second.Transitions))); }
// Clones the finite automaton by renaming the states static Sfsa Remap(this Sfsa automaton, IReadOnlyCollection <int> states) { var k = states.Count; return(new Sfsa( automaton.States.Select(s => s + k), automaton.Initial.Select(s => s + k), automaton.Final.Select(s => s + k), automaton.Transitions.Select(t => (t.From + k, t.Label, t.To + k)))); }
public static Sfsa Concat(this Sfsa fsa, params Sfsa[] automata) => automata.Aggregate(fsa, Concat);