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

documentation for finite automata

parent e182560b
No related branches found
No related tags found
No related merge requests found
Pipeline #
/*
* 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 & ) {
}
};
......
......@@ -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
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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 ) );
......
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