diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
index 13e43c6834dae22aef532a50aa7f91561a54bf1f..5e639c8453c79e0a10e9a9ddf936f2b1f6b39ae5 100644
--- a/alib2algo/src/automaton/simplify/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -12,6 +12,7 @@
 #include <automaton/FSM/EpsilonNFA.h>
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
+#include <automaton/TA/DFTA.h>
 
 namespace automaton {
 
@@ -23,6 +24,7 @@ auto TrimMultiInitialStateNFA = Trim::RegistratorWrapper<automaton::MultiInitial
 auto TrimEpsilonNFA = Trim::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(Trim::trim);
 auto TrimCompactNFA = Trim::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(Trim::trim);
 auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(Trim::trim);
+auto TrimDFTA = Trim::RegistratorWrapper<automaton::DFTA<>, automaton::DFTA<>>(Trim::trim);
 
 automaton::Automaton Trim::trim(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index 0732bf1a4f01d8fcb0ec8b2821fddaa9f70910f5..39701c6f10faa863c0eeaabd9566e128fbe24445 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -17,6 +17,7 @@ auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorW
 auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverDFA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverMultiInitialStateNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > >(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverDFTA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFTA<>, automaton::DFTA < > >(UnreachableStatesRemover::remove);
 
 automaton::Automaton UnreachableStatesRemover::remove(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
index 64eb16c32c711535de149cf27d2f7594a8792c06..d4e7e5a3c754aed4fae60f4706da328278c6f248 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
@@ -17,6 +17,7 @@
 #include <automaton/FSM/MultiInitialStateNFA.h>
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
+#include <automaton/TA/DFTA.h>
 
 #include "../properties/ReachableStates.h"
 
@@ -37,6 +38,8 @@ public:
 	static automaton::DFA < SymbolType, StateType > remove( const automaton::DFA < SymbolType, StateType > & fsm );
 	template < class SymbolType, class StateType >
 	static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
+	template < class SymbolType, class RankType, class StateType >
+	static automaton::DFTA < SymbolType, RankType, StateType > remove( const automaton::DFTA < SymbolType, RankType, StateType > & dfta );
 };
 
 template<class T, class SymbolType, class StateType >
@@ -121,6 +124,61 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov
 	return M;
 }
 
+template < class SymbolType, class RankType, class StateType >
+automaton::DFTA < SymbolType, RankType, StateType > UnreachableStatesRemover::remove( const automaton::DFTA < SymbolType, RankType, StateType > & dfta ) {
+	automaton::DFTA < SymbolType, RankType, StateType > res;
+	res.setInputAlphabet(dfta.getInputAlphabet());
+
+	typedef std::pair < const std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < StateType > >, StateType > Transition;
+	std::vector<std::pair<const Transition *, int>> transitionsUnreachableCount;
+	transitionsUnreachableCount.reserve(dfta.getTransitions().size());
+
+	//for a state, transitions with unreachable count (initially all unreachable) and number of occurences of this state (at least 1)
+	std::map<StateType, std::map<std::pair<const Transition *, int> *, int>> stateOccurences;
+	std::deque<StateType> queue;
+	for(const auto & transition : dfta.getTransitions()) {
+		if (transition.first.second.empty()) {
+			queue.push_back(transition.second);
+			res.addState(transition.second);
+			res.addTransition(transition.first.first, transition.first.second, transition.second);
+		} else {
+			transitionsUnreachableCount.push_back({&transition, transition.first.second.size()});
+			for (const auto & state : transition.first.second) {
+				auto & occurences = stateOccurences[state];
+				auto it = occurences.find(&transitionsUnreachableCount.back());
+				if (it == occurences.end()) occurences[&transitionsUnreachableCount.back()] = 1;
+				else it->second++;
+			}
+		}
+	}
+
+	while(!queue.empty()) {
+		const auto & occurences = stateOccurences[queue.front()];
+		queue.pop_front();
+		for (const auto & occurence : occurences) {
+			int & unreachableCount = occurence.first -> second;
+			const StateType & to = occurence.first -> first -> second;
+			unreachableCount -=  occurence.second;
+			if (unreachableCount == 0) {
+				if (res.addState(to)) {
+					queue.push_back(to);
+				}
+			}
+		}
+	}
+
+	for (const auto & state : res.getStates()) {
+		if (dfta.getFinalStates().count(state) != 0) res.addFinalState(state);
+	}
+	for (const auto & transitionUnreachableCount : transitionsUnreachableCount) {
+		if (transitionUnreachableCount.second == 0) {
+			const Transition transition = *(transitionUnreachableCount.first);
+			res.addTransition(transition.first.first, transition.first.second, transition.second);
+		}
+	}
+	return res;
+}
+
 } /* namespace simplify */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index b416822197913011739f32b36c9b9f8f531537f3..8b008413f2a8e8b8a90438817c7c87d135fe631c 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -17,6 +17,7 @@ auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<a
 auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UselessStatesRemover::remove);
 auto UselessStatesRemoverDFA = UselessStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UselessStatesRemover::remove);
 auto UselessStatesRemoverMultiInitialStateNFA = UselessStatesRemover::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > >(UselessStatesRemover::remove);
+auto UselessStatesRemoverDFTA = UselessStatesRemover::RegistratorWrapper<automaton::DFTA<>, automaton::DFTA<>>(UselessStatesRemover::remove);
 
 automaton::Automaton UselessStatesRemover::remove(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
index fbf21b2335f99c2fb6ed133e0fee51341a1dc291..7ea18e0297f2065983a468237d35be7416aee2e6 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
@@ -19,6 +19,7 @@
 #include <automaton/FSM/MultiInitialStateNFA.h>
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
+#include <automaton/TA/DFTA.h>
 
 namespace automaton {
 
@@ -37,6 +38,8 @@ public:
 	static automaton::DFA < SymbolType, StateType > remove( const automaton::DFA < SymbolType, StateType > & fsm );
 	template < class SymbolType, class StateType >
 	static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
+	template < class SymbolType, class RankType, class StateType >
+	static automaton::DFTA < SymbolType, RankType, StateType > remove( const automaton::DFTA < SymbolType, RankType, StateType > & dfta );
 };
 
 template < class T, class SymbolType, class StateType >
@@ -130,6 +133,44 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UselessStatesRemover::
 	return M;
 }
 
+template < class SymbolType, class RankType, class StateType >
+automaton::DFTA < SymbolType, RankType, StateType > UselessStatesRemover::remove( const automaton::DFTA < SymbolType, RankType, StateType > & dfta ) {
+	automaton::DFTA < SymbolType, RankType, StateType > res;
+	res.setInputAlphabet(dfta.getInputAlphabet());
+	res.setStates(dfta.getFinalStates());
+	res.setFinalStates(dfta.getFinalStates());
+
+	typedef std::pair < const std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < StateType > >, StateType > Transition;
+
+	std::map<StateType, std::set<const Transition *>> transitionsToState;
+	for(const auto & transition : dfta.getTransitions()) {
+		transitionsToState[transition.second].insert(&transition);
+	}
+
+	std::deque<StateType> queue;
+	for (const auto & state : dfta.getFinalStates()) {
+		queue.push_back(state);
+	}
+
+	while(!queue.empty()) {
+		std::set<const Transition *> & transitions = transitionsToState[queue.front()];
+		queue.pop_front();
+		for (const Transition * transitionPt : transitions) {
+			const Transition &transition = *transitionPt;
+
+			for (const auto & state : transition.first.second) {
+				if (res.addState(state)) {
+					queue.push_back(state);
+				}
+			}
+
+			res.addTransition(transition.first.first, transition.first.second, transition.second);
+		}
+	}
+
+	return res;
+}
+
 } /* namespace simplify */
 
 } /* namespace automaton */
diff --git a/alib2algo/test-src/automaton/simplify/trimTest.cpp b/alib2algo/test-src/automaton/simplify/trimTest.cpp
index 6c17786b04a6ea273287ecb6e0ef9d5591dca9bb..e2d813d8d34d84c32290744febbd0a860ec745c2 100644
--- a/alib2algo/test-src/automaton/simplify/trimTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/trimTest.cpp
@@ -6,6 +6,7 @@
 
 #include "automaton/FSM/DFA.h"
 #include "grammar/Regular/RightRG.h"
+#include "automaton/TA/DFTA.h"
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( trimTest, "automaton" );
 CPPUNIT_TEST_SUITE_REGISTRATION( trimTest );
@@ -17,47 +18,99 @@ void trimTest::tearDown() {
 }
 
 void trimTest::testTrimAutomaton() {
-  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.addTransition(DefaultStateType(3), DefaultSymbolType("b"), DefaultStateType(1));
-
-  automaton.addFinalState(DefaultStateType(1));
-  
-  automaton::DFA<> trimed = automaton::simplify::Trim::trim(automaton);
-
-  CPPUNIT_ASSERT(trimed.getStates().size() == 2);
+	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.addTransition(DefaultStateType(3), DefaultSymbolType("b"), DefaultStateType(1));
+
+	automaton.addFinalState(DefaultStateType(1));
+
+	automaton::DFA<> trimed = automaton::simplify::Trim::trim(automaton);
+
+	CPPUNIT_ASSERT(trimed.getStates().size() == 2);
 }
 
 void trimTest::testTrimGrammar() {
-  grammar::RightRG < > rrGrammar(DefaultSymbolType(1));
-
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(1));
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(2));
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(3));
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(4));
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(5));
-  rrGrammar.addNonterminalSymbol(DefaultSymbolType(6));
-  rrGrammar.addTerminalSymbol(DefaultSymbolType("a"));
-  rrGrammar.addTerminalSymbol(DefaultSymbolType("b"));
-  
-  rrGrammar.addRule(DefaultSymbolType(1), std::make_pair(DefaultSymbolType("a"), DefaultSymbolType(2)));
-  rrGrammar.addRule(DefaultSymbolType(2), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(3)));
-  rrGrammar.addRule(DefaultSymbolType(3), DefaultSymbolType("a"));
-
-  rrGrammar.addRule(DefaultSymbolType(4), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(5)));
-  rrGrammar.addRule(DefaultSymbolType(5), DefaultSymbolType("a"));
-  rrGrammar.addRule(DefaultSymbolType(5), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(2)));
-  rrGrammar.addRule(DefaultSymbolType(6), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(6)));
-
-  grammar::RightRG < > trimed = grammar::simplify::Trim::trim(rrGrammar);
-
-  CPPUNIT_ASSERT(trimed.getNonterminalAlphabet().size() == 3);
+	grammar::RightRG < > rrGrammar(DefaultSymbolType(1));
+
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(1));
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(2));
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(3));
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(4));
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(5));
+	rrGrammar.addNonterminalSymbol(DefaultSymbolType(6));
+	rrGrammar.addTerminalSymbol(DefaultSymbolType("a"));
+	rrGrammar.addTerminalSymbol(DefaultSymbolType("b"));
+	
+	rrGrammar.addRule(DefaultSymbolType(1), std::make_pair(DefaultSymbolType("a"), DefaultSymbolType(2)));
+	rrGrammar.addRule(DefaultSymbolType(2), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(3)));
+	rrGrammar.addRule(DefaultSymbolType(3), DefaultSymbolType("a"));
+
+	rrGrammar.addRule(DefaultSymbolType(4), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(5)));
+	rrGrammar.addRule(DefaultSymbolType(5), DefaultSymbolType("a"));
+	rrGrammar.addRule(DefaultSymbolType(5), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(2)));
+	rrGrammar.addRule(DefaultSymbolType(6), std::make_pair(DefaultSymbolType("b"), DefaultSymbolType(6)));
+
+	grammar::RightRG < > trimed = grammar::simplify::Trim::trim(rrGrammar);
+
+	CPPUNIT_ASSERT(trimed.getNonterminalAlphabet().size() == 3);
+}
+
+void trimTest::testTrimDFTA() {
+	automaton::DFTA < > automaton;
+
+	std::vector<DefaultStateType> q;
+	for (int i = 0; i <= 11; ++i) {
+		DefaultStateType state (i);
+		q.push_back(state);
+		automaton.addState(state);
+	}
+	automaton.addFinalState(q[2]);
+	automaton.addFinalState(q[11]);
+
+	const std::ranked_symbol < > a ("a", 2);
+	const std::ranked_symbol < > b ("b", 1);
+	const std::ranked_symbol < > c ("c", 0);
+	automaton.addInputSymbol(a);
+	automaton.addInputSymbol(b);
+	automaton.addInputSymbol(c);
+
+	automaton.addTransition(c, {}, q[0]);
+	automaton.addTransition(a, {q[0], q[0]}, q[1]);
+	automaton.addTransition(b, {q[1]}, q[2]);
+
+	//unreachable and useless
+	automaton.addTransition(a, {q[3], q[4]}, q[5]);
+	automaton.addTransition(b, {q[5]}, q[6]);
+
+	//useless
+	automaton.addTransition(a, {q[2], q[2]}, q[7]);
+	automaton.addTransition(a, {q[7], q[7]}, q[8]);
+
+	//unreachable
+	automaton.addTransition(a, {q[9], q[9]}, q[10]);
+	automaton.addTransition(a, {q[10], q[10]}, q[11]);
+
+	automaton::DFTA<> trimed = automaton::simplify::Trim::trim(automaton);
+
+	automaton::DFTA<> correct;
+	correct.addState(q[0]);
+	correct.addState(q[1]);
+	correct.addState(q[2]);
+	correct.addFinalState(q[2]);
+	correct.addInputSymbol(a);
+	correct.addInputSymbol(b);
+	correct.addInputSymbol(c);
+	correct.addTransition(c, {}, q[0]);
+	correct.addTransition(a, {q[0], q[0]}, q[1]);
+	correct.addTransition(b, {q[1]}, q[2]);
+
+	CPPUNIT_ASSERT(trimed == correct);
 }
diff --git a/alib2algo/test-src/automaton/simplify/trimTest.h b/alib2algo/test-src/automaton/simplify/trimTest.h
index b23af79d17e8e2423e455379987f8891074d5550..79b6736ce63b0ac4fbba61bfc8e53192f969b449 100644
--- a/alib2algo/test-src/automaton/simplify/trimTest.h
+++ b/alib2algo/test-src/automaton/simplify/trimTest.h
@@ -3,19 +3,20 @@
 
 #include <cppunit/extensions/HelperMacros.h>
 
-class trimTest : public CppUnit::TestFixture
-{
-  CPPUNIT_TEST_SUITE( trimTest );
-  CPPUNIT_TEST( testTrimAutomaton );
-  CPPUNIT_TEST( testTrimGrammar );
-  CPPUNIT_TEST_SUITE_END();
+class trimTest : public CppUnit::TestFixture {
+	CPPUNIT_TEST_SUITE( trimTest );
+	CPPUNIT_TEST( testTrimAutomaton );
+	CPPUNIT_TEST( testTrimGrammar );
+	CPPUNIT_TEST( testTrimDFTA );
+	CPPUNIT_TEST_SUITE_END();
 
 public:
-  void setUp();
-  void tearDown();
+	void setUp();
+	void tearDown();
 
-  void testTrimAutomaton();
-  void testTrimGrammar();
+	void testTrimAutomaton();
+	void testTrimGrammar();
+	void testTrimDFTA();
 };
 
-#endif  // TRIM_TEST_H_
+#endif	// TRIM_TEST_H_
diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp
index 06f914e4beb3d5bf0a9536324cad3efb46dcb658..cce17143a26494a0ead90b8956be3dbf0849ba2b 100644
--- a/atrim2/src/atrim.cpp
+++ b/atrim2/src/atrim.cpp
@@ -65,10 +65,10 @@ int main(int argc, char* argv[]) {
 
 		TCLAP::CmdLine cmd("Removes unreachable and useless states from FSM, productive and unreachable nonterminals from CFG. Simplifies representation of RE", ' ', "0.01");
 
-		TCLAP::SwitchArg useless(		"u",	"useless",	"Removes useless states (or symbols). (works with FSM or CFG)"		);
+		TCLAP::SwitchArg useless(		"u",	"useless",	"Removes useless states (or symbols). (works with FSM, FTA or CFG)"	);
 		cmd.add( useless );
 
-		TCLAP::SwitchArg unreachable(		"r",	"unreachable",	"Removes unreachable states (or symbols). (works with FSM or CFG)"	);
+		TCLAP::SwitchArg unreachable(		"r",	"unreachable",	"Removes unreachable states (or symbols). (works with FSM, FTA or CFG)"	);
 		cmd.add( unreachable );
 
 		TCLAP::SwitchArg simplify(		"s",	"simplify",	"Simplifies representation. (works with RE only)"			);