diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h index 86126da059044d9cb0fcefa0832fed5fd5f9703f..abc65084488973f85d34aa606c96f90988989810 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.h +++ b/alib2data/src/automaton/FSM/CompactNFA.h @@ -1,6 +1,22 @@ /* * CompactNFA.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Mar 25, 2013 * Author: Jan Travnicek */ @@ -30,162 +46,395 @@ namespace automaton { -/** - * Represents Finite Automaton. - * Can store nondeterministic finite automaton without epsilon transitions. - */ class InputAlphabet; class States; class FinalStates; class InitialState; +/** + * \brief + * Compact nondeterministic finite automaton. Accepts regular languages. The automaton has a list of symbols on transitions. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, I, \delta), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form A \times a -> P(Q), where A \in Q, a \in T*, and P(Q) is a powerset of states, + * I (InitialState) = initial state, + * + * \tparam SymbolType used for the terminal alphabet + * \tparam StateType used to the states, and the initial state of the automaton. + */ template < class SymbolType, class StateType > class CompactNFA final : public AutomatonBase, public alib::Components < CompactNFA < SymbolType, StateType >, SymbolType, ext::tuple < InputAlphabet >, ext::tuple < >, StateType, ext::tuple < States, FinalStates >, ext::tuple < InitialState > > { -protected: + /** + * Transition function as mapping from a state times a list of input symbols on the left hand side to a set of states. + */ ext::map < ext::pair < StateType, ext::vector < SymbolType > >, ext::set < StateType > > transitions; public: + /** + * \brief Creates a new instance of the automaton with a concrete initial state. + * + * \param initialState the initial state of the automaton + */ explicit CompactNFA ( StateType initialState ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial state, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param initialState the initial state of the automaton + * \param finalStates the initial set of final states of the automaton + */ explicit CompactNFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of the automaton based on the Epsilon Nondeterministic finite automaton. + * + * \param other the Epsilon nondeterministic finite automaton + * + * \tparam EpsilonType used in the Epsilon nondeterministic finite automaton + */ template < class EpsilonType > explicit CompactNFA ( const EpsilonNFA < SymbolType, EpsilonType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton with multiple initial states. + * + * \param other the Nondeterministic finite automaton with multiple initial states + */ explicit CompactNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton. + * + * \param other the Nondeterministic finite automaton + */ explicit CompactNFA ( const NFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Deterministic finite automaton. + * + * \param other the Deterministic finite automaton + */ explicit CompactNFA ( const DFA < SymbolType, StateType > & other ); - virtual AutomatonBase * clone ( ) const; + /** + * @copydoc automaton::AutomatonBase::clone() + */ + virtual AutomatonBase * clone ( ) const override; - virtual AutomatonBase * plunder ( ) &&; + /** + * @copydoc automaton::AutomatonBase::plunder() + */ + virtual AutomatonBase * plunder ( ) && override; + /** + * Getter of the initial state. + * + * \returns the initial state of the automaton + */ const StateType & getInitialState ( ) const { return this->template accessElement < InitialState > ( ).get ( ); } + /** + * Setter of the initial state. + * + * \param state new initial state of the automaton + * + * \returns true if the initial state was indeed changed + */ bool setInitialState ( StateType state ) { return this->template accessElement < InitialState > ( ).set ( std::move ( state ) ); } + /** + * Getter of states. + * + * \returns the states of the automaton + */ const ext::set < StateType > & getStates ( ) const { return this->template accessComponent < States > ( ).get ( ); } + /** + * Adder of a state. + * + * \param state the new state to be added to a set of states + * + * \returns true if the state was indeed added + */ bool addState ( StateType state ) { return this->template accessComponent < States > ( ).add ( std::move ( state ) ); } + /** + * Setter of states. + * + * \param states completely new set of states + */ void setStates ( ext::set < StateType > states ) { this->template accessComponent < States > ( ).set ( std::move ( states ) ); } + /** + * Remover of a state. + * + * \param state a state to be removed from a set of states + * + * \returns true if the state was indeed removed + */ void removeState ( const StateType & state ) { this->template accessComponent < States > ( ).remove ( state ); } + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ const ext::set < StateType > & getFinalStates ( ) const { return this->template accessComponent < FinalStates > ( ).get ( ); } + /** + * Adder of a final state. + * + * \param state the new state to be added to a set of final states + * + * \returns true if the state was indeed added + */ bool addFinalState ( StateType state ) { return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); } + /** + * Setter of final states. + * + * \param states completely new set of final states + */ void setFinalStates ( ext::set < StateType > states ) { this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); } + /** + * Remover of a final state. + * + * \param state a state to be removed from a set of final states + * + * \returns true if the state was indeed removed + */ void removeFinalState ( const StateType & state ) { this->template accessComponent < FinalStates > ( ).remove ( state ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ const ext::set < SymbolType > & getInputAlphabet ( ) const { return this->template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Adder of a input symbol. + * + * \param symbol the new symbol to be added to an input alphabet + * + * \returns true if the symbol was indeed added + */ bool addInputSymbol ( SymbolType symbol ) { return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Adder of input symbols. + * + * \param symbols new symbols to be added to an input alphabet + */ void addInputSymbols ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ void setInputAlphabet ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Remover of an input symbol. + * + * \param symbol a symbol to be removed from an input alphabet + * + * \returns true if the symbol was indeed removed + */ void removeInputSymbol ( const SymbolType & symbol ) { this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T* + * + * \param current the source state (A) + * \param input the list of input symbols (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType current, ext::vector < SymbolType > input, StateType next ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times a -> P(Q), where A \in Q, a \in T*, P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param input the list of input symbols (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType current, ext::vector < SymbolType > input, ext::set < StateType > next ); /** - * Removes transition from the automaton. - * @param transition transition to remove - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T* + * + * \param current the source state (A) + * \param input the list of input symbols (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & current, const ext::vector < SymbolType > & input, const StateType & next ); /** - * @return automaton transitions + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton */ const ext::map < ext::pair < StateType, ext::vector < SymbolType > >, ext::set < StateType > > & getTransitions ( ) const; /** - * @return automaton transitions from state + * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the source state fixed */ ext::map < ext::pair < StateType, ext::vector < SymbolType > >, ext::set < StateType > > getTransitionsFromState ( const StateType & from ) const; /** - * @return automaton transitions to state + * Get a subset of the transition function of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the target state fixed */ ext::map < ext::pair < StateType, ext::vector < SymbolType > >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( ext::type_index ( typeid ( * this ) ) == ext::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return ext::type_index ( typeid ( * this ) ) - ext::type_index ( typeid ( other ) ); } - virtual int compare ( const CompactNFA & other ) const; + /** + * The actual compare method + * + * \param other the other instance + * + * \returns the actual relation between two by type same automata instances + */ + int compare ( const CompactNFA & other ) const; - virtual void operator >>( std::ostream & os ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; - virtual explicit operator std::string ( ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "CompactNFA"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the automaton + */ static CompactNFA parse ( ext::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual transitions of the automaton from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params automaton the automaton to add the rule to + */ static void parseTransition ( ext::deque < sax::Token >::iterator & input, CompactNFA & automaton ); - void compose ( ext::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out the sink for new xml tokens representing the automaton + */ + virtual void compose ( ext::deque < sax::Token > & out ) const override; + + /** + * Helper for composing transitions of the automaton to a sequence of xml tokens. + * + * \param out the sink for xml tokens representing the rules of the automaton + */ void composeTransitions ( ext::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef CompactNFA < > normalized_type; - virtual AutomatonBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states. + * + * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones + */ + virtual AutomatonBase * normalize ( ) && override { if ( typeid ( CompactNFA < > ) == typeid ( CompactNFA < SymbolType, StateType > ) ) return this; @@ -454,9 +703,23 @@ alib::ObjectBase* CompactNFA < SymbolType, StateType >::inc() && { namespace alib { +/** + * Helper class specifying constraints for the automaton's internal input alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::CompactNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > { public: + /** + * Returns true if the symbol is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const automaton::CompactNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) { for ( const std::pair < const ext::pair < StateType, ext::vector < SymbolType > >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) { ext::set < SymbolType > alphabet ( transition.first.second.begin ( ), transition.first.second.end ( ) ); @@ -467,17 +730,45 @@ public: return false; } + /** + * Returns true as all symbols are possibly available to be elements of the input alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::CompactNFA < SymbolType, StateType > &, const SymbolType & ) { return true; } + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::CompactNFA < SymbolType, StateType > &, const SymbolType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::CompactNFA < SymbolType, StateType >, StateType, automaton::States > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::CompactNFA < SymbolType, StateType > & automaton, const StateType & state ) { if ( automaton.getInitialState ( ) == state ) return true; @@ -492,36 +783,98 @@ public: return false; } + /** + * Returns true as all states are possibly available to be elements of the states. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::CompactNFA < SymbolType, StateType > &, const StateType & ) { return true; } + /** + * All states are valid as a state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::CompactNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal final states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::CompactNFA < SymbolType, StateType >, StateType, automaton::FinalStates > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::CompactNFA < SymbolType, StateType > &, const StateType & ) { return false; } + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::CompactNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as a final state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::CompactNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal initial state element. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ElementConstraint< automaton::CompactNFA < SymbolType, StateType >, StateType, automaton::InitialState > { public: + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::CompactNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as an initial state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::CompactNFA < SymbolType, StateType > &, const StateType & ) { } }; diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h index c37ee7a905064f4c173d47b3b0b2315d7c9923bd..b0126a15ab3dcfa1ce1d5c0b580489832c6ee064 100644 --- a/alib2data/src/automaton/FSM/DFA.h +++ b/alib2data/src/automaton/FSM/DFA.h @@ -75,14 +75,14 @@ class DFA final : public AutomatonBase, public alib::Components < DFA < SymbolTy public: /** - * \brief Creates a new instance of Deterministic finite automaton with a concrete initial state. + * \brief Creates a new instance of the automaton with a concrete initial state. * * \param initialState the initial state of the automaton */ explicit DFA ( StateType initialState ); /** - * \brief Creates a new instance of Deterministic finite automaton with a concrete set of states, input alphabet, initial state, and a set of final states. + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial state, and a set of final states. * * \param states the initial set of states of the automaton * \param inputAlphabet the initial input alphabet @@ -304,9 +304,9 @@ public: ext::map < ext::pair < StateType, SymbolType >, StateType > getTransitionsToState ( const StateType & to ) const; /** - * \brief Determines whether Deterministic finite automaton is total + * \brief Determines whether the automaton is total * - * Deterministic finite automaton is total if and only if: + * The automaton is total if and only if: * \li \c size of transition function \forall states \times input symbols = 1 * * \return true if the automaton is total, false otherwise diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h index 9eb1cac09b45cb38f246a2276c1e795e67814419..db7cf3b9a4a7b69c3d2b6752fa3e14ff6403c93a 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.h +++ b/alib2data/src/automaton/FSM/EpsilonNFA.h @@ -1,6 +1,22 @@ /* * EpsilonNFA.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Mar 25, 2013 * Author: Jan Travnicek */ @@ -30,255 +46,531 @@ namespace automaton { -/** - * Represents Finite Automaton. - * Can store nondeterministic finite automaton with epsilon transitions. - */ class InputAlphabet; class States; class FinalStates; class InitialState; +/** + * \brief + * Epsilon nondeterministic finite automaton. Accepts regular languages. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, I, \delta), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form A \times a -> P(Q), where A \in Q, a \in T \cup \{\epsilon\}, and P(Q) is a powerset of states, + * I (InitialState) = initial state, + * + * \tparam SymbolType used for the terminal alphabet + * \tparam EpsilonType used for the epislon in the automaton. + * \tparam StateType used to the states, and the initial state of the automaton. + */ template<class SymbolType, class EpsilonType, class StateType > class EpsilonNFA final : public AutomatonBase, public alib::Components < EpsilonNFA < SymbolType, EpsilonType, StateType >, SymbolType, ext::tuple < InputAlphabet >, ext::tuple < >, StateType, ext::tuple < States, FinalStates >, ext::tuple < InitialState > > { -protected: + /** + * Transition function as mapping from a state times an input symbol or epsilon on the left hand side to a set of states. + */ ext::map < ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, ext::set < StateType > > transitions; public: + /** + * \brief Creates a new instance of the automaton with a concrete initial state. + * + * \param initialState the initial state of the automaton + */ explicit EpsilonNFA ( StateType initialState ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial state, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param initialState the initial state of the automaton + * \param finalStates the initial set of final states of the automaton + */ explicit EpsilonNFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of Nondeterministic finite automaton based on the Deterministic finite automaton. + * + * \param other the Nondeterministic finite automaton with multiple initial states + */ explicit EpsilonNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of Nondeterministic finite automaton based on the Deterministic finite automaton. + * + * \param other the Nondeterministic finite automaton + */ explicit EpsilonNFA ( const NFA < SymbolType, StateType > & other ); + + /* + * \brief creates a new instance of the automaton based on the deterministic finite automaton. + * + * \param other the deterministic finite automaton + */ explicit EpsilonNFA ( const DFA < SymbolType, StateType > & other ); - virtual AutomatonBase * clone ( ) const; + /** + * @copydoc automaton::AutomatonBase::clone() + */ + virtual AutomatonBase * clone ( ) const override; - virtual AutomatonBase * plunder ( ) &&; + /** + * @copydoc automaton::AutomatonBase::plunder() + */ + virtual AutomatonBase * plunder ( ) && override; + /** + * Getter of the initial state. + * + * \returns the initial state of the automaton + */ const StateType & getInitialState ( ) const { return this->template accessElement < InitialState > ( ).get ( ); } + /** + * Setter of the initial state. + * + * \param state new initial state of the automaton + * + * \returns true if the initial state was indeed changed + */ bool setInitialState ( StateType state ) { return this->template accessElement < InitialState > ( ).set ( std::move ( state ) ); } + /** + * Getter of states. + * + * \returns the states of the automaton + */ const ext::set < StateType > & getStates ( ) const { return this->template accessComponent < States > ( ).get ( ); } + /** + * Adder of a state. + * + * \param state the new state to be added to a set of states + * + * \returns true if the state was indeed added + */ bool addState ( StateType state ) { return this->template accessComponent < States > ( ).add ( std::move ( state ) ); } + /** + * Setter of states. + * + * \param states completely new set of states + */ void setStates ( ext::set < StateType > states ) { this->template accessComponent < States > ( ).set ( std::move ( states ) ); } + /** + * Remover of a state. + * + * \param state a state to be removed from a set of states + * + * \returns true if the state was indeed removed + */ void removeState ( const StateType & state ) { this->template accessComponent < States > ( ).remove ( state ); } + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ const ext::set < StateType > & getFinalStates ( ) const { return this->template accessComponent < FinalStates > ( ).get ( ); } + /** + * Adder of a final state. + * + * \param state the new state to be added to a set of final states + * + * \returns true if the state was indeed added + */ bool addFinalState ( StateType state ) { return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); } + /** + * Setter of final states. + * + * \param states completely new set of final states + */ void setFinalStates ( ext::set < StateType > states ) { this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); } + /** + * Remover of a final state. + * + * \param state a state to be removed from a set of final states + * + * \returns true if the state was indeed removed + */ void removeFinalState ( const StateType & state ) { this->template accessComponent < FinalStates > ( ).remove ( state ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ const ext::set < SymbolType > & getInputAlphabet ( ) const { return this->template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Adder of a input symbol. + * + * \param symbol the new symbol to be added to an input alphabet + * + * \returns true if the symbol was indeed added + */ bool addInputSymbol ( SymbolType symbol ) { return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Adder of input symbols. + * + * \param symbols new symbols to be added to an input alphabet + */ void addInputSymbols ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ void setInputAlphabet ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Remover of an input symbol. + * + * \param symbol a symbol to be removed from an input alphabet + * + * \returns true if the symbol was indeed removed + */ void removeInputSymbol ( const SymbolType & symbol ) { this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T \cup \{\epsilon\} + * + * \param current the source state (A) + * \param input the input symbol or epsilon (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType from, ext::variant < EpsilonType, SymbolType > input, StateType to ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType from, SymbolType input, StateType to ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times \epsilon -> B, where A, B \in Q + * + * \param current the source state (A) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType from, StateType to ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times a -> P(Q), where A \in Q, a \in T \cup \{\epsilon\}, P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param input the input symbol or epsilon (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType from, ext::variant < EpsilonType, SymbolType > input, ext::set < StateType > to ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times a -> P(Q), where A \in Q, a \in T, P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType from, SymbolType input, ext::set < StateType > to ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times \epsilon -> P(Q), where A \in Q, P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType from, ext::set < StateType > to ); /** - * Removes transition from the automaton. - * @param transition transition to remove - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & current, const SymbolType & input, const StateType & next ); /** - * Removes transition from the automaton. - * @param transition transition to remove - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A times \epsilon -> B, where A, B \in Q + * + * \param current the source state (A) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & current, const StateType & next ); /** - * @return automaton transitions + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton */ const ext::map < ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, ext::set < StateType > > & getTransitions ( ) const; /** - * @return automaton epsilon transitions + * Get the epsilon transitions of the automaton + * + * \returns epsilon transitions of the automaton */ ext::map < StateType, ext::set < StateType > > getEpsilonTransitions ( ) const; /** - * @return automaton transitions reading some symbol + * Get the non-epsilon transitions of the automaton + * + * \returns non-epsilon transitions of the automaton */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getSymbolTransitions ( ) const; /** - * @return automaton transitions from state + * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the source state fixed */ ext::map < ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, ext::set < StateType > > getTransitionsFromState ( const StateType & from ) const; /** - * @return automaton epsilon transitions from state + * Get a subset of epsilon transitions of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of epsilon transitions of the automaton with the source state fixed */ ext::map < StateType, ext::set < StateType > > getEpsilonTransitionsFromState ( const StateType & from ) const; /** - * @return automaton transitions from state reading some symbols + * Get a subset of non-epsilon transitions of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of non-epsilon transitions of the automaton with the source state fixed */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getSymbolTransitionsFromState ( const StateType & from ) const; /** - * @return automaton transitions to state + * Get a subset of the transition function of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the target state fixed */ ext::map < ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; /** - * @return automaton epsilon transitions to state + * Get a subset of epsilon transitions of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of epsilon transitions of the automaton with the target state fixed */ ext::map < StateType, ext::set < StateType > > getEpsilonTransitionsToState ( const StateType & to ) const; /** - * @return automaton transitions to state reading some symbols + * Get a subset of non-epsilon transitions of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of non-epsilon transitions of the automaton with the target state fixed */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getSymbolTransitionsToState ( const StateType & to ) const; /** - * Determines whether NFA is without epsilon transitions. - * @return true when automaton doesn't contain epsilon transitions, false otherwise + * \brief Determines whether the automaton is without epsilon transitions. + * + * \return true when automaton doesn't contain epsilon transitions, false otherwise */ bool isEpsilonFree ( ) const; /** - * Determines whether NFA is deterministic. - * FA is deterministic if and only if: + * \brief Determines whether the automaton is deterministic + * + * The automaton is deterministic if and only if: * \li \c is epsilon free. * \li \c size of transition function \delta (from state, input symbol) \leq 1 - * @return true when automaton is deterministic, false otherwise + * + * \return true if the automaton is deterministic, false otherwise */ bool isDeterministic ( ) const; /** - * Determines whether NFA is total deterministic - * FA is deterministic if and only if + * \brief Determines whether the automaton is total deterministic + * + * The automaton is deterministic if and only if: * \li \c it is deterministic * \li \c size of transition function \forall states and \forall input symbols \delta (from state, input symbol) = 1 - * @return true when automaton is total deterministic, false otherwise + * + * \return true if the automaton is total deterministic, false otherwise */ bool isTotal ( ) const; - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( ext::type_index ( typeid ( * this ) ) == ext::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return ext::type_index ( typeid ( * this ) ) - ext::type_index ( typeid ( other ) ); } + /** + * The actual compare method + * + * \param other the other instance + * + * \returns the actual relation between two by type same automata instances + */ virtual int compare ( const EpsilonNFA & other ) const; - virtual void operator >>( std::ostream & os ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; - virtual explicit operator std::string ( ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "EpsilonNFA"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the automaton + */ static EpsilonNFA parse ( ext::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual transitions of the automaton from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params automaton the automaton to add the rule to + */ static void parseTransition ( ext::deque < sax::Token >::iterator & input, EpsilonNFA & automaton ); - void compose ( ext::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out the sink for new xml tokens representing the automaton + */ + virtual void compose ( ext::deque < sax::Token > & out ) const override; + + /** + * Helper for composing transitions of the automaton to a sequence of xml tokens. + * + * \param out the sink for xml tokens representing the rules of the automaton + */ void composeTransitions ( ext::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef EpsilonNFA < > normalized_type; - virtual AutomatonBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states. + * + * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones + */ + virtual AutomatonBase * normalize ( ) && override { if ( typeid ( EpsilonNFA < > ) == typeid ( EpsilonNFA < SymbolType, EpsilonType, StateType > ) ) return this; @@ -668,9 +960,24 @@ alib::ObjectBase* EpsilonNFA < SymbolType, EpsilonType, StateType >::inc() && { namespace alib { +/** + * Helper class specifying constraints for the automaton's internal input alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam EpsilonType used for the epislon in the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class EpsilonType, class StateType > class ComponentConstraint< automaton::EpsilonNFA < SymbolType, EpsilonType, StateType >, SymbolType, automaton::InputAlphabet > { public: + /** + * Returns true if the symbol is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const SymbolType & symbol ) { for ( const std::pair < const ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) if ( transition.first.second.template is < SymbolType > ( ) && ( transition.first.second.template get < SymbolType > ( ) == symbol ) ) @@ -679,17 +986,46 @@ public: return false; } + /** + * Returns true as all symbols are possibly available to be elements of the input alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const SymbolType & ) { return true; } + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const SymbolType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam EpsilonType used for the epislon in the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class EpsilonType, class StateType > class ComponentConstraint< automaton::EpsilonNFA < SymbolType, EpsilonType, StateType >, StateType, automaton::States > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const StateType & state ) { if ( automaton.getInitialState ( ) == state ) return true; @@ -704,36 +1040,100 @@ public: return false; } + /** + * Returns true as all states are possibly available to be elements of the states. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const StateType & ) { return true; } + /** + * All states are valid as a state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal final states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam EpsilonType used for the epislon in the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class EpsilonType, class StateType > class ComponentConstraint< automaton::EpsilonNFA < SymbolType, EpsilonType, StateType >, StateType, automaton::FinalStates > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const StateType & ) { return false; } + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as a final state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal initial state element. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam EpsilonType used for the epislon in the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class EpsilonType, class StateType > class ElementConstraint< automaton::EpsilonNFA < SymbolType, EpsilonType, StateType >, StateType, automaton::InitialState > { public: + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as an initial state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > &, const StateType & ) { } }; diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h index 4de6209c925ac2540928edde24ca6858f1748454..47c93878aed100f283422f50ebce1b4b0cf48465 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.h +++ b/alib2data/src/automaton/FSM/ExtendedNFA.h @@ -1,6 +1,22 @@ /* * ExtendedNFA.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Mar 25, 2013 * Author: Jan Travnicek */ @@ -33,163 +49,402 @@ namespace automaton { -/** - * Represents Finite Automaton. - * Can store nondeterministic finite automaton without epsilon transitions. - */ class InputAlphabet; class States; class FinalStates; class InitialState; +/** + * \brief + * Extended nondeterministic finite automaton. Accepts regular languages. The automaton has a regular expression on transitions. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, I, \delta), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form A \times a -> P(Q), where A \in Q, a \in RegExpsOver(T), and P(Q) is a powerset of states, + * I (InitialState) = initial state, + * + * \tparam SymbolType used for the terminal alphabet + * \tparam StateType used to the states, and the initial state of the automaton. + */ template<class SymbolType, class StateType > class ExtendedNFA final : public AutomatonBase, public alib::Components < ExtendedNFA < SymbolType, StateType >, SymbolType, ext::tuple < InputAlphabet >, ext::tuple < >, StateType, ext::tuple < States, FinalStates >, ext::tuple < InitialState > > { -protected: + /** + * Transition function as mapping from a state times a regular expression on the left hand side to a set of states. + */ ext::map < ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, ext::set < StateType > > transitions; public: + /** + * \brief Creates a new instance of the automaton with a concrete initial state. + * + * \param initialState the initial state of the automaton + */ explicit ExtendedNFA ( StateType initialState ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial state, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param initialState the initial state of the automaton + * \param finalStates the initial set of final states of the automaton + */ explicit ExtendedNFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of the automaton based on the Compact nondeterministic finite automaton. + * + * \param other the Compact nondeterministic finite automaton + */ explicit ExtendedNFA ( const CompactNFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Epsilon Nondeterministic finite automaton. + * + * \param other the Epsilon nondeterministic finite automaton + * + * \tparam EpsilonType used in the Epsilon nondeterministic finite automaton + */ template < class EpsilonType > explicit ExtendedNFA ( const EpsilonNFA < SymbolType, EpsilonType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton with multiple initial states. + * + * \param other the Nondeterministic finite automaton with multiple initial states + */ explicit ExtendedNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton. + * + * \param other the Nondeterministic finite automaton + */ explicit ExtendedNFA ( const NFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Deterministic finite automaton. + * + * \param other the Deterministic finite automaton + */ explicit ExtendedNFA ( const DFA < SymbolType, StateType > & other ); - virtual AutomatonBase * clone ( ) const; + /** + * @copydoc automaton::AutomatonBase::clone() + */ + virtual AutomatonBase * clone ( ) const override; - virtual AutomatonBase * plunder ( ) &&; + /** + * @copydoc automaton::AutomatonBase::plunder() + */ + virtual AutomatonBase * plunder ( ) && override; + /** + * Getter of the initial state. + * + * \returns the initial state of the automaton + */ const StateType & getInitialState ( ) const { return this->template accessElement < InitialState > ( ).get ( ); } + /** + * Setter of the initial state. + * + * \param state new initial state of the automaton + * + * \returns true if the initial state was indeed changed + */ bool setInitialState ( StateType state ) { return this->template accessElement < InitialState > ( ).set ( std::move ( state ) ); } + /** + * Getter of states. + * + * \returns the states of the automaton + */ const ext::set < StateType > & getStates ( ) const { return this->template accessComponent < States > ( ).get ( ); } + /** + * Adder of a state. + * + * \param state the new state to be added to a set of states + * + * \returns true if the state was indeed added + */ bool addState ( StateType state ) { return this->template accessComponent < States > ( ).add ( std::move ( state ) ); } + /** + * Setter of states. + * + * \param states completely new set of states + */ void setStates ( ext::set < StateType > states ) { this->template accessComponent < States > ( ).set ( std::move ( states ) ); } + /** + * Remover of a state. + * + * \param state a state to be removed from a set of states + * + * \returns true if the state was indeed removed + */ void removeState ( const StateType & state ) { this->template accessComponent < States > ( ).remove ( state ); } + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ const ext::set < StateType > & getFinalStates ( ) const { return this->template accessComponent < FinalStates > ( ).get ( ); } + /** + * Adder of a final state. + * + * \param state the new state to be added to a set of final states + * + * \returns true if the state was indeed added + */ bool addFinalState ( StateType state ) { return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); } + /** + * Setter of final states. + * + * \param states completely new set of final states + */ void setFinalStates ( ext::set < StateType > states ) { this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); } + /** + * Remover of a final state. + * + * \param state a state to be removed from a set of final states + * + * \returns true if the state was indeed removed + */ void removeFinalState ( const StateType & state ) { this->template accessComponent < FinalStates > ( ).remove ( state ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ const ext::set < SymbolType > & getInputAlphabet ( ) const { return this->template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Adder of a input symbol. + * + * \param symbol the new symbol to be added to an input alphabet + * + * \returns true if the symbol was indeed added + */ bool addInputSymbol ( SymbolType symbol ) { return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Adder of input symbols. + * + * \param symbols new symbols to be added to an input alphabet + */ void addInputSymbols ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ void setInputAlphabet ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Remover of an input symbol. + * + * \param symbol a symbol to be removed from an input alphabet + * + * \returns true if the symbol was indeed removed + */ void removeInputSymbol ( const SymbolType & symbol ) { this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in RegExpsOver(T) + * + * \param current the source state (A) + * \param input the regexp (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType current, regexp::UnboundedRegExpStructure < SymbolType > input, StateType next ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times a -> P(Q), where A \in Q, a \in RegExpsOver(T), P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param input the regexp (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType current, regexp::UnboundedRegExpStructure < SymbolType > input, ext::set < StateType > next ); /** - * Removes transition from the automaton. - * @param transition transition to remove - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in RegExpsOver(T) + * + * \param current the source state (A) + * \param input the regexp (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & current, const regexp::UnboundedRegExpStructure < SymbolType > & input, const StateType & next ); /** - * @return automaton transitions + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton */ const ext::map < ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, ext::set < StateType > > & getTransitions ( ) const; /** - * @return automaton transitions from state + * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the source state fixed */ ext::map < ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, ext::set < StateType > > getTransitionsFromState ( const StateType & from ) const; /** - * @return automaton transitions to state + * Get a subset of the transition function of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the target state fixed */ ext::map < ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( ext::type_index ( typeid ( * this ) ) == ext::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return ext::type_index ( typeid ( * this ) ) - ext::type_index ( typeid ( other ) ); } - virtual int compare ( const ExtendedNFA & other ) const; + /** + * The actual compare method + * + * \param other the other instance + * + * \returns the actual relation between two by type same automata instances + */ + int compare ( const ExtendedNFA & other ) const; - virtual void operator >>( std::ostream & os ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; - virtual explicit operator std::string ( ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "ExtendedNFA"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the automaton + */ static ExtendedNFA parse ( ext::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual transitions of the automaton from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params automaton the automaton to add the rule to + */ static void parseTransition ( ext::deque < sax::Token >::iterator & input, ExtendedNFA & automaton ); - void compose ( ext::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out the sink for new xml tokens representing the automaton + */ + virtual void compose ( ext::deque < sax::Token > & out ) const override; + + /** + * Helper for composing transitions of the automaton to a sequence of xml tokens. + * + * \param out the sink for xml tokens representing the rules of the automaton + */ void composeTransitions ( ext::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef ExtendedNFA < > normalized_type; - virtual AutomatonBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states. + * + * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones + */ + virtual AutomatonBase * normalize ( ) && override { if ( typeid ( ExtendedNFA < > ) == typeid ( ExtendedNFA < SymbolType, StateType > ) ) return this; @@ -472,9 +727,23 @@ alib::ObjectBase* ExtendedNFA < SymbolType, StateType >::inc() && { namespace alib { +/** + * Helper class specifying constraints for the automaton's internal input alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class StateType > class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > { public: + /** + * Returns true if the symbol is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) { for ( const std::pair < const ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) { ext::set < SymbolType > alphabet = transition.first.second.getStructure ( ).computeMinimalAlphabet ( ); @@ -485,17 +754,45 @@ public: return false; } + /** + * Returns true as all symbols are possibly available to be elements of the input alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) { return true; } + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class StateType > class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::States > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { if ( automaton.getInitialState ( ) == state ) return true; @@ -510,36 +807,98 @@ public: return false; } + /** + * Returns true as all states are possibly available to be elements of the states. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { return true; } + /** + * All states are valid as a state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal final states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class StateType > class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::FinalStates > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { return false; } + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as a final state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal initial state element. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template<class SymbolType, class StateType > class ElementConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::InitialState > { public: + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as an initial state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h index e94dcae431c3a5abecd1d36b87acb6fa20c416a5..60e6b718e7219ddac207fbc6e25e6401b113363d 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h @@ -1,6 +1,22 @@ /* * MultiInitialStateNFA.h * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * * Created on: Mar 25, 2013 * Author: Jan Travnicek */ @@ -26,184 +42,427 @@ namespace automaton { -/** - * Represents Finite Automaton. - * Can store nondeterministic finite automaton without epsilon transitions. - */ class InputAlphabet; class States; class FinalStates; class InitialStates; +/** + * \brief + * Nondeterministic finite automaton with multiple initial states. Accepts regular languages. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, I, \delta), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form A \times a -> P(Q), where A \in Q, a \in T, and P(Q) is a powerset of states, + * I (InitialState) = finite set of initial states, + * + * \tparam SymbolType used for the terminal alphabet + * \tparam StateType used to the states, and the initial state of the automaton. + */ template < class SymbolType, class StateType > class MultiInitialStateNFA final : public AutomatonBase, public alib::Components < MultiInitialStateNFA < SymbolType, StateType >, SymbolType, ext::tuple < InputAlphabet >, ext::tuple < >, StateType, ext::tuple < States, InitialStates, FinalStates >, ext::tuple < > > { -protected: + /** + * Transition function as mapping from a state times an input symbol on the left hand side to a set of states. + */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > transitions; public: + /** + * \brief Creates a new instance of the automaton + * + * \param initialState the initial state of the automaton + */ explicit MultiInitialStateNFA ( ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial states, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param initialStates the initial set of initial states of the automaton + * \param finalStates the initial set of final states of the automaton + */ explicit MultiInitialStateNFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, ext::set < StateType > initialStates, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton. + * + * \param other the Nondeterministic finite automaton + */ explicit MultiInitialStateNFA ( const NFA < SymbolType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Deterministic finite automaton. + * + * \param other the Deterministic finite automaton + */ explicit MultiInitialStateNFA ( const DFA < SymbolType, StateType > & other ); - virtual AutomatonBase * clone ( ) const; + /** + * @copydoc automaton::AutomatonBase::clone() + */ + virtual AutomatonBase * clone ( ) const override; - virtual AutomatonBase * plunder ( ) &&; + /** + * @copydoc automaton::AutomatonBase::plunder() + */ + virtual AutomatonBase * plunder ( ) && override; + /** + * Getter of initial states. + * + * \returns the initial states of the automaton + */ const ext::set < StateType > & getInitialStates ( ) const { return this->template accessComponent < InitialStates > ( ).get ( ); } + /** + * Adder of a initial state. + * + * \param state the new state to be added to a set of initial states + * + * \returns true if the state was indeed added + */ bool addInitialState ( StateType state ) { return this->template accessComponent < InitialStates > ( ).add ( std::move ( state ) ); } + /** + * Setter of initial states. + * + * \param states completely new set of initial states + */ void setInitialStates ( ext::set < StateType > states ) { this->template accessComponent < InitialStates > ( ).set ( std::move ( states ) ); } + /** + * Remover of a initial state. + * + * \param state a state to be removed from a set of initial states + * + * \returns true if the state was indeed removed + */ + void removeInitialState ( const StateType & state ) { + this->template accessComponent < InitialStates > ( ).remove ( state ); + } + + /** + * Getter of states. + * + * \returns the states of the automaton + */ const ext::set < StateType > & getStates ( ) const { return this->template accessComponent < States > ( ).get ( ); } + /** + * Adder of a state. + * + * \param state the new state to be added to a set of states + * + * \returns true if the state was indeed added + */ bool addState ( StateType state ) { return this->template accessComponent < States > ( ).add ( std::move ( state ) ); } + /** + * Setter of states. + * + * \param states completely new set of states + */ void setStates ( ext::set < StateType > states ) { this->template accessComponent < States > ( ).set ( std::move ( states ) ); } + /** + * Remover of a state. + * + * \param state a state to be removed from a set of states + * + * \returns true if the state was indeed removed + */ void removeState ( const StateType & state ) { this->template accessComponent < States > ( ).remove ( state ); } + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ const ext::set < StateType > & getFinalStates ( ) const { return this->template accessComponent < FinalStates > ( ).get ( ); } + /** + * Adder of a final state. + * + * \param state the new state to be added to a set of final states + * + * \returns true if the state was indeed added + */ bool addFinalState ( StateType state ) { return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); } + /** + * Setter of final states. + * + * \param states completely new set of final states + */ void setFinalStates ( ext::set < StateType > states ) { this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); } + /** + * Remover of a final state. + * + * \param state a state to be removed from a set of final states + * + * \returns true if the state was indeed removed + */ void removeFinalState ( const StateType & state ) { this->template accessComponent < FinalStates > ( ).remove ( state ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ const ext::set < SymbolType > & getInputAlphabet ( ) const { return this->template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Adder of a input symbol. + * + * \param symbol the new symbol to be added to an input alphabet + * + * \returns true if the symbol was indeed added + */ bool addInputSymbol ( SymbolType symbol ) { return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Adder of input symbols. + * + * \param symbols new symbols to be added to an input alphabet + */ void addInputSymbols ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ void setInputAlphabet ( ext::set < SymbolType > symbols ) { this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Remover of an input symbol. + * + * \param symbol a symbol to be removed from an input alphabet + * + * \returns true if the symbol was indeed removed + */ void removeInputSymbol ( const SymbolType & symbol ) { this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ bool addTransition ( StateType current, SymbolType input, StateType next ); /** - * Adds transition defined by parameters to the automaton. - * @param current current state - * @param input input symbol - * @param next next state - * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + * \brief Add a transitions to the automaton. + * + * \details The transition is in a form A times a -> P(Q), where A \in Q, a \in T, P(Q) is a powerset of states. + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transitions contain states or symbols not present in the automaton components */ void addTransitions ( StateType current, SymbolType input, ext::set < StateType > next ); /** - * Removes transition from the automaton. - * @param transition transition to remove - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A times a -> B, where A, B \in Q and a \in T + * + * \param current the source state (A) + * \param input the input symbol (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & current, const SymbolType & input, const StateType & next ); /** - * @return automaton transitions + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton */ const ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > & getTransitions ( ) const; /** - * @return automaton transitions from state + * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. + * + * \param from filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the source state fixed */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getTransitionsFromState ( const StateType & from ) const; /** - * @return automaton transitions to state + * Get a subset of the transition function of the automaton, with the target state fixed in the transitions natural representation. + * + * \param to filter the transition function based on this state as a source state + * + * \returns a subset of the transition function of the automaton with the target state fixed */ ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; /** - * Determines whether MultiInitialStateNFA is deterministic. - * FA is deterministic if and only if: + * \brief Determines whether the automaton is deterministic. + * + * the automaton is deterministic if and only if: * \li \c contains only 1 initial state. - * \li \c is epsilon free. Trivial for this class * \li \c size of transition function \delta (from state, input symbol) \leq 1 - * @return true when automaton is deterministic, false otherwise + * + * \return true if the automaton is deterministic, false otherwise */ bool isDeterministic ( ) const; /** - * Determines whether MultiInitialStateNFA is total deterministic - * FA is deterministic if and only if + * \brief Determines whether the automaton is total deterministic + * + * The automaton is deterministic if and only if: * \li \c it is deterministic * \li \c size of transition function \forall states and \forall input symbols \delta (from state, input symbol) = 1 - * @return true when automaton is total deterministic, false otherwise + * + * \return true if the automaton is total deterministic, false otherwise */ bool isTotal ( ) const; + /** + * \brief Computes number of transitions in the automaton + * + * \return number of transitions in the automaton + */ unsigned transitionsSize ( ) const; - virtual int compare ( const ObjectBase & other ) const { + /** + * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) + */ + virtual int compare ( const ObjectBase & other ) const override { if ( ext::type_index ( typeid ( * this ) ) == ext::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return ext::type_index ( typeid ( * this ) ) - ext::type_index ( typeid ( other ) ); } - virtual int compare ( const MultiInitialStateNFA & other ) const; + /** + * The actual compare method + * + * \param other the other instance + * + * \returns the actual relation between two by type same automata instances + */ + int compare ( const MultiInitialStateNFA & other ) const; - virtual void operator >>( std::ostream & os ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator >> ( std::ostream & ) + */ + virtual void operator >>( std::ostream & os ) const override; - virtual explicit operator std::string ( ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual explicit operator std::string ( ) const override; + /** + * \brief The XML tag name of class. + * + * \details Intentionaly a static member function to be safe in the initialisation before the main function starts. + * + * \returns string representing the XML tag name of the class + */ static const std::string & getXmlTagName() { static std::string xmlTagName = "MultiInitialStateNFA"; return xmlTagName; } + /** + * Parsing from a sequence of xml tokens helper. + * + * \params input the iterator to sequence of xml tokens to parse from + * + * \returns the new instance of the automaton + */ static MultiInitialStateNFA parse ( ext::deque < sax::Token >::iterator & input ); + + /** + * Helper for parsing of individual transitions of the automaton from a sequence of xml tokens. + * + * \params input the iterator to sequence of xml tokens to parse from + * \params automaton the automaton to add the rule to + */ static void parseTransition ( ext::deque < sax::Token >::iterator & input, MultiInitialStateNFA & automaton ); - void compose ( ext::deque < sax::Token > & out ) const; + /** + * Composing to a sequence of xml tokens helper. + * + * \param out the sink for new xml tokens representing the automaton + */ + virtual void compose ( ext::deque < sax::Token > & out ) const override; + + /** + * Helper for composing transitions of the automaton to a sequence of xml tokens. + * + * \param out the sink for xml tokens representing the rules of the automaton + */ void composeTransitions ( ext::deque < sax::Token > & out ) const; - virtual alib::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual alib::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef MultiInitialStateNFA < > normalized_type; - virtual AutomatonBase * normalize ( ) && { + /** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states. + * + * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones + */ + virtual AutomatonBase * normalize ( ) && override { if ( typeid ( MultiInitialStateNFA < > ) == typeid ( MultiInitialStateNFA < SymbolType, StateType > ) ) return this; @@ -460,9 +719,23 @@ alib::ObjectBase* MultiInitialStateNFA < SymbolType, StateType >::inc() && { namespace alib { +/** + * Helper class specifying constraints for the automaton's internal input alphabet component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > { public: + /** + * Returns true if the symbol is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ static bool used ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) { for ( const std::pair < const ext::pair < StateType, SymbolType >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) if ( transition.first.second == symbol ) @@ -471,17 +744,45 @@ public: return false; } + /** + * Returns true as all symbols are possibly available to be elements of the input alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const SymbolType & ) { return true; } + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const SymbolType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::States > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const StateType & state ) { if ( automaton.getInitialStates ( ).count ( state ) ) return true; @@ -496,40 +797,110 @@ public: return false; } + /** + * Returns true as all states are possibly available to be elements of the states. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { return true; } + /** + * All states are valid as a state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal final states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::FinalStates > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { return false; } + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as a final state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { } }; +/** + * Helper class specifying constraints for the automaton's internal initial states component. + * + * \tparam SymbolType used for the terminal alphabet of the automaton. + * \tparam StateType used for the terminal alphabet of the automaton. + */ template < class SymbolType, class StateType > class ComponentConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::InitialStates > { public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ static bool used ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { return false; } + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ static bool available ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const StateType & state ) { return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } + /** + * All states are valid as a initial state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::MultiInitialStateNFA < SymbolType, StateType > &, const StateType & ) { } }; diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h index 2c6c3ea8859ec647de71d73564efd564c00809c0..63a20c18e11e8aa1c37c45918af539951f35ed1b 100644 --- a/alib2data/src/automaton/FSM/NFA.h +++ b/alib2data/src/automaton/FSM/NFA.h @@ -69,14 +69,14 @@ class NFA final : public AutomatonBase, public alib::Components < NFA < SymbolTy public: /** - * \brief Creates a new instance of Nondeterministic finite automaton with a concrete initial state. + * \brief Creates a new instance of the automaton with a concrete initial state. * * \param initialState the initial state of the automaton */ explicit NFA ( StateType initialState ); /** - * \brief Creates a new instance of Nondeterministic finite automaton with a concrete set of states, input alphabet, initial state, and a set of final states. + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, initial state, and a set of final states. * * \param states the initial set of states of the automaton * \param inputAlphabet the initial input alphabet @@ -86,7 +86,7 @@ public: explicit NFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ); /* - * \brief Creates a new instance of Nondeterministic finite automaton based on the Deterministic finite automaton. + * \brief Creates a new instance of the automaton based on the Deterministic finite automaton. * * \param other the Deterministic finite automaton */ @@ -300,7 +300,7 @@ public: const ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > & getTransitions ( ) const; /** - * Get a subset of the transition function of the automaton, with the source state fixed as a view to the internal representation. + * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. * * \param from filter the transition function based on this state as a source state * @@ -318,23 +318,23 @@ public: ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; /** - * \brief Determines whether Nonterministic finite automaton is deterministic. + * \brief Determines whether the automaton is deterministic. * - * Nonodeterministic finite automaton is deterministic if and only if: + * the automaton is deterministic if and only if: * \li \c size of transition function \delta (from state, input symbol) \leq 1 * - * @return true if the automaton is deterministic, false otherwise + * \return true if the automaton is deterministic, false otherwise */ bool isDeterministic ( ) const; /** - * \brief Determines whether Nondeterministic finite automaton is total deterministic + * \brief Determines whether the automaton is total deterministic * - * Nondeterministic finite automaton is deterministic if and only if: + * The automaton is deterministic if and only if: * \li \c it is deterministic * \li \c size of transition function \forall states and \forall input symbols \delta (from state, input symbol) = 1 * - * @return true if the automaton is total deterministic, false otherwise + * \return true if the automaton is total deterministic, false otherwise */ bool isTotal ( ) const; @@ -348,7 +348,7 @@ public: /** * @copydoc alib::CommonBase<ObjectBase>::compare ( const ObjectBase & ) */ - int compare ( const ObjectBase & other ) const override { + virtual int compare ( const ObjectBase & other ) const override { if ( ext::type_index ( typeid ( * this ) ) == ext::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); return ext::type_index ( typeid ( * this ) ) - ext::type_index ( typeid ( other ) );