diff --git a/alib2data/src/automaton/TA/NFTA.h b/alib2data/src/automaton/TA/NFTA.h index ee2850c4342bdf8127b5f8e523cb1bfefbc2b781..990497a41904ca1cc619bf2ba8c79c9393016ed4 100644 --- a/alib2data/src/automaton/TA/NFTA.h +++ b/alib2data/src/automaton/TA/NFTA.h @@ -1,6 +1,22 @@ /* * NFTA.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 21, 2015 * Author: Stepan Plachy */ @@ -38,157 +54,387 @@ class FinalStates; * Represents Finite Tree Automaton. * Can store nondeterministic finite tree automaton without epsilon transitions. */ +/** + * \brief + * Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, \delta, F), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal ranked symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form (A, B, C, ...) \times a -> P(Q), where A, B, C, ... \in Q, a \in T, and P(Q) is a powerset of states, + * F (FinalStates) = set of final states + * + * Elements of the \delta mapping must meet following criteria. The size of the state list must equal the rank of the ranked symbol. + * + * \tparam SymbolType used for the terminal alphabet + * \tparam StateType used to the states, and the initial state of the automaton. + */ template < class SymbolType, class RankType, class StateType > class NFTA final : public AutomatonBase, public core::Components < NFTA < SymbolType, RankType, StateType >, ext::set < common::ranked_symbol < SymbolType, RankType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > { + /** + * Transition function as mapping from a list of states times an input symbol on the left hand side to a set of states. + */ ext::map < ext::pair < common::ranked_symbol < SymbolType, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions; public: + /** + * \brief Creates a new instance of the automaton. + */ explicit NFTA ( ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param finalStates the initial set of final states of the automaton + */ explicit NFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType, RankType > > inputAlphabet, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of the automaton based on the Deterministic finite tree automaton. + * + * \param other the Deterministic finite tree automaton + */ explicit NFTA ( const DFTA < SymbolType, RankType, 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 states. + * + * \returns the states of the automaton + */ const ext::set < StateType > & getStates ( ) const & { return this->template accessComponent < States > ( ).get ( ); } + /** + * Getter of states. + * + * \returns the states of the automaton + */ ext::set < StateType > && getStates ( ) && { return std::move ( 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 ( ); } + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ ext::set < StateType > && getFinalStates ( ) && { return std::move ( 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 < common::ranked_symbol < SymbolType, RankType > > & getInputAlphabet ( ) const & { return this->template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ ext::set < common::ranked_symbol < SymbolType, RankType > > && getInputAlphabet ( ) && { return std::move ( 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 ( common::ranked_symbol < SymbolType, RankType > 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 < common::ranked_symbol < SymbolType, RankType > > symbols ) { this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ void setInputAlphabet ( ext::set < common::ranked_symbol < SymbolType, RankType > > 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 common::ranked_symbol < SymbolType, RankType > & symbol ) { this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** - * Adds transition defined by parameters to the automaton. - * @param current current symbol in node - * @param children states of children of current node - * @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, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T + * + * \param children the source states (A, B, C, ...) + * \param current 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 ( common::ranked_symbol < SymbolType, RankType > current, ext::vector < StateType > children, StateType next ); /** - * Adds transition defined by parameters to the automaton. - * @param current current symbol in node - * @param children states of children of current node - * @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, B, C, ... ) \times a -> P(Q), where A, B, C, ... \in Q and a \in T, P(Q) is a powerset of states + * + * \param children the source states (A, B, C, ...) + * \param current the input symbol (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added */ void addTransitions ( common::ranked_symbol < SymbolType, RankType > current, ext::vector < StateType > children, ext::set < StateType > next ); /** - * Removes transition from the automaton. - * @throws AutomatonException when transition doesn't exists. + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T + * + * \param children the source states (A, B, C, ...) + * \param current the input symbol (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const common::ranked_symbol < SymbolType, RankType > symbol, const ext::vector < StateType > & states, 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 < common::ranked_symbol < SymbolType, RankType >, ext::vector < StateType > >, ext::set < StateType > > & getTransitions ( ) const & { return transitions; } + /** + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton + */ ext::map < ext::pair < common::ranked_symbol < SymbolType, RankType >, ext::vector < StateType > >, ext::set < StateType > > && getTransitions ( ) && { return std::move ( transitions ); } + /* Get the target states of a transition identified by input symbol and source trantition + * + * \param symbol the input symbol + * \param states source states + * + * \return target states + */ ext::set < StateType > getTransitionRightSide ( const common::ranked_symbol < SymbolType, RankType > symbol, const ext::vector < StateType > & states ); /** - * Determines whether NFTA is deterministic. - * FA is deterministic if and only if: - * \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 + * \brief Determines whether the automaton is deterministic. + * + * the automaton is deterministic if and only if: + * \li \c size of transition function \delta (from states, input symbol) \leq 1 + * + * \return true if the automaton is deterministic, false otherwise */ bool isDeterministic ( ) 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 NFTA & 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 NFTA & 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 operator std::string ( ) const; + /** + * @copydoc alib::CommonBase<ObjectBase>::operator std::string ( ) + */ + virtual 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 = "NFTA"; 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 NFTA 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, NFTA & automaton ); + /** + * Composing to a sequence of xml tokens helper. + * + * \param out the sink for new xml tokens representing the automaton + * \param automaton the automaton to compose + */ static void compose ( ext::deque < sax::Token > & out, const NFTA & automaton ); + + /** + * 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 + * \param automaton the automaton to compose + */ static void composeTransitions ( ext::deque < sax::Token > & out, const NFTA & automaton ); - virtual object::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual object::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef NFTA < > normalized_type; }; @@ -383,9 +629,23 @@ object::ObjectBase* NFTA < SymbolType, RankType, StateType >::inc() && { namespace core { +/** + * 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 RankType, class StateType > class SetConstraint< automaton::NFTA < SymbolType, RankType, StateType >, common::ranked_symbol < SymbolType, RankType >, 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::NFTA < SymbolType, RankType, StateType > & automaton, const common::ranked_symbol < SymbolType, RankType > & symbol ) { for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType, RankType >, ext::vector<StateType> >, ext::set<StateType>>& t : automaton.getTransitions()) if (t.first.first == symbol) @@ -394,17 +654,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::NFTA < SymbolType, RankType, StateType > &, const common::ranked_symbol < SymbolType, RankType > & ) { return true; } + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::NFTA < SymbolType, RankType, StateType > &, const common::ranked_symbol < SymbolType, RankType > & ) { } }; +/** + * 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 RankType, class StateType > class SetConstraint< automaton::NFTA < SymbolType, RankType, 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::NFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) { if ( automaton.getFinalStates ( ).count ( state ) ) return true; @@ -416,25 +704,67 @@ 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::NFTA < SymbolType, RankType, 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::NFTA < SymbolType, RankType, 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 RankType, class StateType > class SetConstraint< automaton::NFTA < SymbolType, RankType, StateType >, StateType, automaton::FinalStates > { public: + /** + * Returns false. Final state is only a mark that the automaton itself does require further. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns false + */ static bool used ( const automaton::NFTA < SymbolType, RankType, 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::NFTA < SymbolType, RankType, 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::NFTA < SymbolType, RankType, StateType > &, const StateType & ) { } };