diff --git a/alib2algo/src/automaton/simplify/Minimize.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp
index 7cd64184fe8b4d8ec780443c4f0f0226a7c1a378..110d208996783e91efee270b9dc182a577c6ad3c 100644
--- a/alib2algo/src/automaton/simplify/Minimize.cpp
+++ b/alib2algo/src/automaton/simplify/Minimize.cpp
@@ -16,6 +16,7 @@ automaton::Automaton Minimize::minimize(const automaton::Automaton& automaton) {
 }
 
 auto MinimizeNFA = Minimize::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>( Minimize::minimize );
+auto MinimizeNFTA = Minimize::RegistratorWrapper<automaton::DFTA<>, automaton::DFTA<>>( Minimize::minimize );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/Minimize.h b/alib2algo/src/automaton/simplify/Minimize.h
index 2ad33d66d16bdea0dd074888f8ea49737176813f..bde5a7ec46b0b46f5eaaaf32c659a9a7fe5a8025 100644
--- a/alib2algo/src/automaton/simplify/Minimize.h
+++ b/alib2algo/src/automaton/simplify/Minimize.h
@@ -11,6 +11,7 @@
 #include <core/multipleDispatch.hpp>
 #include <automaton/Automaton.h>
 #include <automaton/FSM/DFA.h>
+#include <automaton/TA/DFTA.h>
 
 #include <map>
 #include <set>
@@ -33,6 +34,9 @@ public:
 	template < class SymbolType, class StateType >
 	static automaton::DFA < SymbolType, StateType > minimize(const automaton::DFA < SymbolType, StateType >& dfa);
 
+	template < class SymbolType, class RankType, class StateType >
+	static automaton::DFTA < SymbolType, RankType, StateType > minimize(const automaton::DFTA < SymbolType, RankType, StateType >& dfta);
+
 private:
 	template < class SymbolType, class StateType >
 	static void print_progress(const automaton::DFA < SymbolType, StateType >& dfa, const std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& minimizedTransitionFunction, size_t iter);
@@ -208,6 +212,94 @@ void Minimize::print_progress(const automaton::DFA < SymbolType, StateType >& df
 	std::clog << std::endl;
 }
 
+template < class SymbolType, class RankType, class StateType >
+automaton::DFTA < SymbolType, RankType, StateType > Minimize::minimize(const automaton::DFTA < SymbolType, RankType, StateType >& dfta) {
+	automaton::DFTA<SymbolType, RankType, StateType> result;
+	result.setInputAlphabet(dfta.getInputAlphabet());
+
+	if (dfta.getFinalStates().size() == 0)
+		return result;
+
+	typedef std::pair < const std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < StateType > >, StateType > Transition;
+
+	std::map<StateType, std::map<Transition, std::vector<int>>> stateOccurences;
+
+	for (const auto & state : dfta.getStates())
+		stateOccurences[state];
+
+	for(auto & transition : dfta.getTransitions()) {
+		const std::vector<StateType> & from = transition.first.second;
+		for (int i = 0; i < (int) from.size(); ++i)
+			stateOccurences[from[i]][transition].push_back(i);
+	}
+
+	std::map <StateType, StateType> toEquivalentStates;
+	std::map<std::pair<StateType, std::map<std::tuple<std::ranked_symbol<SymbolType, RankType>, std::vector<StateType>, StateType >, std::set<int> > >, std::set<StateType> > minimizedTransitionFunction; //mapped to the original states
+	const StateType *firstFinal = NULL, *firstNonfinal = NULL;
+	for (const StateType &state : dfta.getStates()) {
+		if (dfta.getFinalStates().count(state) == 0) { // not a final state
+			if (!firstNonfinal)
+				firstNonfinal = &state;
+
+			toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstNonfinal));
+		} else {
+			if (!firstFinal)
+				firstFinal = &state;
+
+			toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstFinal));
+		}
+	}
+
+	unsigned prevSize = 0;
+	while(true) {
+		for(const auto & occurencesOfState : stateOccurences) {
+			const StateType & state = occurencesOfState.first;
+			const StateType & equivalentState = toEquivalentStates.find(state) -> second;
+			std::map<std::tuple<std::ranked_symbol<SymbolType, RankType>, std::vector<StateType>, StateType >, std::set<int> > keyTransitionsPart;
+
+			for(const auto & transitionOccurences : occurencesOfState.second) {
+				const auto & transition = transitionOccurences.first;
+				for (int i : transitionOccurences.second) {
+					std::vector<StateType> fromWithoutCurrent (transition.first.second);
+					fromWithoutCurrent.erase(fromWithoutCurrent.begin()+i);
+					keyTransitionsPart[std::make_tuple(transition.first.first, fromWithoutCurrent, toEquivalentStates.find(transition.second)->second)].insert(i);
+				}
+			}
+
+			minimizedTransitionFunction [ std::make_pair ( equivalentState, keyTransitionsPart ) ].insert(state);
+		}
+
+		if (minimizedTransitionFunction.size() == prevSize)
+			break;
+
+		prevSize = minimizedTransitionFunction.size();
+		toEquivalentStates.clear();
+		for(const auto & transition : minimizedTransitionFunction)
+			for(const StateType & target : transition.second)
+				toEquivalentStates.insert(std::make_pair ( target, * transition.second.begin() ) );
+
+		minimizedTransitionFunction.clear();
+	}
+
+	for (const auto & transition : minimizedTransitionFunction) {
+		const auto & state = *(transition.second.begin());
+		result.addState(state);
+		if(dfta.getFinalStates().count(state))
+			result.addFinalState(state);
+	}
+
+	for(const auto & transition : dfta.getTransitions()) {
+		std::vector<StateType> from;
+		from.reserve(transition.first.second.size());
+		for (const StateType & state : transition.first.second)
+			from.push_back(toEquivalentStates.find(state)->second);
+
+		result.addTransition(transition.first.first, from, toEquivalentStates.find(transition.second)->second);
+	}
+
+	return result;
+}
+
 } /* namespace simplify */
 
 } /* namespace automaton */
diff --git a/alib2algo/test-src/automaton/simplify/minimizeTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
index bf891143c2e444223d1ef011ceeeedc7f933231f..60cd74c3c496665eabd60fb9e6e26cf00d43861c 100644
--- a/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
@@ -2,6 +2,7 @@
 #include "minimizeTest.h"
 
 #include "automaton/simplify/Minimize.h"
+#include <factory/XmlDataFactory.hpp>
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( minimizeTest, "automaton" );
 CPPUNIT_TEST_SUITE_REGISTRATION( minimizeTest );
@@ -12,22 +13,166 @@ void minimizeTest::setUp() {
 void minimizeTest::tearDown() {
 }
 
-void minimizeTest::testMinimize() {
-  automaton::DFA < > automaton(DefaultStateType(1));
+void minimizeTest::testMinimizeDFA() {
+	automaton::DFA < > automaton(DefaultStateType(1));
 
-  automaton.addState(DefaultStateType(1));
-  automaton.addState(DefaultStateType(2));
-  automaton.addState(DefaultStateType(3));
-  automaton.addInputSymbol(DefaultSymbolType("a"));
-  automaton.addInputSymbol(DefaultSymbolType("b"));
-  
-  automaton.addTransition(DefaultStateType(1), DefaultSymbolType("a"), DefaultStateType(2));
-  automaton.addTransition(DefaultStateType(2), DefaultSymbolType("b"), DefaultStateType(1));
+	automaton.addState(DefaultStateType(1));
+	automaton.addState(DefaultStateType(2));
+	automaton.addState(DefaultStateType(3));
+	automaton.addInputSymbol(DefaultSymbolType("a"));
+	automaton.addInputSymbol(DefaultSymbolType("b"));
 
-  automaton.addFinalState(DefaultStateType(3));
-  
-  automaton::DFA<> minimized = automaton::simplify::Minimize::minimize(automaton);
+	automaton.addTransition(DefaultStateType(1), DefaultSymbolType("a"), DefaultStateType(2));
+	automaton.addTransition(DefaultStateType(2), DefaultSymbolType("b"), DefaultStateType(1));
 
-  CPPUNIT_ASSERT(minimized.getStates().size() == 3);
+	automaton.addFinalState(DefaultStateType(3));
 
+	automaton::DFA<> minimized = automaton::simplify::Minimize::minimize(automaton);
+
+	CPPUNIT_ASSERT(minimized.getStates().size() == 3);
+
+}
+
+void minimizeTest::testMinimizeDFTA() {
+	automaton::DFTA < > automaton;
+
+	std::vector<DefaultStateType> q;
+
+	for (int i = 0; i <= 10; ++i) {
+		DefaultStateType state (i);
+		q.push_back(state);
+		automaton.addState(state);
+	}
+
+	automaton.addFinalState(q[9]);
+	automaton.addFinalState(q[10]);
+
+	const std::ranked_symbol < > a ("a", 3);
+	const std::ranked_symbol < > b ("b", 2);
+	const std::ranked_symbol < > c ("c", 1);
+	const std::ranked_symbol < > d ("d", 0);
+	const std::ranked_symbol < > e ("e", 0);
+	const std::ranked_symbol < > f ("f", 0);
+	const std::ranked_symbol < > g ("g", 0);
+
+	automaton.addInputSymbol(a);
+	automaton.addInputSymbol(b);
+	automaton.addInputSymbol(c);
+	automaton.addInputSymbol(d);
+	automaton.addInputSymbol(e);
+	automaton.addInputSymbol(f);
+	automaton.addInputSymbol(g);
+
+	automaton.addTransition(d, {}, q[0]);
+	automaton.addTransition(e, {}, q[1]);
+
+	for (int i = 0; i <= 1; ++i) {
+		for (int j = 0; j <= 1; ++j) {
+			automaton.addTransition(b, {q[i], q[j]}, q[2]);
+		}
+	}
+
+	automaton.addTransition(b, {q[2], q[2]}, q[6]);
+	automaton.addTransition(f, {}, q[3]);
+	for (int i = 3; i < 5; ++i) {
+		automaton.addTransition(c, {q[i]}, q[i+1]);
+	}
+
+	automaton.addTransition(c, {q[5]}, q[7]);
+	automaton.addTransition(g, {}, q[8]);
+
+	for (int i = 6; i <= 8; ++i) {
+		for (int j = 6; j <= 8; ++j) {
+			for (int k = 6; k <= 8; ++k) {
+				automaton.addTransition(a, {q[i], q[j], q[k]}, q[9]);
+			}
+		}
+	}
+
+	automaton.addTransition(a, {q[9], q[9], q[9]}, q[10]);
+
+	automaton::DFTA < > minimal;
+	minimal.addState(q[0]);
+	minimal.addState(q[2]);
+	minimal.addState(q[3]);
+	minimal.addState(q[4]);
+	minimal.addState(q[5]);
+	minimal.addState(q[6]);
+	minimal.addState(q[9]);
+	minimal.addState(q[10]);
+	minimal.setFinalStates(automaton.getFinalStates());
+	minimal.setInputAlphabet(automaton.getInputAlphabet());
+	minimal.addTransition(d, {}, q[0]);
+	minimal.addTransition(e, {}, q[0]);
+	minimal.addTransition(b, {q[0], q[0]}, q[2]);
+	minimal.addTransition(b, {q[2], q[2]}, q[6]);
+	minimal.addTransition(f, {}, q[3]);
+
+	for (int i = 3; i < 5; ++i) {
+		minimal.addTransition(c, {q[i]}, q[i+1]);
+	}
+
+	minimal.addTransition(c, {q[5]}, q[6]);
+	minimal.addTransition(g, {}, q[6]);
+	minimal.addTransition(a, {q[6], q[6], q[6]}, q[9]);
+	minimal.addTransition(a, {q[9], q[9], q[9]}, q[10]);
+
+	automaton::DFTA<> minimized = automaton::simplify::Minimize::minimize(automaton);
+	CPPUNIT_ASSERT(minimized == minimal);
+
+/*	automaton::DFTA < > automaton;
+
+	const DefaultStateType q0 ("0");
+	const DefaultStateType q1 ("1");
+	const DefaultStateType q00 ("00");
+	const DefaultStateType q11 ("11");
+	automaton.addState(q0);
+	automaton.addState(q1);
+	automaton.addState(q00);
+	automaton.addState(q11);
+
+	const std::ranked_symbol < > st ("t", 0);
+	const std::ranked_symbol < > sf ("f", 0);
+	const std::ranked_symbol < > snot ("not", 1);
+	const std::ranked_symbol < > sor ("or", 2);
+	automaton.addInputSymbol(st);
+	automaton.addInputSymbol(sf);
+	automaton.addInputSymbol(snot);
+	automaton.addInputSymbol(sor);
+
+	automaton.addTransition(st, {}, q1);
+	automaton.addTransition(sf, {}, q0);
+
+	automaton.addTransition(snot, {q0}, q1);
+	automaton.addTransition(snot, {q1}, q0);
+	automaton.addTransition(snot, {q00}, q1);
+	automaton.addTransition(snot, {q11}, q0);
+
+	automaton.addTransition(sor, {q0, q0}, q00);
+	automaton.addTransition(sor, {q0, q00}, q00);
+	automaton.addTransition(sor, {q00, q0}, q00);
+	automaton.addTransition(sor, {q00, q00}, q00);
+	automaton.addTransition(sor, {q0, q1}, q1);
+	automaton.addTransition(sor, {q0, q11}, q1);
+	automaton.addTransition(sor, {q00, q1}, q1);
+	automaton.addTransition(sor, {q00, q11}, q1);
+	automaton.addTransition(sor, {q1, q0}, q1);
+	automaton.addTransition(sor, {q1, q00}, q1);
+	automaton.addTransition(sor, {q11, q0}, q1);
+	automaton.addTransition(sor, {q11, q00}, q1);
+	automaton.addTransition(sor, {q1, q1}, q11);
+	automaton.addTransition(sor, {q1, q11}, q11);
+	automaton.addTransition(sor, {q11, q1}, q11);
+	automaton.addTransition(sor, {q11, q11}, q11);
+
+	automaton.addFinalState(q1);
+	automaton.addFinalState(q11);
+
+	automaton::DFTA<> minimized = automaton::simplify::Minimize::minimize(automaton);
+	std::cout << minimized << std::endl;
+	CPPUNIT_ASSERT(minimized.getStates().size() == 2);
+	CPPUNIT_ASSERT(minimized.getFinalStates().size() == 1);
+	CPPUNIT_ASSERT(minimized.getTransitions().size() == 8);
+	CPPUNIT_ASSERT(minimized.getInputAlphabet().size() == 4);
+*/
 }
diff --git a/alib2algo/test-src/automaton/simplify/minimizeTest.h b/alib2algo/test-src/automaton/simplify/minimizeTest.h
index 4b1f60f638835bd1ca86c227b077a1fb1aeb996a..50813dbd68c983f7b12873b98c2bb7a493aa4e01 100644
--- a/alib2algo/test-src/automaton/simplify/minimizeTest.h
+++ b/alib2algo/test-src/automaton/simplify/minimizeTest.h
@@ -3,17 +3,18 @@
 
 #include <cppunit/extensions/HelperMacros.h>
 
-class minimizeTest : public CppUnit::TestFixture
-{
-  CPPUNIT_TEST_SUITE( minimizeTest );
-  CPPUNIT_TEST( testMinimize );
-  CPPUNIT_TEST_SUITE_END();
+class minimizeTest : public CppUnit::TestFixture {
+	CPPUNIT_TEST_SUITE( minimizeTest );
+	CPPUNIT_TEST( testMinimizeDFA );
+	CPPUNIT_TEST( testMinimizeDFTA );
+	CPPUNIT_TEST_SUITE_END();
 
 public:
-  void setUp();
-  void tearDown();
+	void setUp();
+	void tearDown();
 
-  void testMinimize();
+	void testMinimizeDFA();
+	void testMinimizeDFTA();
 };
 
 #endif  // MINIMIZE_TEST_H_