/*
 * 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
 */

#pragma once

#include <sstream>

#include <alib/map>
#include <alib/set>
#include <alib/tuple>

#include <core/components.hpp>

#include <common/DefaultStateType.h>
#include <common/DefaultSymbolType.h>

#include <automaton/AutomatonException.h>
#include <automaton/common/Shift.h>

#include <core/normalize.hpp>
#include <alphabet/common/SymbolNormalize.h>
#include <automaton/common/AutomatonNormalize.h>

namespace automaton {

class TapeAlphabet;
class InputAlphabet;
class BlankSymbol;
class States;
class FinalStates;
class InitialState;

/**
 * \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 SymbolTypeT used for the terminal alphabet
 * \tparam StateTypeT used to the states, and the initial state of the automaton.
 */
template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
class OneTapeDTM final : public core::Components < OneTapeDTM < SymbolTypeT, StateTypeT >, ext::set < SymbolTypeT >, component::Set, std::tuple < TapeAlphabet, InputAlphabet >, SymbolTypeT, component::Value, BlankSymbol, ext::set < StateTypeT >, component::Set, std::tuple < States, FinalStates >, StateTypeT, component::Value, InitialState > {
public:
	typedef SymbolTypeT SymbolType;
	typedef StateTypeT StateType;

private:
	/**
	 * 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 initial, SymbolType blank );

	/**
	 * 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 ) );
	}

	/**
	 * \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 );

	/**
	 * \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 );

	/**
	 * 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 ( ) &&;

	/**
	 * The three way comparison implementation
	 *
	 * \param other the other instance
	 *
	 * \returns the ordering between this object and the @p other.
	 */
	auto operator <=> ( const OneTapeDTM & other ) const {
		return std::tie(getStates(), getInputAlphabet(), getInitialState(), getFinalStates(), getTapeAlphabet(), getBlankSymbol(), transitions) <=> std::tie(other.getStates(), other.getInputAlphabet(), other.getInitialState(), other.getFinalStates(), other.getTapeAlphabet(), other.getBlankSymbol(), other.transitions);
	}

	/**
	 * The equality comparison implementation.
	 *
	 * \param other the other object to compare with.
	 *
	 * \returns true if this and other objects are equal, false othervise
	 */
	bool operator == ( const OneTapeDTM & other ) const {
		return std::tie(getStates(), getInputAlphabet(), getInitialState(), getFinalStates(), getTapeAlphabet(), getBlankSymbol(), transitions) == std::tie(other.getStates(), other.getInputAlphabet(), other.getInitialState(), other.getFinalStates(), other.getTapeAlphabet(), other.getBlankSymbol(), other.transitions);
	}

	/**
	 * Print this object as raw representation to ostream.
	 *
	 * \param out ostream where to print
	 * \param instance object to print
	 *
	 * \returns modified output stream
	 */
	friend std::ostream & operator << ( std::ostream & out, const OneTapeDTM & instance ) {
		return out << "(OneTapeDTM "
			   << "states = " << instance.getStates ( )
			   << "inputAlphabet = " << instance.getInputAlphabet ( )
			   << "initialState = " << instance.getInitialState ( )
			   << "finalStates = " << instance.getFinalStates ( )
			   << "tapeAlphabet = " << instance.getTapeAlphabet ( )
			   << "blankSymbol = " << instance.getBlankSymbol ( )
			   << "transitions = " << instance.getTransitions ( )
			   << ")";
	}

	/**
	 * Casts this instance to as compact as possible string representation.
	 *
	 * \returns string representation of the object
	 */
	explicit operator std::string ( ) const;
};

template<class SymbolType, class StateType >
OneTapeDTM<SymbolType, StateType>::OneTapeDTM ( ext::set < StateType > states, ext::set < SymbolType > tapeAlphabet, SymbolType blankSymbol, ext::set< SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ) : core::Components < OneTapeDTM, 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 > ( std::move ( tapeAlphabet ), std::move ( inputAlphabet ), std::move ( blankSymbol ), std::move ( states ), std::move ( finalStates ), std::move ( initialState ) ) {

}

template<class SymbolType, class StateType >
OneTapeDTM<SymbolType, StateType>::OneTapeDTM(StateType initial, SymbolType blank) : OneTapeDTM(ext::set<StateType>{initial}, ext::set<SymbolType> {blank}, blank, ext::set<SymbolType>{}, initial, ext::set<StateType>{}) {

}

template<class SymbolType, class StateType >
bool OneTapeDTM<SymbolType, StateType>::addTransition(StateType from, SymbolType input, StateType to, SymbolType output, Shift shift) {
	if (!getStates().count(from)) {
		throw AutomatonException("State \"" + ext::to_string ( from ) + "\" doesn't exist.");
	}

	if ( getFinalStates().count ( from ) )
		throw AutomatonException("From state \"" + ext::to_string ( from ) + "\" is final..");

	if (!getTapeAlphabet().count(input)) {
		throw AutomatonException("Tape symbol \"" + ext::to_string ( input ) + "\" doesn't exist.");
	}

	if (!getStates().count(to)) {
		throw AutomatonException("State \"" + ext::to_string ( to ) + "\" doesn't exist.");
	}

	if (!getTapeAlphabet().count(output)) {
		throw AutomatonException("Tape symbol  \"" + ext::to_string ( output ) + "\" doesn't exist.");
	}

	ext::pair<StateType, SymbolType> key = ext::make_pair(std::move(from), std::move(input));

	ext::tuple<StateType, SymbolType, Shift > value(std::move(to), std::move(output), shift);

	if (transitions.find(key) != transitions.end()) {
		if(transitions.find(key)->second == value)
			return false;
		else
			throw AutomatonException("Transition (\"" + ext::to_string ( key.first ) + "\", \"" + ext::to_string ( key.second ) + "\") -> ? already exists.");
	}

	transitions.insert ( std::move(key), std::move(value) );
	return true;
}

template<class SymbolType, class StateType >
bool OneTapeDTM<SymbolType, StateType>::removeTransition(const StateType& from, const SymbolType& input, const StateType& to, const SymbolType& output, const Shift& shift) {
	ext::pair<StateType, SymbolType> key = ext::make_pair(from, input);

	if (transitions.find(key) == transitions.end())
		return false;

	ext::tuple<StateType, SymbolType, Shift > value(to, output, shift);
	if(transitions.find(key)->second != value)
		throw AutomatonException("Transition (\"" + ext::to_string ( from ) + "\", \"" + ext::to_string ( input ) + "\") -> ? doesn't exists.");

	transitions.erase(key);
	return true;
}

template<class SymbolType, class StateType >
const ext::map < ext::pair < StateType, SymbolType >, ext::tuple < StateType, SymbolType, Shift > > & OneTapeDTM < SymbolType, StateType >::getTransitions ( ) const & {
	return transitions;
}

template<class SymbolType, class StateType >
ext::map < ext::pair < StateType, SymbolType >, ext::tuple < StateType, SymbolType, Shift > > && OneTapeDTM < SymbolType, StateType >::getTransitions ( ) && {
	return std::move ( transitions );
}

template<class SymbolType, class StateType >
OneTapeDTM<SymbolType, StateType>::operator std::string ( ) const {
	std::stringstream ss;
	ss << *this;
	return ss.str();
}

} /* namespace automaton */

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;

		if ( automaton.getInputAlphabet().count(symbol))
			return true;

		for ( const std::pair<const ext::pair<StateType, SymbolType>, ext::tuple<StateType, SymbolType, automaton::Shift> >& transition : automaton.getTransitions())
			if (symbol == transition.first.second || symbol == std::get<1>(transition.second))
				return true;

		return false;

	}

	/**
	 * Returns true as all symbols are possibly available to be elements of the tape alphabet.
	 *
	 * \param automaton the tested automaton
	 * \param symbol the tested symbol
	 *
	 * \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 symbol the tested symbol
	 */
	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 symbol 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 symbol the tested symbol
	 *
	 * \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 symbol 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 symbol the tested symbol
	 *
	 * \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 symbol the tested symbol
	 */
	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;

		if ( automaton.getFinalStates ( ).count ( state ) )
			return true;

		for ( const std::pair<const ext::pair<StateType, SymbolType>, ext::tuple<StateType, SymbolType, automaton::Shift> >& transition : automaton.getTransitions ( ) )
			if ( state == transition.first.first || state == std::get < 0 > ( transition.second ) )
				return true;

		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 );
	}

	/**
	 * 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::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) {
		for ( const std::pair<const ext::pair<StateType, SymbolType>, ext::tuple<StateType, SymbolType, automaton::Shift> >& transition : automaton.getTransitions ( ) )
			if ( state == transition.first.first )
				throw automaton::AutomatonException("State \"" + ext::to_string ( state ) + "\" cannot be marked as final as it is source of a transition.");
	}
};

/**
 * 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 & ) {
	}
};

/**
 * 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
 */
template<class SymbolType, class StateType >
struct normalize < automaton::OneTapeDTM < SymbolType, StateType > > {
	static automaton::OneTapeDTM < > eval ( automaton::OneTapeDTM < SymbolType, StateType > && value ) {
		ext::set < DefaultSymbolType > tapeAlphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getTapeAlphabet ( ) );
		ext::set < DefaultSymbolType > alphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getInputAlphabet ( ) );
		DefaultSymbolType blankSymbol = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( value ).getBlankSymbol ( ) );
		ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
		DefaultStateType initialState = automaton::AutomatonNormalize::normalizeState ( std::move ( value ).getInitialState ( ) );
		ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );

		automaton::OneTapeDTM < > res ( std::move ( states ), std::move ( tapeAlphabet ), std::move ( blankSymbol ), std::move ( alphabet ), std::move ( initialState ), std::move ( finalStates ) );

		for ( std::pair < ext::pair < DefaultStateType, DefaultSymbolType >, ext::tuple < DefaultStateType, DefaultSymbolType, automaton::Shift > > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
			DefaultStateType from = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.first.first ) );
			DefaultSymbolType input = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( transition.first.second ) );
			DefaultStateType to = automaton::AutomatonNormalize::normalizeState ( std::move ( std::get < 0 > ( transition.second ) ) );
			DefaultSymbolType output = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( std::get < 1 > ( transition.second ) ) );

			res.addTransition ( std::move ( from ), std::move ( input ), std::move ( to ), std::move ( output ), std::get < 2 > ( transition.second ) );
		}

		return res;
	}
};

} /* namespace core */

extern template class automaton::OneTapeDTM < >;

