From c42927eeddb2b3f04fa6e627fb499b4da2d47521 Mon Sep 17 00:00:00 2001
From: Tomas Pecka <peckato1@fit.cvut.cz>
Date: Thu, 21 Mar 2019 09:36:37 +0100
Subject: [PATCH] Data: ExtendedNFTA

---
 alib2data/src/automaton/TA/ExtendedNFTA.cpp |  16 +
 alib2data/src/automaton/TA/ExtendedNFTA.h   | 719 ++++++++++++++++++++
 2 files changed, 735 insertions(+)
 create mode 100644 alib2data/src/automaton/TA/ExtendedNFTA.cpp
 create mode 100644 alib2data/src/automaton/TA/ExtendedNFTA.h

diff --git a/alib2data/src/automaton/TA/ExtendedNFTA.cpp b/alib2data/src/automaton/TA/ExtendedNFTA.cpp
new file mode 100644
index 0000000000..0e5f3e8078
--- /dev/null
+++ b/alib2data/src/automaton/TA/ExtendedNFTA.cpp
@@ -0,0 +1,16 @@
+/*
+ * ExtendedNFTA.cpp
+ *
+ *  Created on: Mar 13, 2019
+ *      Author: Tomas Pecka
+ */
+
+#include "ExtendedNFTA.h"
+
+#include <registration/ValuePrinterRegistration.hpp>
+
+namespace {
+
+static auto valuePrinter = registration::ValuePrinterRegister < automaton::ExtendedNFTA < > > ( );
+
+} /* namespace */
diff --git a/alib2data/src/automaton/TA/ExtendedNFTA.h b/alib2data/src/automaton/TA/ExtendedNFTA.h
new file mode 100644
index 0000000000..ac14b6ec8e
--- /dev/null
+++ b/alib2data/src/automaton/TA/ExtendedNFTA.h
@@ -0,0 +1,719 @@
+/*
+ * ExtendedNFTA.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 13, 2019
+ *      Author: Tomas Pecka
+ */
+
+#ifndef EXTENDED_NFTA_H_
+#define EXTENDED_NFTA_H_
+
+#include <ostream>
+#include <sstream>
+
+#include <alib/map>
+#include <alib/set>
+#include <alib/vector>
+#include <alib/compare>
+
+#include <core/components.hpp>
+
+#include <core/normalize.hpp>
+
+#include <common/DefaultStateType.h>
+#include <common/DefaultSymbolType.h>
+#include <common/DefaultRankType.h>
+
+#include <automaton/AutomatonException.h>
+
+#include <core/normalize.hpp>
+#include <alphabet/common/SymbolNormalize.h>
+#include <automaton/common/AutomatonNormalize.h>
+
+#include <rte/formal/FormalRTEElements.h>
+#include <rte/formal/FormalRTEStructure.h>
+
+#include "DFTA.h"
+#include "NFTA.h"
+
+namespace automaton {
+
+class InputAlphabet;
+class States;
+class FinalStates;
+
+/**
+ * \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 symbol part of the ranked symbol
+ * \tparam RankType used for the rank part of the ranked symbol
+ * \tparam StateType used to the states, and the initial state of the automaton.
+ */
+template < class SymbolType = DefaultSymbolType, class RankType = DefaultRankType, class StateType = DefaultStateType >
+class ExtendedNFTA final : public ext::CompareOperators < ExtendedNFTA < SymbolType, RankType, StateType > >, public core::Components < ExtendedNFTA < 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 < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions;
+
+public:
+	/**
+	 * \brief Creates a new instance of the automaton.
+	 */
+	explicit ExtendedNFTA ( );
+
+	/**
+	 * \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 ExtendedNFTA ( 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 ExtendedNFTA ( const DFTA < SymbolType, RankType, StateType > & other );
+
+	/*
+	 * \brief Creates a new instance of the automaton based on the Nondeterministic finite tree automaton.
+	 *
+	 * \param other the Deterministic finite tree automaton
+	 */
+	explicit ExtendedNFTA ( const NFTA < SymbolType, RankType, StateType > & other );
+
+	/**
+	 * 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 );
+	}
+
+	/**
+	 * \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 ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > current, ext::vector < StateType >, StateType next );
+
+	/**
+	 * \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 ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > current, ext::vector < StateType >, ext::set < StateType > next );
+
+	/**
+	 * \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 rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, const ext::vector < StateType > & prevStates, const StateType& next );
+
+	/**
+	 * Get the transition function of the automaton in its natural form.
+	 *
+	 * \returns transition function of the automaton
+	 */
+	const ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, 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 < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > && getTransitions ( ) && {
+		return std::move ( transitions );
+	}
+
+	/**
+	 * \returns the subset of transitions where the state @p q is a target state
+	 */
+	ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > getTransitionsToState ( const StateType & q ) const;
+
+	/**
+	 * \returns the subset of transitions where the state @p q is a source state
+	 */
+	ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > getTransitionsFromState ( const StateType & q ) const;
+
+	/**
+	 * \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;
+
+	/**
+	 * The actual compare method
+	 *
+	 * \param other the other instance
+	 *
+	 * \returns the actual relation between two by type same automata instances
+	 */
+	int compare ( const ExtendedNFTA & other ) const;
+
+	/**
+	 * 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 ExtendedNFTA & instance ) {
+		return out << "(ExtendedNFTA "
+			   << " states = " << instance.getStates ( )
+			   << " inputAlphabet = " << instance.getInputAlphabet ( )
+			   << " finalStates = " << instance.getFinalStates ( )
+			   << " transitions = " << instance.getTransitions ( )
+			   << ")";
+	}
+
+	/**
+	 * Casts this instance to as compact as possible string representation.
+	 *
+	 * \returns string representation of the object
+	 */
+	operator std::string ( ) const;
+};
+
+template < class SymbolType, class RankType, class StateType >
+ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType, RankType > > inputAlphabet, ext::set < StateType > finalStates ) : core::Components < ExtendedNFTA, ext::set < common::ranked_symbol < SymbolType, RankType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ) ) {
+}
+
+template < class SymbolType, class RankType, class StateType >
+ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA() : ExtendedNFTA ( ext::set < StateType > { }, ext::set < common::ranked_symbol < SymbolType, RankType > > { }, ext::set < StateType > { } ) {
+}
+
+template < class SymbolType, class RankType, class StateType >
+ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA(const DFTA < SymbolType, RankType, StateType > & other) : ExtendedNFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		// ( symbol, prevStates ) -> nextState
+		// ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions;
+
+		ext::ptr_vector < rte::FormalRTEElement < ext::variant < SymbolType, StateType >, RankType > > children;
+		for ( const StateType & state : transition.first.second )
+			children.push_back ( rte::FormalRTESymbolSubst < ext::variant < SymbolType, StateType >, RankType > ( common::ranked_symbol < ext::variant < SymbolType, StateType > > ( state, 0 ) ) );
+
+		common::ranked_symbol < ext::variant < SymbolType, StateType >, RankType > symbol ( transition.first.first.getSymbol ( ), transition.first.first.getRank ( ) );
+		rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte ( rte::FormalRTESymbolAlphabet < ext::variant < SymbolType, StateType >, RankType > ( symbol, children ) );
+		transitions [ ext::make_pair ( rte, transition.first.second ) ].insert ( transition.second );
+	}
+}
+
+template < class SymbolType, class RankType, class StateType >
+ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA(const NFTA < SymbolType, RankType, StateType > & other) : ExtendedNFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		// ( symbol, prevStates ) -> nextState
+		// ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions;
+
+		ext::ptr_vector < rte::FormalRTEElement < ext::variant < SymbolType, StateType >, RankType > > children;
+		for ( const StateType & state : transition.first.second )
+			children.push_back ( rte::FormalRTESymbolSubst < ext::variant < SymbolType, StateType >, RankType > ( common::ranked_symbol < ext::variant < SymbolType, StateType > > ( state, 0 ) ) );
+
+		common::ranked_symbol < ext::variant < SymbolType, StateType >, RankType > symbol ( transition.first.first.getSymbol ( ), transition.first.first.getRank ( ) );
+		rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte ( rte::FormalRTESymbolAlphabet < ext::variant < SymbolType, StateType >, RankType > ( symbol, children ) );
+		transitions [ ext::make_pair ( rte, transition.first.second ) ].insert ( transition.second );
+	}
+}
+
+template < class SymbolType, class RankType, class StateType >
+bool ExtendedNFTA < SymbolType, RankType, StateType >::addTransition ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, ext::vector < StateType > prevStates, StateType next ) {
+	/*
+	if (prevStates.size() != ( size_t ) symbol.getRank() )
+		throw AutomatonException("Number of states doesn't match rank of the symbol");
+
+	if (! getInputAlphabet().count(symbol))
+		throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist.");
+	*/
+
+	if (! getStates().count(next))
+		throw AutomatonException("State \"" + ext::to_string ( next ) + "\" doesn't exist.");
+
+	for (const StateType& it : prevStates) {
+		if (! getStates().count(it))
+			throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist.");
+	}
+
+	ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( std::move ( rte ), std::move ( prevStates ) );
+	return transitions [ std::move ( key ) ].insert ( std::move ( next ) ).second;
+}
+
+template < class SymbolType, class RankType, class StateType >
+void ExtendedNFTA < SymbolType, RankType, StateType >::addTransitions ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, ext::vector < StateType > prevStates, ext::set < StateType > next ) {
+	/*
+	if (prevStates.size() != ( size_t ) symbol.getRank() )
+		throw AutomatonException("Number of states doesn't match rank of the symbol");
+
+	if (! getInputAlphabet().count(symbol))
+		throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist.");
+	*/
+
+	if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), next.begin ( ), next.end ( ) ) )
+		throw AutomatonException ( "Some target states don't exist." );
+
+	for (const StateType& it : prevStates) {
+		if (! getStates().count(it))
+			throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist.");
+	}
+
+	ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( std::move ( rte ), std::move ( prevStates ) );
+	transitions [ std::move ( key ) ].insert ( ext::make_mover ( next ).begin ( ), ext::make_mover ( next ).end ( ) );
+}
+
+template < class SymbolType, class RankType, class StateType >
+bool ExtendedNFTA < SymbolType, RankType, StateType >::removeTransition ( const rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, const ext::vector < StateType > & prevStates, const StateType& next ) {
+	ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( rte, prevStates );
+	return transitions [ key ].erase ( next );
+}
+
+template < class SymbolType, class RankType, class StateType >
+bool ExtendedNFTA < SymbolType, RankType, StateType >::isDeterministic() const {
+	return false;
+}
+
+
+template < class SymbolType, class RankType, class StateType >
+unsigned ExtendedNFTA < SymbolType, RankType, StateType >::transitionsSize() const {
+	int res = 0;
+
+	for(const auto& transition : transitions )
+		res += transition.second.size();
+
+	return res;
+}
+
+template<class SymbolType, class RankType, class StateType >
+ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > ExtendedNFTA < SymbolType, RankType, StateType >::getTransitionsToState ( const StateType & to ) const {
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist" );
+
+	ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > res;
+
+	for ( const auto & transition : transitions )
+		if ( transition.second.count ( to ) > 0 )
+			res.insert ( ext::make_pair ( transition.first, to ) );
+
+	return res;
+}
+
+template<class SymbolType, class RankType, class StateType >
+ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > ExtendedNFTA < SymbolType, RankType, StateType >::getTransitionsFromState ( const StateType & from ) const {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" );
+
+	ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > res;
+
+	for ( const auto & transition : transitions )
+		if ( std::find ( transition.first.second.begin ( ), transition.first.second.end ( ), from ) != transition.first.second.end ( ) )
+			res.insert ( transition );
+
+	return res;
+}
+
+
+template < class SymbolType, class RankType, class StateType >
+int ExtendedNFTA < SymbolType, RankType, StateType >::compare(const ExtendedNFTA& other) const {
+	auto first = ext::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions);
+	auto second = ext::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
+
+	static ext::compare<decltype(first)> comp;
+	return comp(first, second);
+}
+
+template < class SymbolType, class RankType, class StateType >
+ExtendedNFTA < SymbolType, RankType, 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 input alphabet component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam RankType used for the rank part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class RankType, class StateType >
+class SetConstraint< automaton::ExtendedNFTA < 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::ExtendedNFTA < 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)
+				return true;
+
+		return false;
+	}
+
+	/**
+	 * Returns true as all symbols are possibly available to be elements of the input alphabet.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 *
+	 * \returns true
+	 */
+	static bool available ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const common::ranked_symbol < SymbolType, RankType > & ) {
+		return true;
+	}
+
+	/**
+	 * All symbols are valid as input symbols.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 */
+	static void valid ( const automaton::ExtendedNFTA < 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 symbol part of the ranked symbol
+ * \tparam RankType used for the rank part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class RankType, class StateType >
+class SetConstraint< automaton::ExtendedNFTA < 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::ExtendedNFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) {
+		if ( automaton.getFinalStates ( ).count ( state ) )
+			return true;
+
+		for ( const std::pair<const ext::pair<rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector<StateType> >, ext::set<StateType>>& t : automaton.getTransitions())
+			if(ext::contains(t.first.second.begin(), t.first.second.end(), state ) || t . second.count ( state ) )
+				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::ExtendedNFTA < 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::ExtendedNFTA < SymbolType, RankType, StateType > &, const StateType & ) {
+	}
+};
+
+/**
+ * Helper class specifying constraints for the automaton's internal final states component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam RankType used for the rank part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class RankType, class StateType >
+class SetConstraint< automaton::ExtendedNFTA < 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::ExtendedNFTA < 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::ExtendedNFTA < 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::ExtendedNFTA < SymbolType, RankType, 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 RankType, class StateType >
+struct normalize < automaton::ExtendedNFTA < SymbolType, RankType, StateType > > {
+	static automaton::ExtendedNFTA < > eval ( automaton::ExtendedNFTA < SymbolType, RankType, StateType > && value ) {
+		ext::set < common::ranked_symbol < > > alphabet = alphabet::SymbolNormalize::normalizeRankedAlphabet ( std::move ( value ).getInputAlphabet ( ) );
+		ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
+		ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
+
+		automaton::ExtendedNFTA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( finalStates ) );
+
+		for ( std::pair < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
+			rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte = transition.first.first; // TODO alphabet::SymbolNormalize::normalizeRankedSymbol ( std::move ( transition.first.first ) );
+			ext::vector < DefaultStateType > from = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.first.second ) );
+			ext::set < DefaultStateType > to = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.second ) );
+
+			res.addTransitions ( std::move ( rte ), std::move ( from ), std::move ( to ) );
+		}
+
+		return res;
+	}
+};
+
+} /* namespace core */
+
+#endif /* EXTENDED_NFTA_H_ */
-- 
GitLab