Skip to content
Snippets Groups Projects
Commit 0d06a81f authored by Jan Trávníček's avatar Jan Trávníček
Browse files

document NFTA automaton

parent 275d1d2a
No related branches found
No related tags found
No related merge requests found
/*
* 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 & ) {
}
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment