From 264de0065837707b00e6f7b65a95c07c243e0d42 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 11 Oct 2016 13:36:08 +0200
Subject: [PATCH] template DFTA automaton

---
 acompare2/src/AutomatonCompare.cpp            |   8 +-
 acompare2/src/AutomatonCompare.h              |   6 +-
 aconvert2/src/DotConverter.cpp                |   6 +-
 aconvert2/src/DotConverter.h                  |   4 +-
 aconvert2/src/GasTexConverter.cpp             |   6 +-
 aconvert2/src/GasTexConverter.h               |   4 +-
 aconvert2/src/TikZConverter.cpp               |   6 +-
 aconvert2/src/TikZConverter.h                 |   4 +-
 .../src/automaton/determinize/Determinize.cpp |   4 +-
 .../src/automaton/determinize/Determinize.h   |   4 +-
 .../determinize/DeterminizeNFTAPart.cxx       |   6 +-
 alib2algo/src/automaton/run/Accept.cpp        |   4 +-
 alib2algo/src/automaton/run/Accept.h          |   2 +-
 alib2algo/src/automaton/run/Occurrences.cpp   |   4 +-
 alib2algo/src/automaton/run/Occurrences.h     |   2 +-
 alib2algo/src/automaton/run/Result.cpp        |   4 +-
 alib2algo/src/automaton/run/Result.h          |   2 +-
 alib2algo/src/automaton/run/Run.cpp           |   4 +-
 alib2algo/src/automaton/run/Run.h             |   4 +-
 .../automaton/determinize/determinizeTest.cpp |   2 +-
 alib2data/src/automaton/AutomatonFeatures.h   |   2 +
 alib2data/src/automaton/TA/DFTA.cpp           | 145 +---------
 alib2data/src/automaton/TA/DFTA.h             | 264 ++++++++++++++----
 alib2data/src/automaton/TA/NFTA.cpp           |   2 +-
 alib2data/src/automaton/TA/NFTA.h             |   2 +-
 .../automaton/common/AutomatonFromXMLParser.h |   1 +
 .../automaton/common/AutomatonToXMLComposer.h |   1 +
 27 files changed, 261 insertions(+), 242 deletions(-)

diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp
index a8788239af..b2d48528cb 100644
--- a/acompare2/src/AutomatonCompare.cpp
+++ b/acompare2/src/AutomatonCompare.cpp
@@ -86,7 +86,7 @@ bool AutomatonCompare::testCompare(const automaton::CompactNFA < > & a, const au
 			a.getTransitions()    == b.getTransitions()    ;
 }
 
-bool AutomatonCompare::testCompare(const automaton::DFTA& a, const automaton::DFTA& b) {
+bool AutomatonCompare::testCompare(const automaton::DFTA < > & a, const automaton::DFTA < > & b) {
 	return  	a.getFinalStates()    == b.getFinalStates()    &&
 //			a.getInputAlphabet()  == b.getInputAlphabet()  &&
 			a.getStates()         == b.getStates()         &&
@@ -486,7 +486,7 @@ void AutomatonCompare::printCompare(const automaton::CompactNFA < > & a, const a
 	}
 }
 
-void AutomatonCompare::printCompare(const automaton::DFTA& a, const automaton::DFTA& b) {
+void AutomatonCompare::printCompare(const automaton::DFTA < > & a, const automaton::DFTA < > & b) {
 	std::cout << "AutomatonCompareer" << std::endl;
 
 	if(a.getFinalStates() != b.getFinalStates()){
@@ -1238,7 +1238,7 @@ int AutomatonCompare::compare(const automaton::CompactNFA < > & a, const automat
 
 auto AutomatonCompareCompactNFA = AutomatonCompare::RegistratorWrapper<int, automaton::CompactNFA < >, automaton::CompactNFA < > >(AutomatonCompare::compare);
 
-int AutomatonCompare::compare(const automaton::DFTA& a, const automaton::DFTA& b) {
+int AutomatonCompare::compare(const automaton::DFTA < > & a, const automaton::DFTA < > & b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
 	  AutomatonCompare::printCompare(a, b);
 	  return 1;
@@ -1247,7 +1247,7 @@ int AutomatonCompare::compare(const automaton::DFTA& a, const automaton::DFTA& b
 	}
 }
 
-auto AutomatonCompareDFTA = AutomatonCompare::RegistratorWrapper<int, automaton::DFTA, automaton::DFTA>(AutomatonCompare::compare);
+auto AutomatonCompareDFTA = AutomatonCompare::RegistratorWrapper<int, automaton::DFTA < >, automaton::DFTA < > >(AutomatonCompare::compare);
 
 int AutomatonCompare::compare(const automaton::NFTA& a, const automaton::NFTA& b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h
index 06ade0d1da..5f71a24885 100644
--- a/acompare2/src/AutomatonCompare.h
+++ b/acompare2/src/AutomatonCompare.h
@@ -44,8 +44,8 @@ private:
 	static bool testCompare(const automaton::NPDA < > & a, const automaton::NPDA < > & b);
 	static void printCompare(const automaton::NPDA < > & a, const automaton::NPDA < > & b);
 
-	static bool testCompare(const automaton::DFTA& a, const automaton::DFTA& b);
-	static void printCompare(const automaton::DFTA& a, const automaton::DFTA& b);
+	static bool testCompare(const automaton::DFTA < > & a, const automaton::DFTA < > & b);
+	static void printCompare(const automaton::DFTA < > & a, const automaton::DFTA < > & b);
 
 	static bool testCompare(const automaton::NFTA& a, const automaton::NFTA& b);
 	static void printCompare(const automaton::NFTA& a, const automaton::NFTA& b);
@@ -88,7 +88,7 @@ public:
 	static int compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b);
 	static int compare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b);
 
-	static int compare(const automaton::DFTA& a, const automaton::DFTA& b);
+	static int compare(const automaton::DFTA < > & a, const automaton::DFTA < > & b);
 	static int compare(const automaton::NFTA& a, const automaton::NFTA& b);
 
 	static int compare(const automaton::DPDA < > & a, const automaton::DPDA < > & b);
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index 9643cb67ab..7deeb1d51d 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -279,7 +279,7 @@ void DotConverter::convert(std::ostream& out, const automaton::NFTA& a) {
 
 auto DotConverterNFTA = DotConverter::RegistratorWrapper<void, automaton::NFTA>(DotConverter::convert);
 
-void DotConverter::convert(std::ostream& out, const automaton::DFTA& a) {
+void DotConverter::convert(std::ostream& out, const automaton::DFTA < > & a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -306,7 +306,7 @@ void DotConverter::convert(std::ostream& out, const automaton::DFTA& a) {
 	out << "}";
 }
 
-auto DotConverterDFTA = DotConverter::RegistratorWrapper<void, automaton::DFTA>(DotConverter::convert);
+auto DotConverterDFTA = DotConverter::RegistratorWrapper<void, automaton::DFTA < > >(DotConverter::convert);
 
 void DotConverter::convert(std::ostream& out, const automaton::DPDA < > & a) {
 	out << "digraph automaton {\n";
@@ -933,7 +933,7 @@ void DotConverter::transitions(const automaton::NFTA& fta, const std::map<label:
 	}
 }
 
-void DotConverter::transitions(const automaton::DFTA& fta, const std::map<label::Label, int>& states, std::ostream& out) {
+void DotConverter::transitions(const automaton::DFTA < > & fta, const std::map<label::Label, int>& states, std::ostream& out) {
 	std::map<std::pair<int, std::vector<int>>, std::string> transitions;
 
 	//put transitions from automaton to "transitions"
diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h
index 0da8c9fabd..677b4917cf 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -27,7 +27,7 @@ class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, vo
 	static void transitions(const automaton::ExtendedNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::CompactNFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::NFTA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
-	static void transitions(const automaton::DFTA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
+	static void transitions(const automaton::DFTA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::DPDA < > & pda, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::SinglePopDPDA < > & tm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::InputDrivenDPDA < > & pda, const std::map<label::Label, int>& states, std::ostream& out);
@@ -49,7 +49,7 @@ public:
 	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
 	static void convert(std::ostream& out, const automaton::CompactNFA < > & a);
 	static void convert(std::ostream& out, const automaton::NFTA& a);
-	static void convert(std::ostream& out, const automaton::DFTA& a);
+	static void convert(std::ostream& out, const automaton::DFTA < > & a);
 	static void convert(std::ostream& out, const automaton::DPDA < > & a);
 	static void convert(std::ostream& out, const automaton::SinglePopDPDA < > & a);
 	static void convert(std::ostream& out, const automaton::InputDrivenDPDA < > & a);
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index 1ec3bab7f4..984c01593a 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -290,11 +290,11 @@ void GasTexConverter::convert(std::ostream&, const automaton::NFTA&) {
 
 auto GasTexConverterNFTA = GasTexConverter::RegistratorWrapper<void, automaton::NFTA>(GasTexConverter::convert);
 
-void GasTexConverter::convert(std::ostream&, const automaton::DFTA&) {
+void GasTexConverter::convert(std::ostream&, const automaton::DFTA < > &) {
 	//TODO
 }
 
-auto GasTexConverterDFTA = GasTexConverter::RegistratorWrapper<void, automaton::DFTA>(GasTexConverter::convert);
+auto GasTexConverterDFTA = GasTexConverter::RegistratorWrapper<void, automaton::DFTA < > >(GasTexConverter::convert);
 
 void GasTexConverter::convert(std::ostream& out, const automaton::DPDA < > & a) {
 	out << "\\begin{center}\n";
@@ -911,7 +911,7 @@ void GasTexConverter::transitions(const automaton::NFTA&, std::ostream&) {
 	//TODO
 }
 
-void GasTexConverter::transitions(const automaton::DFTA&, std::ostream&) {
+void GasTexConverter::transitions(const automaton::DFTA < > &, std::ostream&) {
 	//TODO
 }
 
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index a2f95ce496..e7b6a5c2f5 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -28,7 +28,7 @@ class GasTexConverter : public std::SingleDispatchFirstStaticParam<GasTexConvert
 	static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out);
 	static void transitions(const automaton::CompactNFA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::NFTA& fsm, std::ostream& out);
-	static void transitions(const automaton::DFTA& fsm, std::ostream& out);
+	static void transitions(const automaton::DFTA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::DPDA < > & pda, std::ostream& out);
 	static void transitions(const automaton::SinglePopDPDA < > & tm, std::ostream& out);
 	static void transitions(const automaton::InputDrivenDPDA < > & pda, std::ostream& out);
@@ -50,7 +50,7 @@ public:
 	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
 	static void convert(std::ostream& out, const automaton::CompactNFA < > & a);
 	static void convert(std::ostream& out, const automaton::NFTA& a);
-	static void convert(std::ostream& out, const automaton::DFTA& a);
+	static void convert(std::ostream& out, const automaton::DFTA < > & a);
 	static void convert(std::ostream& out, const automaton::DPDA < > & a);
 	static void convert(std::ostream& out, const automaton::SinglePopDPDA < > & a);
 	static void convert(std::ostream& out, const automaton::InputDrivenDPDA < > & a);
diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp
index a077566155..b84feb154c 100644
--- a/aconvert2/src/TikZConverter.cpp
+++ b/aconvert2/src/TikZConverter.cpp
@@ -251,7 +251,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::NFTA & a ) {
 
 auto TikZConverterNFTA = TikZConverter::RegistratorWrapper < void, automaton::NFTA > ( TikZConverter::convert );
 
-void TikZConverter::convert ( std::ostream & out, const automaton::DFTA & a ) {
+void TikZConverter::convert ( std::ostream & out, const automaton::DFTA < > & a ) {
 	out << "\\begin{tikzpicture}\n";
 	int cnt = 1;
 
@@ -275,7 +275,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::DFTA & a ) {
 	out << "\\end{tikzpicture}";
 }
 
-auto TikZConverterDFTA = TikZConverter::RegistratorWrapper < void, automaton::DFTA > ( TikZConverter::convert );
+auto TikZConverterDFTA = TikZConverter::RegistratorWrapper < void, automaton::DFTA < > > ( TikZConverter::convert );
 
 void TikZConverter::convert ( std::ostream & out, const automaton::DPDA < > & a ) {
 	out << "\\begin{tikzpicture}\n";
@@ -916,7 +916,7 @@ void TikZConverter::transitions ( const automaton::NFTA & fta, const std::map <
 	}
 }
 
-void TikZConverter::transitions ( const automaton::DFTA & fta, const std::map < label::Label, int > & states, std::ostream & out ) {
+void TikZConverter::transitions ( const automaton::DFTA < > & fta, const std::map < label::Label, int > & states, std::ostream & out ) {
 	std::map < std::pair < int, std::vector < int > >, std::string > transitions;
 
 	 // put transitions from automaton to "transitions"
diff --git a/aconvert2/src/TikZConverter.h b/aconvert2/src/TikZConverter.h
index aaced9c82e..c7af7992f5 100644
--- a/aconvert2/src/TikZConverter.h
+++ b/aconvert2/src/TikZConverter.h
@@ -27,7 +27,7 @@ class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter
 	static void transitions ( const automaton::ExtendedNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::CompactNFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::NFTA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
-	static void transitions ( const automaton::DFTA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
+	static void transitions ( const automaton::DFTA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::DPDA < > & pda, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::SinglePopDPDA < > & tm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::InputDrivenDPDA < > & pda, const std::map < label::Label, int > & states, std::ostream & out );
@@ -50,7 +50,7 @@ public:
 	static void convert ( std::ostream & out, const automaton::ExtendedNFA & a );
 	static void convert ( std::ostream & out, const automaton::CompactNFA < > & a );
 	static void convert ( std::ostream & out, const automaton::NFTA & a );
-	static void convert ( std::ostream & out, const automaton::DFTA & a );
+	static void convert ( std::ostream & out, const automaton::DFTA < > & a );
 	static void convert ( std::ostream & out, const automaton::DPDA < > & a );
 	static void convert ( std::ostream & out, const automaton::SinglePopDPDA < > & a );
 	static void convert ( std::ostream & out, const automaton::InputDrivenDPDA < > & a );
diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
index 964c4eef10..90ac800af5 100644
--- a/alib2algo/src/automaton/determinize/Determinize.cpp
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -79,11 +79,11 @@ OneTapeDTM<> Determinize::determinize(const automaton::OneTapeDTM<>& automaton)
 
 auto DeterminizeOneTapeDTM = Determinize::RegistratorWrapper<automaton::OneTapeDTM<>, automaton::OneTapeDTM<>>(Determinize::determinize);
 
-DFTA Determinize::determinize(const automaton::DFTA& automaton) {
+DFTA < > Determinize::determinize(const automaton::DFTA < > & automaton) {
 	return automaton;
 }
 
-auto DeterminizeDFTA = Determinize::RegistratorWrapper<automaton::DFTA, automaton::DFTA>(Determinize::determinize);
+auto DeterminizeDFTA = Determinize::RegistratorWrapper<automaton::DFTA < >, automaton::DFTA < > >(Determinize::determinize);
 
 } /* namespace determinize */
 
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index f94567166b..1c965d883c 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -43,8 +43,8 @@ public:
 	static automaton::InputDrivenDPDA < > determinize(const automaton::InputDrivenNPDA < > & nfa);
 	static automaton::RealTimeHeightDeterministicDPDA < > determinize(const automaton::RealTimeHeightDeterministicDPDA < > & nondeterministic);
 	static automaton::RealTimeHeightDeterministicDPDA < > determinize(const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic);
-	static automaton::DFTA determinize(const automaton::DFTA& nfta);
-	static automaton::DFTA determinize(const automaton::NFTA& nfta);
+	static automaton::DFTA < > determinize(const automaton::DFTA < > & nfta);
+	static automaton::DFTA < > determinize(const automaton::NFTA& nfta);
 
 	static automaton::OneTapeDTM<> determinize(const automaton::OneTapeDTM<>& nfta);
 };
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
index 56e18a010b..9c01466106 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
@@ -29,8 +29,8 @@ std::set<label::Label> getTransitionRightSide(const NFTA & nfta, const std::rank
 	return res;
 }
 
-DFTA Determinize::determinize(const NFTA & nfta) {
-	DFTA res;
+DFTA < > Determinize::determinize(const NFTA & nfta) {
+	DFTA < > res;
 	res.setInputAlphabet(nfta.getInputAlphabet());
 	for (const auto & state : nfta.getStates()) res.addState(createDFAState({state}));
 	for (const auto & state : nfta.getFinalStates()) res.addFinalState(createDFAState({state}));
@@ -94,7 +94,7 @@ DFTA Determinize::determinize(const NFTA & nfta) {
 	return res;
 }
 
-auto DeterminizeNFTA = Determinize::RegistratorWrapper<automaton::DFTA, automaton::NFTA>( Determinize::determinize );
+auto DeterminizeNFTA = Determinize::RegistratorWrapper<automaton::DFTA < >, automaton::NFTA>( Determinize::determinize );
 
 } /* namespace determinize */
 
diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp
index b99ad5b730..66542ffede 100644
--- a/alib2algo/src/automaton/run/Accept.cpp
+++ b/alib2algo/src/automaton/run/Accept.cpp
@@ -55,13 +55,13 @@ bool Accept::accept ( const automaton::NFA < > & automaton, const string::Linear
 
 auto AcceptNFALinearString = Accept::RegistratorWrapper < bool, automaton::NFA < > , string::LinearString < > > ( Accept::accept );
 
-bool Accept::accept ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree ) {
+bool Accept::accept ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree );
 
 	return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) );
 }
 
-auto AcceptDFTARankedTree = Accept::RegistratorWrapper < bool, automaton::DFTA, tree::RankedTree < > > ( Accept::accept );
+auto AcceptDFTARankedTree = Accept::RegistratorWrapper < bool, automaton::DFTA < >, tree::RankedTree < > > ( Accept::accept );
 
 bool Accept::accept ( const automaton::NFTA & automaton, const tree::RankedTree < > & tree ) {
 	std::tuple < bool, std::set < label::Label >, std::set < unsigned > > res = Run::calculateStates ( automaton, tree );
diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h
index 7f0e03ffb8..0bfd062abc 100644
--- a/alib2algo/src/automaton/run/Accept.h
+++ b/alib2algo/src/automaton/run/Accept.h
@@ -31,7 +31,7 @@ public:
 
 	static bool accept ( const automaton::DFA<> & automaton, const string::LinearString < > & string );
 	static bool accept ( const automaton::NFA < > & automaton, const string::LinearString < > & string );
-	static bool accept ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree );
+	static bool accept ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree );
 	static bool accept ( const automaton::NFTA & automaton, const tree::RankedTree < > & tree );
 	static bool accept ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string );
 	static bool accept ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string );
diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp
index 040ed70a9b..a3b38aa6fa 100644
--- a/alib2algo/src/automaton/run/Occurrences.cpp
+++ b/alib2algo/src/automaton/run/Occurrences.cpp
@@ -41,13 +41,13 @@ std::set < unsigned > Occurrences::occurrences ( const automaton::DFA < > & auto
 
 auto OccurrencesDFALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFA<>, string::LinearString < > > ( Occurrences::occurrences );
 
-std::set < unsigned > Occurrences::occurrences ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree ) {
+std::set < unsigned > Occurrences::occurrences ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree );
 
 	return std::get < 2 > ( res );
 }
 
-auto OccurrencesDFTARankedTree = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFTA, tree::RankedTree < > > ( Occurrences::occurrences );
+auto OccurrencesDFTARankedTree = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFTA < >, tree::RankedTree < > > ( Occurrences::occurrences );
 
 std::set < unsigned > Occurrences::occurrences ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ) {
 	std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string );
diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h
index 339e62386c..ba6db00688 100644
--- a/alib2algo/src/automaton/run/Occurrences.h
+++ b/alib2algo/src/automaton/run/Occurrences.h
@@ -30,7 +30,7 @@ public:
 	static std::set < unsigned > occurrences ( const automaton::Automaton & automaton, const tree::RankedTree < > & string );
 
 	static std::set < unsigned > occurrences ( const automaton::DFA<> & automaton, const string::LinearString < > & string );
-	static std::set < unsigned > occurrences ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree );
+	static std::set < unsigned > occurrences ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree );
 	static std::set < unsigned > occurrences ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string );
 	static std::set < unsigned > occurrences ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string );
 	static std::set < unsigned > occurrences ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string );
diff --git a/alib2algo/src/automaton/run/Result.cpp b/alib2algo/src/automaton/run/Result.cpp
index c5062d325f..e91d7be414 100644
--- a/alib2algo/src/automaton/run/Result.cpp
+++ b/alib2algo/src/automaton/run/Result.cpp
@@ -35,7 +35,7 @@ label::Label Result::result ( const automaton::DFA < > & automaton, const string
 
 auto ResultDFALinearString = Result::RegistratorWrapper < label::Label, automaton::DFA<>, string::LinearString < > > ( Result::result );
 
-label::Label Result::result ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel ) {
+label::Label Result::result ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree );
 
 	if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res );
@@ -43,7 +43,7 @@ label::Label Result::result ( const automaton::DFTA & automaton, const tree::Ran
 	return failLabel;
 }
 
-auto ResultDFTARankedTree = Result::RegistratorWrapper < label::Label, automaton::DFTA, tree::RankedTree < > > ( Result::result );
+auto ResultDFTARankedTree = Result::RegistratorWrapper < label::Label, automaton::DFTA < >, tree::RankedTree < > > ( Result::result );
 
 label::Label Result::result ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) {
 	std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string );
diff --git a/alib2algo/src/automaton/run/Result.h b/alib2algo/src/automaton/run/Result.h
index bb8d82b0c7..81761062fa 100644
--- a/alib2algo/src/automaton/run/Result.h
+++ b/alib2algo/src/automaton/run/Result.h
@@ -30,7 +30,7 @@ public:
 	static label::Label result ( const automaton::Automaton & automaton, const alib::Object & object, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 
 	static label::Label result ( const automaton::DFA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
-	static label::Label result ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
+	static label::Label result ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp
index d6d766ce98..8324dc0f5b 100644
--- a/alib2algo/src/automaton/run/Run.cpp
+++ b/alib2algo/src/automaton/run/Run.cpp
@@ -106,7 +106,7 @@ std::tuple < bool, std::set < label::Label >, std::set < unsigned > > Run::calcu
 
 // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-std::pair < bool, label::Label > Run::calculateState ( const automaton::DFTA & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ) {
+std::pair < bool, label::Label > Run::calculateState ( const automaton::DFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ) {
 	std::vector < label::Label > states;
 
 	states.reserve ( node.getData ( ).getRank ( ).getData ( ) );
@@ -141,7 +141,7 @@ std::pair < bool, label::Label > Run::calculateState ( const automaton::DFTA & a
 	return std::make_pair ( true, state );
 }
 
-std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree ) {
+std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) {
 	std::set < unsigned > occ;
 	unsigned i = 0;
 	std::pair < bool, label::Label > res = calculateState ( automaton, tree.getContent ( ), occ, i );
diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h
index 6891170c62..733bd5f990 100644
--- a/alib2algo/src/automaton/run/Run.h
+++ b/alib2algo/src/automaton/run/Run.h
@@ -20,14 +20,14 @@ namespace automaton {
 namespace run {
 
 class Run {
-	static std::pair < bool, label::Label > calculateState ( const automaton::DFTA & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i );
+	static std::pair < bool, label::Label > calculateState ( const automaton::DFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i );
 	static std::pair < bool, std::set < label::Label > > calculateStates ( const automaton::NFTA & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i );
 	static bool canPop ( const std::deque < alphabet::Symbol > & pushdownStore, const std::vector < alphabet::Symbol > & pop );
 
 public:
 	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFA < > & automaton, const string::LinearString < > & string );
 	static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFA < > & automaton, const string::LinearString < > & string );
-	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFTA & automaton, const tree::RankedTree < > & tree );
+	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree );
 	static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFTA & automaton, const tree::RankedTree < > & tree );
 	static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string );
 	static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string );
diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
index 37332bf8bf..d287a5ac15 100644
--- a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
@@ -133,7 +133,7 @@ void determinizeTest::testDeterminizeNFTA() {
   automaton.addFinalState(label::labelFrom(3));
 
 
-  automaton::DFTA determinized = automaton::determinize::Determinize::determinize(automaton);
+  automaton::DFTA < > determinized = automaton::determinize::Determinize::determinize(automaton);
 
   CPPUNIT_ASSERT(determinized.getStates().size() == 5);
   CPPUNIT_ASSERT(determinized.getFinalStates().size() == 3);
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index c477ae0380..78ac7c9093 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -11,6 +11,7 @@
 #include <alphabet/Symbol.h>
 #include <label/Label.h>
 #include <string/Epsilon.h>
+#include <primitive/Unsigned.h>
 
 namespace automaton {
 
@@ -75,6 +76,7 @@ template<class SymbolType = typename alphabet::Symbol, class EpsilonType = typen
 class SinglePopNPDA;
 template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class OneTapeDTM;
+template<class SymbolType = typename alphabet::Symbol, class RankType = primitive::Unsigned, class StateType = typename label::Label >
 class DFTA;
 class NFTA;
 
diff --git a/alib2data/src/automaton/TA/DFTA.cpp b/alib2data/src/automaton/TA/DFTA.cpp
index 9c7148b193..2c670f4c28 100644
--- a/alib2data/src/automaton/TA/DFTA.cpp
+++ b/alib2data/src/automaton/TA/DFTA.cpp
@@ -6,154 +6,13 @@
  */
 
 #include "DFTA.h"
-#include <ostream>
-#include <sstream>
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/AutomatonFromXMLParser.h"
-#include "../common/AutomatonToXMLComposer.h"
 #include "../Automaton.h"
 #include <object/Object.h>
 #include <core/xmlApi.hpp>
 
-namespace automaton {
-
-DFTA::DFTA ( std::set < label::Label > states, std::set < std::ranked_symbol < > > inputAlphabet, std::set < label::Label > finalStates ) : std::Components < DFTA, std::ranked_symbol < >, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::tuple < > ( ) ) {
-}
-
-DFTA::DFTA() : DFTA ( std::set < label::Label > { }, std::set < std::ranked_symbol < > > { }, std::set < label::Label > { } ) {
-}
-
-AutomatonBase* DFTA::clone() const {
-	return new DFTA(*this);
-}
-
-AutomatonBase* DFTA::plunder() && {
-	return new DFTA(std::move(*this));
-}
-
-bool DFTA::addTransition(const std::ranked_symbol < > & symbol, const std::vector<label::Label> & prevStates, const label::Label & next) {
-	if ( prevStates.size() != symbol.getRank().getData())
-		throw AutomatonException("Number of states doesn't match rank of the symbol");
-
-	if (! getInputAlphabet().count(symbol))
-		throw AutomatonException("Input symbol \"" + std::to_string ( symbol ) + "\" doesn't exist.");
-
-	if (! getStates().count(next))
-		throw AutomatonException("State \"" + std::to_string ( next ) + "\" doesn't exist.");
-
-	for (const label::Label& it : prevStates) {
-		if (! getStates().count(it))
-			throw AutomatonException("State \"" + std::to_string ( it ) + "\" doesn't exist.");
-	}
-
-	std::pair<std::ranked_symbol < >, std::vector<label::Label> > key = std::make_pair(symbol, prevStates);
-	if ( transitions.find ( key ) != transitions.end ( ) ) {
-		if ( transitions.find ( key )->second == next )
-			return false;
-		else
-			throw AutomatonException("Transition already exists");
-	}
-
-	transitions.insert(std::make_pair(key, next));
-	return true;
-}
-
-bool DFTA::removeTransition(const std::ranked_symbol < > symbol, const std::vector<label::Label> & states, const label::Label & next) {
-	std::pair<std::ranked_symbol < >, std::vector<label::Label> > key = std::make_pair(symbol, states);
-
-	if ( transitions.find ( key ) == transitions.end ( ) )
-		return false;
-
-	if ( transitions.find ( key )->second != next )
-		throw AutomatonException("Transition does not exist");
-
-	transitions.erase(key);
-	return true;
-}
-
-int DFTA::compare(const DFTA& other) const {
-	auto first = std::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions);
-	auto second = std::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
-
-	std::compare<decltype(first)> comp;
-	return comp(first, second);
-}
-
-void DFTA::operator>>(std::ostream& out) const {
-	out << "(DFTA "
-		<< " states = " << getStates()
-		<< " inputAlphabet = " << getInputAlphabet()
-		<< " finalStates = " << getFinalStates()
-		<< " transitions = " << transitions
-		<< ")";
-}
-
-DFTA::operator std::string () const {
-	std::stringstream ss;
-	ss << *this;
-	return ss.str();
-}
-
-DFTA DFTA::parse(std::deque<sax::Token>::iterator& input) {
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, DFTA::getXmlTagName());
-
-	std::set<label::Label> states = AutomatonFromXMLParser::parseStates<label::Label>(input);
-	std::set<std::ranked_symbol < >> inputSymbols = AutomatonFromXMLParser::parseRankedInputAlphabet<std::ranked_symbol < >>(input);
-	std::set<label::Label> finalStates = AutomatonFromXMLParser::parseFinalStates<label::Label>(input);
-
-	DFTA automaton;
-	automaton.setStates(std::move(states));
-	automaton.setInputAlphabet(std::move(inputSymbols));
-	automaton.setFinalStates(std::move(finalStates));
-
-	AutomatonFromXMLParser::parseTransitions<DFTA>(input, automaton);
-
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, DFTA::getXmlTagName());
-	return automaton;
-}
-
-void DFTA::parseTransition(std::deque<sax::Token>::iterator& input, DFTA& automaton) {
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, "transition");
-	std::ranked_symbol < > inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol<std::ranked_symbol < >>(input);
-	std::vector<label::Label> from = AutomatonFromXMLParser::parseTransitionFromMultiple<label::Label>(input);
-	label::Label to = AutomatonFromXMLParser::parseTransitionTo<label::Label>(input);
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transition");
-
-	automaton.addTransition(std::move(inputSymbol), std::move(from), std::move(to));
-}
-
-void DFTA::compose(std::deque<sax::Token>& out) const {
-	out.emplace_back(DFTA::getXmlTagName(), sax::Token::TokenType::START_ELEMENT);
-
-	AutomatonToXMLComposer::composeStates(out, this->getStates());
-	AutomatonToXMLComposer::composeRankedInputAlphabet(out, this->getInputAlphabet());
-	AutomatonToXMLComposer::composeFinalStates(out, this->getFinalStates());
-	composeTransitions(out);
-
-	out.emplace_back(DFTA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT);
-}
-
-void DFTA::composeTransitions(std::deque<sax::Token>& out) const {
-	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
-	for(const auto& transition : this->getTransitions()) {
-		out.emplace_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT));
-
-		AutomatonToXMLComposer::composeTransitionInputSymbol(out, transition.first.first);
-		AutomatonToXMLComposer::composeTransitionFrom(out, transition.first.second);
-		AutomatonToXMLComposer::composeTransitionTo(out, transition.second);
-
-		out.emplace_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT));
-	}
-
-	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
-}
-
-} /* namespace automaton */
-
 namespace alib {
 
-auto DFTAParserRegister = xmlApi<automaton::Automaton>::ParserRegister<automaton::DFTA>();
-auto DFTAParserRegister2 = xmlApi<alib::Object>::ParserRegister<automaton::DFTA>();
+auto DFTAParserRegister = xmlApi<automaton::Automaton>::ParserRegister<automaton::DFTA < > >();
+auto DFTAParserRegister2 = xmlApi<alib::Object>::ParserRegister<automaton::DFTA < > >();
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/TA/DFTA.h b/alib2data/src/automaton/TA/DFTA.h
index 6654f42156..35cb5d5af0 100644
--- a/alib2data/src/automaton/TA/DFTA.h
+++ b/alib2data/src/automaton/TA/DFTA.h
@@ -8,13 +8,20 @@
 #ifndef DFTA_H_
 #define DFTA_H_
 
-#include "../AutomatonException.h"
 #include <map>
 #include <vector>
+#include <ostream>
+#include <sstream>
+
 #include <core/components.hpp>
+#include <sax/FromXMLParserHelper.h>
+#include "alphabet/ranked_symbol.hpp"
+
+#include "../AutomatonFeatures.h"
+#include "../AutomatonException.h"
 #include "../AutomatonBase.h"
-#include "../../alphabet/RankedSymbol.h"
-#include "../../label/Label.h"
+#include "../common/AutomatonFromXMLParser.h"
+#include "../common/AutomatonToXMLComposer.h"
 
 namespace automaton {
 
@@ -26,67 +33,68 @@ class FinalStates;
  * Represents Finite Tree Automaton.
  * Can store nondeterministic finite automaton without epsilon transitions.
  */
-class DFTA : public AutomatonBase, public std::Components < DFTA, std::ranked_symbol < >, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < > > {
-	std::map < std::pair < std::ranked_symbol < >, std::vector < label::Label > >, label::Label > transitions;
+template<class SymbolType, class RankType, class StateType >
+class DFTA : public AutomatonBase, public std::Components < DFTA < SymbolType, RankType, StateType >, std::ranked_symbol < SymbolType, RankType >, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < > > {
+	std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < StateType > >, StateType > transitions;
 
 public:
 	explicit DFTA ( );
-	explicit DFTA ( std::set < label::Label > states, std::set < std::ranked_symbol < > > inputAlphabet, std::set < label::Label > finalStates );
+	explicit DFTA ( std::set < StateType > states, std::set < std::ranked_symbol < SymbolType, RankType > > inputAlphabet, std::set < StateType > finalStates );
 
 	virtual AutomatonBase * clone ( ) const;
 
 	virtual AutomatonBase * plunder ( ) &&;
 
-	const std::set < label::Label > & getStates ( ) const {
-		return accessComponent < States > ( ).get ( );
+	const std::set < StateType > & getStates ( ) const {
+		return this->template accessComponent < States > ( ).get ( );
 	}
 
-	bool addState ( label::Label state ) {
-		return accessComponent < States > ( ).add ( std::move ( state ) );
+	bool addState ( StateType state ) {
+		return this->template accessComponent < States > ( ).add ( std::move ( state ) );
 	}
 
-	void setStates ( std::set < label::Label > states ) {
-		accessComponent < States > ( ).set ( std::move ( states ) );
+	void setStates ( std::set < StateType > states ) {
+		this->template accessComponent < States > ( ).set ( std::move ( states ) );
 	}
 
-	void removeState ( const label::Label & state ) {
-		accessComponent < States > ( ).remove ( state );
+	void removeState ( const StateType & state ) {
+		this->template accessComponent < States > ( ).remove ( state );
 	}
 
-	const std::set < label::Label > & getFinalStates ( ) const {
-		return accessComponent < FinalStates > ( ).get ( );
+	const std::set < StateType > & getFinalStates ( ) const {
+		return this->template accessComponent < FinalStates > ( ).get ( );
 	}
 
-	bool addFinalState ( label::Label state ) {
-		return accessComponent < FinalStates > ( ).add ( std::move ( state ) );
+	bool addFinalState ( StateType state ) {
+		return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
 	}
 
-	void setFinalStates ( std::set < label::Label > states ) {
-		accessComponent < FinalStates > ( ).set ( std::move ( states ) );
+	void setFinalStates ( std::set < StateType > states ) {
+		this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
 	}
 
-	void removeFinalState ( const label::Label & state ) {
-		accessComponent < FinalStates > ( ).remove ( state );
+	void removeFinalState ( const StateType & state ) {
+		this->template accessComponent < FinalStates > ( ).remove ( state );
 	}
 
-	const std::set < std::ranked_symbol < > > & getInputAlphabet ( ) const {
-		return accessComponent < InputAlphabet > ( ).get ( );
+	const std::set < std::ranked_symbol < SymbolType, RankType > > & getInputAlphabet ( ) const {
+		return this->template accessComponent < InputAlphabet > ( ).get ( );
 	}
 
-	bool addInputSymbol ( std::ranked_symbol < > symbol ) {
-		return accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
+	bool addInputSymbol ( std::ranked_symbol < SymbolType, RankType > symbol ) {
+		return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
 	}
 
-	void addInputSymbols ( std::set < std::ranked_symbol < > > symbols ) {
-		accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
+	void addInputSymbols ( std::set < std::ranked_symbol < SymbolType, RankType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
 	}
 
-	void setInputAlphabet ( std::set < std::ranked_symbol < > > symbols ) {
-		accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
+	void setInputAlphabet ( std::set < std::ranked_symbol < SymbolType, RankType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
 	}
 
-	void removeInputSymbol ( const std::ranked_symbol < > & symbol ) {
-		accessComponent < InputAlphabet > ( ).remove ( symbol );
+	void removeInputSymbol ( const std::ranked_symbol < SymbolType, RankType > & symbol ) {
+		this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
 	}
 
 	/**
@@ -96,20 +104,20 @@ public:
 	 * @param next next state
 	 * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton
 	 */
-	bool addTransition ( const std::ranked_symbol < > & current, const std::vector < label::Label > & children, const label::Label & next );
+	bool addTransition ( const std::ranked_symbol < SymbolType, RankType > & current, const std::vector < StateType > & children, const StateType & next );
 
 	/**
 	 * Removes transition from the automaton.
 	 * @throws AutomatonException when transition doesn't exists.
 	 */
-	bool removeTransition ( const std::ranked_symbol < > symbol, const std::vector < label::Label > & states, const label::Label & next );
+	bool removeTransition ( const std::ranked_symbol < SymbolType, RankType > symbol, const std::vector < StateType > & states, const StateType & next );
 
 	/**
 	 * @return automaton transitions
 	 */
-	const std::map < std::pair < std::ranked_symbol < >, std::vector < label::Label > >, label::Label > & getTransitions ( ) const { return transitions; }
+	const std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < StateType > >, StateType > & getTransitions ( ) const { return transitions; }
 
-	std::set < label::Label > getTransitionRightSide ( const std::ranked_symbol < > symbol, const std::vector < label::Label > & states );
+	std::set < StateType > getTransitionRightSide ( const std::ranked_symbol < SymbolType, RankType > symbol, const std::vector < StateType > & states );
 
 	unsigned transitionsSize ( ) const;
 
@@ -140,61 +148,209 @@ public:
 
 } /* namespace automaton */
 
+namespace automaton {
+
+template<class SymbolType, class RankType, class StateType >
+DFTA < SymbolType, RankType, StateType >::DFTA ( std::set < StateType > states, std::set < std::ranked_symbol < SymbolType, RankType > > inputAlphabet, std::set < StateType > finalStates ) : std::Components < DFTA, std::ranked_symbol < SymbolType, RankType >, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::tuple < > ( ) ) {
+}
+
+template<class SymbolType, class RankType, class StateType >
+DFTA < SymbolType, RankType, StateType >::DFTA() : DFTA ( std::set < StateType > { }, std::set < std::ranked_symbol < SymbolType, RankType > > { }, std::set < StateType > { } ) {
+}
+
+template<class SymbolType, class RankType, class StateType >
+AutomatonBase* DFTA < SymbolType, RankType, StateType >::clone() const {
+	return new DFTA(*this);
+}
+
+template<class SymbolType, class RankType, class StateType >
+AutomatonBase* DFTA < SymbolType, RankType, StateType >::plunder() && {
+	return new DFTA(std::move(*this));
+}
+
+template<class SymbolType, class RankType, class StateType >
+bool DFTA < SymbolType, RankType, StateType >::addTransition(const std::ranked_symbol < SymbolType, RankType > & symbol, const std::vector<StateType> & prevStates, const StateType & next) {
+	if ( prevStates.size() != symbol.getRank().getData())
+		throw AutomatonException("Number of states doesn't match rank of the symbol");
+
+	if (! getInputAlphabet().count(symbol))
+		throw AutomatonException("Input symbol \"" + std::to_string ( symbol ) + "\" doesn't exist.");
+
+	if (! getStates().count(next))
+		throw AutomatonException("State \"" + std::to_string ( next ) + "\" doesn't exist.");
+
+	for (const StateType& it : prevStates) {
+		if (! getStates().count(it))
+			throw AutomatonException("State \"" + std::to_string ( it ) + "\" doesn't exist.");
+	}
+
+	std::pair<std::ranked_symbol < SymbolType, RankType >, std::vector<StateType> > key = std::make_pair(symbol, prevStates);
+	if ( transitions.find ( key ) != transitions.end ( ) ) {
+		if ( transitions.find ( key )->second == next )
+			return false;
+		else
+			throw AutomatonException("Transition already exists");
+	}
+
+	transitions.insert(std::make_pair(key, next));
+	return true;
+}
+
+template<class SymbolType, class RankType, class StateType >
+bool DFTA < SymbolType, RankType, StateType >::removeTransition(const std::ranked_symbol < SymbolType, RankType > symbol, const std::vector<StateType> & states, const StateType & next) {
+	std::pair<std::ranked_symbol < SymbolType, RankType >, std::vector<StateType> > key = std::make_pair(symbol, states);
+
+	if ( transitions.find ( key ) == transitions.end ( ) )
+		return false;
+
+	if ( transitions.find ( key )->second != next )
+		throw AutomatonException("Transition does not exist");
+
+	transitions.erase(key);
+	return true;
+}
+
+template<class SymbolType, class RankType, class StateType >
+int DFTA < SymbolType, RankType, StateType >::compare(const DFTA& other) const {
+	auto first = std::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions);
+	auto second = std::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
+
+	std::compare<decltype(first)> comp;
+	return comp(first, second);
+}
+
+template<class SymbolType, class RankType, class StateType >
+void DFTA < SymbolType, RankType, StateType >::operator>>(std::ostream& out) const {
+	out << "(DFTA "
+		<< " states = " << getStates()
+		<< " inputAlphabet = " << getInputAlphabet()
+		<< " finalStates = " << getFinalStates()
+		<< " transitions = " << transitions
+		<< ")";
+}
+
+template<class SymbolType, class RankType, class StateType >
+DFTA < SymbolType, RankType, StateType >::operator std::string () const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+template<class SymbolType, class RankType, class StateType >
+DFTA < SymbolType, RankType, StateType > DFTA < SymbolType, RankType, StateType >::parse(std::deque<sax::Token>::iterator& input) {
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, DFTA::getXmlTagName());
+
+	std::set<StateType> states = AutomatonFromXMLParser::parseStates<StateType>(input);
+	std::set<std::ranked_symbol < SymbolType, RankType >> inputSymbols = AutomatonFromXMLParser::parseRankedInputAlphabet<std::ranked_symbol < SymbolType, RankType >>(input);
+	std::set<StateType> finalStates = AutomatonFromXMLParser::parseFinalStates<StateType>(input);
+
+	DFTA < SymbolType, RankType, StateType > automaton;
+	automaton.setStates(std::move(states));
+	automaton.setInputAlphabet(std::move(inputSymbols));
+	automaton.setFinalStates(std::move(finalStates));
+
+	AutomatonFromXMLParser::parseTransitions<DFTA>(input, automaton);
+
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, DFTA::getXmlTagName());
+	return automaton;
+}
+
+template<class SymbolType, class RankType, class StateType >
+void DFTA < SymbolType, RankType, StateType >::parseTransition(std::deque<sax::Token>::iterator& input, DFTA& automaton) {
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, "transition");
+	std::ranked_symbol < SymbolType, RankType > inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol<std::ranked_symbol < SymbolType, RankType >>(input);
+	std::vector<StateType> from = AutomatonFromXMLParser::parseTransitionFromMultiple<StateType>(input);
+	StateType to = AutomatonFromXMLParser::parseTransitionTo<StateType>(input);
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transition");
+
+	automaton.addTransition(std::move(inputSymbol), std::move(from), std::move(to));
+}
+
+template<class SymbolType, class RankType, class StateType >
+void DFTA < SymbolType, RankType, StateType >::compose(std::deque<sax::Token>& out) const {
+	out.emplace_back(DFTA::getXmlTagName(), sax::Token::TokenType::START_ELEMENT);
+
+	AutomatonToXMLComposer::composeStates(out, this->getStates());
+	AutomatonToXMLComposer::composeRankedInputAlphabet(out, this->getInputAlphabet());
+	AutomatonToXMLComposer::composeFinalStates(out, this->getFinalStates());
+	composeTransitions(out);
+
+	out.emplace_back(DFTA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT);
+}
+
+template<class SymbolType, class RankType, class StateType >
+void DFTA < SymbolType, RankType, StateType >::composeTransitions(std::deque<sax::Token>& out) const {
+	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
+	for(const auto& transition : this->getTransitions()) {
+		out.emplace_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT));
+
+		AutomatonToXMLComposer::composeTransitionInputSymbol(out, transition.first.first);
+		AutomatonToXMLComposer::composeTransitionFrom(out, transition.first.second);
+		AutomatonToXMLComposer::composeTransitionTo(out, transition.second);
+
+		out.emplace_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT));
+	}
+
+	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
+}
+
+} /* namespace automaton */
+
 namespace std {
 
-template < >
-class ComponentConstraint< automaton::DFTA, std::ranked_symbol < >, automaton::InputAlphabet > {
+template<class SymbolType, class RankType, class StateType >
+class ComponentConstraint< automaton::DFTA < SymbolType, RankType, StateType >, std::ranked_symbol < SymbolType, RankType >, automaton::InputAlphabet > {
 public:
-	static bool used ( const automaton::DFTA & automaton, const std::ranked_symbol < > & symbol ) {
-		for (const std::pair<const std::pair<std::ranked_symbol < >, std::vector<label::Label> >, label::Label>& t : automaton.getTransitions())
+	static bool used ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const std::ranked_symbol < SymbolType, RankType > & symbol ) {
+		for (const std::pair<const std::pair<std::ranked_symbol < SymbolType, RankType >, std::vector<StateType> >, StateType>& t : automaton.getTransitions())
 			if (t.first.first == symbol)
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::DFTA &, const std::ranked_symbol < > & ) {
+	static bool available ( const automaton::DFTA < SymbolType, RankType, StateType > &, const std::ranked_symbol < SymbolType, RankType > & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::DFTA &, const std::ranked_symbol < > & ) {
+	static void valid ( const automaton::DFTA < SymbolType, RankType, StateType > &, const std::ranked_symbol < SymbolType, RankType > & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::DFTA, label::Label, automaton::States > {
+template<class SymbolType, class RankType, class StateType >
+class ComponentConstraint< automaton::DFTA < SymbolType, RankType, StateType >, StateType, automaton::States > {
 public:
-	static bool used ( const automaton::DFTA & automaton, const label::Label & state ) {
+	static bool used ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) {
 		if ( automaton.getFinalStates ( ).count ( state ) )
 			return true;
 
-		for (const std::pair<const std::pair<std::ranked_symbol < >, std::vector<label::Label> >, label::Label>& t : automaton.getTransitions())
+		for (const std::pair<const std::pair<std::ranked_symbol < SymbolType, RankType >, std::vector<StateType> >, StateType>& t : automaton.getTransitions())
 			if(std::contains(t.first.second.begin(), t.first.second.end(), state ) || t.second == state)
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::DFTA &, const label::Label & ) {
+	static bool available ( const automaton::DFTA < SymbolType, RankType, StateType > &, const StateType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::DFTA &, const label::Label & ) {
+	static void valid ( const automaton::DFTA < SymbolType, RankType, StateType > &, const StateType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::DFTA, label::Label, automaton::FinalStates > {
+template<class SymbolType, class RankType, class StateType >
+class ComponentConstraint< automaton::DFTA < SymbolType, RankType, StateType >, StateType, automaton::FinalStates > {
 public:
-	static bool used ( const automaton::DFTA &, const label::Label & ) {
+	static bool used ( const automaton::DFTA < SymbolType, RankType, StateType > &, const StateType & ) {
 		return false;
 	}
 
-	static bool available ( const automaton::DFTA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
 	}
 
-	static void valid ( const automaton::DFTA &, const label::Label & ) {
+	static void valid ( const automaton::DFTA < SymbolType, RankType, StateType > &, const StateType & ) {
 	}
 };
 
diff --git a/alib2data/src/automaton/TA/NFTA.cpp b/alib2data/src/automaton/TA/NFTA.cpp
index ef1ee87adf..77f0881fc3 100644
--- a/alib2data/src/automaton/TA/NFTA.cpp
+++ b/alib2data/src/automaton/TA/NFTA.cpp
@@ -24,7 +24,7 @@ NFTA::NFTA ( std::set < label::Label > states, std::set < std::ranked_symbol < >
 NFTA::NFTA() : NFTA ( std::set < label::Label > { }, std::set < std::ranked_symbol < > > { }, std::set < label::Label > { } ) {
 }
 
-NFTA::NFTA(const DFTA& other) : NFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) {
+NFTA::NFTA(const DFTA < > & other) : NFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) {
 	for(const auto& transition : other.getTransitions()) {
 		transitions[transition.first].insert(transition.second);
 	}
diff --git a/alib2data/src/automaton/TA/NFTA.h b/alib2data/src/automaton/TA/NFTA.h
index f71813065e..ec34d49bc8 100644
--- a/alib2data/src/automaton/TA/NFTA.h
+++ b/alib2data/src/automaton/TA/NFTA.h
@@ -34,7 +34,7 @@ class NFTA : public AutomatonBase, public std::Components < NFTA, std::ranked_sy
 public:
 	explicit NFTA ( );
 	explicit NFTA ( std::set < label::Label > states, std::set < std::ranked_symbol < > > inputAlphabet, std::set < label::Label > finalStates );
-	explicit NFTA ( const DFTA & other );
+	explicit NFTA ( const DFTA < > & other );
 
 	virtual AutomatonBase * clone ( ) const;
 
diff --git a/alib2data/src/automaton/common/AutomatonFromXMLParser.h b/alib2data/src/automaton/common/AutomatonFromXMLParser.h
index b9a73c61dc..779148d498 100644
--- a/alib2data/src/automaton/common/AutomatonFromXMLParser.h
+++ b/alib2data/src/automaton/common/AutomatonFromXMLParser.h
@@ -16,6 +16,7 @@
 #include "Shift.h"
 #include <core/xmlApi.hpp>
 #include "../../regexp/RegExpFeatures.h"
+#include <alphabet/RankedSymbol.h>
 
 namespace automaton {
 
diff --git a/alib2data/src/automaton/common/AutomatonToXMLComposer.h b/alib2data/src/automaton/common/AutomatonToXMLComposer.h
index 539ad58553..c6b551ceea 100644
--- a/alib2data/src/automaton/common/AutomatonToXMLComposer.h
+++ b/alib2data/src/automaton/common/AutomatonToXMLComposer.h
@@ -17,6 +17,7 @@
 #include <sax/Token.h>
 #include <core/xmlApi.hpp>
 #include "../../regexp/RegExpFeatures.h"
+#include <alphabet/RankedSymbol.h>
 
 namespace automaton {
 
-- 
GitLab