From dd351f38acca6cc0a77ffb84a6e8a7d66a513649 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 6 Apr 2018 10:30:32 +0200 Subject: [PATCH] document turing machine --- alib2data/src/automaton/TM/OneTapeDTM.h | 475 +++++++++++++++++++++++- 1 file changed, 458 insertions(+), 17 deletions(-) diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h index 2440ac075c..ea9e71678e 100644 --- a/alib2data/src/automaton/TM/OneTapeDTM.h +++ b/alib2data/src/automaton/TM/OneTapeDTM.h @@ -1,6 +1,22 @@ /* * OneTapeDTM.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: Apr 24, 2013 * Author: Martin Zak * Author: Jan Travnicek @@ -39,182 +55,461 @@ class FinalStates; class InitialState; /** - * One tape turing machine + * \brief + * Deterministic single tape turing machine. Accepts recursive languages. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, G, \delta, I, B, F), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal symbols - having this empty won't let automaton do much though, + * G (TapeAlphabet) = finite work alphabet + * \delta = transition function of the form A \times a -> B \times b \times {-1, 0, 1}, where A, B \in Q \ F and a, b \in G, + * I (InitialState) = initial state, + * B (BlankSymbol) = blank symbol + * F (FinalStates) = set of final 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 OneTapeDTM final : public AutomatonBase, public core::Components < OneTapeDTM < SymbolType, StateType >, ext::set < SymbolType >, component::Set, std::tuple < TapeAlphabet, InputAlphabet >, SymbolType, component::Value, BlankSymbol, ext::set < StateType >, component::Set, std::tuple < States, FinalStates >, StateType, component::Value, InitialState > { -protected: + /** + * Transition function as mapping from a state \times a tape symbol on the left hand side to a state \times tape symbol \times shift on tape. + */ ext::map < ext::pair < StateType, SymbolType >, ext::tuple < StateType, SymbolType, Shift > > transitions; public: + /** + * \brief Creates a new instance of the automaton with a concrete set of states, tape alphabet, blank symbol, input alphabet, initial state, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param tapeAlphabet the initial tape alphabet of the automaton + * \param blankSymbol the initial blank symbol of the automaton + * \param inputAlphabet the initial input alphabet of the automaton + * \param initialState the initial state of the automaton + * \param finalStates the initial set of final states of the automaton + */ explicit OneTapeDTM ( ext::set < StateType > states, ext::set < SymbolType > tapeAlphabet, SymbolType blankSymbol, ext::set< SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ); + /** + * \brief Creates a new instance of the automaton with a concrete initial state and blank symbol. + * + * \param initialState the initial state of the automaton + * \param blankSymbol the initial blank symbol of the automaton + */ explicit OneTapeDTM ( StateType initialState, SymbolType blank ); - 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 accessComponent < InitialState > ( ).get ( ); } + /** + * Getter of the initial state. + * + * \returns the initial state of the automaton + */ StateType && getInitialState ( ) && { return std::move ( this-> template accessComponent < 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 accessComponent < 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 ( ); } + /** + * 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 < SymbolType > & getInputAlphabet ( ) const & { return this-> template accessComponent < InputAlphabet > ( ).get ( ); } + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ ext::set < SymbolType > && 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 ( 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 ); } + /** + * Getter of the tape alphabet. + * + * \returns the tape alphabet of the automaton + */ const ext::set < SymbolType > & getTapeAlphabet ( ) const & { return this-> template accessComponent < TapeAlphabet > ( ).get ( ); } + /** + * Getter of the tape alphabet. + * + * \returns the tape alphabet of the automaton + */ ext::set < SymbolType > && getTapeAlphabet ( ) && { return std::move ( this-> template accessComponent < TapeAlphabet > ( ).get ( ) ); } + /** + * Adder of a tape symbol. + * + * \param symbol the new symbol to be added to a tape alphabet + * + * \returns true if the symbol was indeed added + */ bool addTapeSymbol ( SymbolType symbol ) { return this-> template accessComponent < TapeAlphabet > ( ).add ( std::move ( symbol ) ); } + /** + * Adder of tape symbols. + * + * \param symbols new symbols to be added to an tape alphabet + */ void addTapeSymbols ( ext::set < SymbolType > symbols ) { this-> template accessComponent < TapeAlphabet > ( ).add ( std::move ( symbols ) ); } + /** + * Setter of tape alphabet. + * + * \param symbols completely new tape alphabet + */ void setTapeAlphabet ( ext::set < SymbolType > symbols ) { this-> template accessComponent < TapeAlphabet > ( ).set ( std::move ( symbols ) ); } + /** + * Remover of a tape symbol. + * + * \param symbol a symbol to be removed from a tape alphabet + * + * \returns true if the symbol was indeed removed + */ void removeTapeSymbol ( const SymbolType & symbol ) { this-> template accessComponent < TapeAlphabet > ( ).remove ( symbol ); } + /** + * Getter of the blank symbol. + * + * \returns the blank symbol of the automaton + */ const SymbolType & getBlankSymbol ( ) const & { return this-> template accessComponent < BlankSymbol > ( ).get ( ); } + /** + * Getter of the blank symbol. + * + * \returns the blank symbol of the automaton + */ SymbolType && getBlankSymbol ( ) && { return std::move ( this-> template accessComponent < BlankSymbol > ( ).get ( ) ); } + /** + * Setter of the blank symbol. + * + * \param state new blank symbol of the automaton + * + * \returns true if the blank symbol was indeed changed + */ bool setBlankSymbol ( SymbolType state ) { return this-> template accessComponent < BlankSymbol > ( ).set ( std::move ( state ) ); } /** - * Adds transition to the automaton. - * @param transition transition to add - * @throws AutomatonException when some part of the transition is not present - * in the TM (state, tape symbol) or when transition already exists + * \brief Add a transition to the automaton. + * + * \details The transition is in a form A \times a -> B \times b \times {-1, 0, 1}, where A, B \in Q and a, b \in G + * + * \param current the source state (A) + * \param input the tape symbol (a) + * \param next the target state (B) + * \param output the tape symbol (b) + * \param shift the direction of change on the tape + * + * \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, SymbolType output, Shift shift ); /** - * Removes the transition from the TM. - * @param transition transition to remove - * @throws AutomatonException when transition is not present in the TM + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form A \times a -> B \times b \times {-1, 0, 1}, where A, B \in Q and a, b \in G + * + * \param current the source state (A) + * \param input the tape symbol (a) + * \param next the target state (B) + * \param output the tape symbol (b) + * \param shift the direction of change on the tape + * + * \returns true if the transition was indeed removed */ bool removeTransition ( const StateType & from, const SymbolType & input, const StateType & to, const SymbolType & output, const Shift & shift ); /** - * @return TM 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::tuple < StateType, SymbolType, Shift > > & getTransitions ( ) const &; + /** + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton + */ ext::map < ext::pair < StateType, SymbolType >, ext::tuple < StateType, SymbolType, Shift > > && getTransitions ( ) &&; - 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 OneTapeDTM & 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 OneTapeDTM & 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 = "OneTapeDTM"; 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 OneTapeDTM 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, OneTapeDTM & 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 OneTapeDTM & 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 OneTapeDTM & automaton ); - virtual object::ObjectBase * inc ( ) &&; + /** + * @copydoc alib::GrammarBase::inc() + */ + virtual object::ObjectBase * inc ( ) && override; + /** + * Type of normalized automaton. + */ typedef OneTapeDTM < > normalized_type; }; @@ -406,9 +701,23 @@ object::ObjectBase* OneTapeDTM < SymbolType, StateType >::inc() && { namespace core { +/** + * Helper class specifying constraints for the automaton's internal tape 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 SetConstraint< automaton::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::TapeAlphabet > { 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::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) { if ( automaton.getBlankSymbol ( ) == symbol ) return true; @@ -424,47 +733,123 @@ public: } + /** + * Returns true as all symbols are possibly available to be elements of the tape alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType &) { return true; } + /** + * All symbols are valid as tape symbols. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType & ) { } }; +/** + * 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 SetConstraint< automaton::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::InputAlphabet > { public: + /** + * Returns false. Input symbol is only a mark that the automaton itself does require further. + * + * \param automaton the tested automaton + * \param state the tested symbol + * + * \returns false + */ static bool used ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType & ) { return false; } + /** + * Determines whether the input symbol is available in the automaton's tape alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the symbol is already in the tape alphabet of the automaton + */ static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) { return automaton.getTapeAlphabet ( ).count ( symbol ); } + /** + * Input symbol can't be the same as blank symbol. + * + * \param automaton the tested automaton + * \param state the tested symbol + */ static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) { if (symbol == automaton.getBlankSymbol()) throw automaton::AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" cannot be blank symbol."); } }; +/** + * Helper class specifying constraints for the automaton's internal blank symbol 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::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::BlankSymbol > { public: + /** + * Determines whether the blank symbol is available in the automaton's tape alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the symbol is already in the tape alphabet of the automaton + */ static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) { return automaton.getTapeAlphabet ( ).count ( symbol ); } + /** + * Blank symbol can't be in the automaton's input alphabet. + * + * \param automaton the tested automaton + * \param state the tested state + */ static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) { if (automaton.getInputAlphabet().count( symbol )) throw automaton::AutomatonException("Blank symbol \"" + ext::to_string ( symbol ) + "\" cannot be in input alphabet."); } }; +/** + * 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 SetConstraint< automaton::OneTapeDTM<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::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) { if ( automaton.getInitialState ( ) == state ) return true; @@ -479,21 +864,57 @@ 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::OneTapeDTM<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::OneTapeDTM<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 SetConstraint< automaton::OneTapeDTM<SymbolType, 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::OneTapeDTM<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::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) { return automaton.getStates ( ).count ( state ); } @@ -511,13 +932,33 @@ public: } }; +/** + * 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::OneTapeDTM<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::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) { return automaton.getStates ( ).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::OneTapeDTM<SymbolType, StateType> &, const StateType & ) { } }; -- GitLab