/// <summary> /// Register the list of given <paramref name="states"/> including any edges. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="states">A <see cref="T:IEnumerable`1"/> of <see cref="T:IState`2"/> instances that must be added.</param> /// <remarks> /// <para>If the given <paramref name="nfa"/> or <paramref name="states"/> are not effective, nothing happens.</para> /// </remarks> public static void RegisterStates <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, IEnumerable <IState <TStateTag, TEdgeTag> > states) { if (nfa != null && states != null) { foreach (IState <TStateTag, TEdgeTag> state in states) { nfa.RegisterState(state); } } }
/// <summary> /// Register the list of edges with a list of tuples containing the tags of the initial and final state /// as well as the tag for the edge to create. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="edges">A <see cref="T:IEnumerable`1"/> of <see cref="T:Tuple`3"/> instance containing /// the tag of the initial state, the tag of the edge to create and the tag of the final state.</param> /// <remarks> /// <para>If there is no state associated with the <paramref name="fromStateTag"/> or <paramref name="toStateTag"/>, /// states are registered (using the <see cref="M:RegisterState"/> method) for these tags.</para> /// <para>If there already exists an edge between the two given states with the given tag, no additional /// edge is registered.</para> /// <para>If the given list of <paramref name="edges"/> or the <paramref name="nfa"/> is not effective, nothing happens.</para> /// <para>This operation is not completely specific to the given automaton: if the state is shared with another /// automaton, the edge will be added to all the automata.</para> /// </remarks> public static void RegisterEdges <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, IEnumerable <Tuple <TStateTag, TEdgeTag, TStateTag> > edges) { if (edges != null && nfa != null) { foreach (Tuple <TStateTag, TEdgeTag, TStateTag> edge in edges) { nfa.RegisterEdge(edge.Item1, edge.Item2, edge.Item3); } } }
/// <summary> /// Register the list of given <paramref name="statesTags"/> including any edges as accepting states. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="stateTags">A <see cref="T:IEnumerable`1"/> of tags that represent states that must be registered /// as accepting states.</param> /// <remarks> /// <para>If the given <paramref name="nfa"/> or <paramref name="states"/> are not effective, nothing happens.</para> /// <para>Only if there is at least one state in the <paramref name="nfa"/> with the given tag, that state is registered, otherwise /// the tag is ignored.</para> /// </remarks> public static void RegisterAcceptingStates <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, IEnumerable <TStateTag> stateTags) { if (nfa != null && stateTags != null) { foreach (TStateTag stateTag in stateTags) { nfa.RegisterAcceptingState(stateTag); } } }
/// <summary> /// Disjunct this nondeterministic finite automaton with the given one into a new one such that /// the resulting one accepts a sequence of data if and only if this sequence can be accepted by this automaton /// or by the <paramref name="other"/> automaton. /// </summary> /// <param name="other">The second <see cref="T:INondeterministicFiniteAutomaton`2"/> in the disjunction process.</param> /// <param name="nullTag">An edge tag used for transitions without the need to consume (or "eat") any characters.</param> /// <param name="startTag">The tag of an (optional) <see cref="T:IState`2"/> that must be constructed to disjunct this and the given automaton.</param> /// <remarks> /// <para>For some implementations, the <paramref name="nullTag"/> might be optional, in that case, any value can be passed.</para> /// <para>If the second automaton is not effective, this automaton will be cloned (not deeply, with the same <see cref="T:IState`2"/> instances).</para> /// <para>Although the return parameter only specifies <see cref="T:INondeterministicFiniteAutomaton`2"/>, the return type is always the same as this type.</para> /// </remarks> public INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> Disjunction(INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> other, TEdgeTag nullTag, TStateTag startTag) { NondeterministicFiniteAutomaton <TStateTag, TEdgeTag, TCollection> clone = this.Clone(); if (other != null) { IState <TStateTag, TEdgeTag> initState = new State <TStateTag, TEdgeTag> (startTag); initState.AddEdge(new Edge <TStateTag, TEdgeTag> (nullTag, this.initialState)); initState.AddEdge(new Edge <TStateTag, TEdgeTag> (nullTag, other.InitalState)); clone.stateDictionary.Add(initState); clone.initialState = initState; clone.stateDictionary.AddAll(other.States); clone.acceptingStateDictionary.AddAll(other.AcceptingStates); } return(clone); }
/// <summary> /// Concatenate this nondeterministic finite automaton with the given one into a new one such that /// the resulting one accepts a sequence of data if and only if it can be subdivded into two parts such /// that the first part is accepted by this automaton and the second by the <paramref name="other"/> automaton. /// </summary> /// <param name="other">The second <see cref="T:INondeterministicFiniteAutomaton`2"/> in the concatenation process.</param> /// <param name="nullTag">An edge tag used for transitions without the need to consume (or "eat") any characters.</param> /// <remarks> /// <para>For some implementations, the <paramref name="nullTag"/> might be optional, in that case, any value can be passed.</para> /// <para>If the second automaton is not effective, this automaton will be cloned (not deeply, with the same <see cref="T:IState`2"/> instances).</para> /// <para>Although the return parameter only specifies <see cref="T:INondeterministicFiniteAutomaton`2"/>, the return type is always the same as this type.</para> /// </remarks> public INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> Concatenate(INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> other, TEdgeTag nullTag) { NondeterministicFiniteAutomaton <TStateTag, TEdgeTag, TCollection> clone = this.Clone(); if (other != null) { IState <TStateTag, TEdgeTag> tostate = other.InitalState; IEdge <TStateTag, TEdgeTag> edge = new Edge <TStateTag, TEdgeTag> (nullTag, tostate); IEnumerable <IState <TStateTag, TEdgeTag> > acceptings = this.acceptingStateDictionary; foreach (IState <TStateTag, TEdgeTag> state in acceptings) { state.AddEdge(edge); } clone.stateDictionary.AddAll(other.States); clone.acceptingStateDictionary.Clear(); clone.acceptingStateDictionary.AddAll(other.AcceptingStates); } return(clone); }
/// <summary> /// Register the array of edges with a list of tuples containing the tags of the initial and final state /// as well as the tag for the edge to create. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="edges">An array of <see cref="T:Tuple`3"/> instance containing /// the tag of the initial state, the tag of the edge to create and the tag of the final state.</param> /// <remarks> /// <para>If there is no state associated with the <paramref name="fromStateTag"/> or <paramref name="toStateTag"/>, /// states are registered (using the <see cref="M:RegisterState"/> method) for these tags.</para> /// <para>If there already exists an edge between the two given states with the given tag, no additional /// edge is registered.</para> /// <para>If the given list of <paramref name="edges"/> or the <paramref name="nfa"/> is not effective, nothing happens.</para> /// <para>This operation is not completely specific to the given automaton: if the state is shared with another /// automaton, the edge will be added to all the automata.</para> /// </remarks> public static void RegisterEdges <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, params Tuple <TStateTag, TEdgeTag, TStateTag>[] edges) { RegisterEdges <TStateTag, TEdgeTag> (nfa, (IEnumerable <Tuple <TStateTag, TEdgeTag, TStateTag> >)edges); }
/// <summary> /// Register the array of given <paramref name="statesTags"/> including any edges as accepting states. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="stateTags">An array of tags corresponding to <see cref="T:IState`2"/> instances that must be registered as as accepting states.</param> /// <remarks> /// <para>If the given <paramref name="nfa"/> or <paramref name="states"/> are not effective, nothing happens.</para> /// <para>Only <see cref="T:IState`2"/> instances that were registered as states first, are registered as accepting states.</para> /// <para>Only if there is at least one state in the <paramref name="nfa"/> with the given tag, that state is registered, otherwise /// the tag is ignored.</para> /// </remarks> public static void RegisterAcceptingStates <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, params TStateTag[] stateTags) { RegisterAcceptingStates <TStateTag, TEdgeTag> (nfa, (IEnumerable <TStateTag>)stateTags); }
/// <summary> /// Register the array of given <paramref name="states"/> including any edges. /// </summary> /// <param name="nfa">The finite state automaton to which the edges must be added.</param> /// <param name="states">An array of <see cref="T:IState`2"/> instances that must be added.</param> /// <remarks> /// <para>If the given <paramref name="nfa"/> or <paramref name="states"/> are not effective, nothing happens.</para> /// </remarks> public static void RegisterStates <TStateTag, TEdgeTag> (this INondeterministicFiniteAutomaton <TStateTag, TEdgeTag> nfa, params IState <TStateTag, TEdgeTag>[] states) { RegisterStates <TStateTag, TEdgeTag> (nfa, (IEnumerable <IState <TStateTag, TEdgeTag> >)states); }