From c4a753d599c1715318dee1f40611bb610d647bee Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 3 Sep 2014 19:46:51 +0200
Subject: [PATCH] trim FSM and CFG algorithms

---
 alib2algo/src/trim/automaton/TrimFSM.cpp      | 225 ++++++++++++++++++
 alib2algo/src/trim/automaton/TrimFSM.h        |  40 ++++
 alib2algo/src/trim/grammar/TrimCFG.cpp        | 224 +++++++++++++++++
 alib2algo/src/trim/grammar/TrimCFG.h          |  69 ++++++
 alib2algo/test-src/trim/trimTest.cpp          |  69 ++++++
 alib2algo/test-src/trim/trimTest.h            |  21 ++
 alib2data/src/grammar/ContextFree/CFG.cpp     |  14 +-
 alib2data/src/grammar/ContextFree/CFG.h       |   8 +-
 alib2data/src/grammar/ContextFree/CNF.cpp     |  54 ++++-
 alib2data/src/grammar/ContextFree/CNF.h       |   8 +-
 .../grammar/ContextFree/EpsilonFreeCFG.cpp    |  32 ++-
 .../src/grammar/ContextFree/EpsilonFreeCFG.h  |   8 +-
 alib2data/src/grammar/ContextFree/GNF.cpp     |  44 +++-
 alib2data/src/grammar/ContextFree/GNF.h       |   8 +-
 alib2data/src/grammar/ContextFree/LG.cpp      |  58 ++++-
 alib2data/src/grammar/ContextFree/LG.h        |  10 +-
 .../src/grammar/ContextSensitive/CSG.cpp      |   2 +-
 alib2data/src/grammar/ContextSensitive/CSG.h  |   2 +-
 .../NonContractingGrammar.cpp                 |   2 +-
 .../ContextSensitive/NonContractingGrammar.h  |   2 +-
 alib2data/src/grammar/Regular/LeftLG.cpp      |  50 +++-
 alib2data/src/grammar/Regular/LeftLG.h        |  10 +-
 alib2data/src/grammar/Regular/LeftRG.cpp      |  55 ++++-
 alib2data/src/grammar/Regular/LeftRG.h        |   9 +-
 alib2data/src/grammar/Regular/RightLG.cpp     |  50 +++-
 alib2data/src/grammar/Regular/RightLG.h       |  10 +-
 alib2data/src/grammar/Regular/RightRG.cpp     |  55 ++++-
 alib2data/src/grammar/Regular/RightRG.h       |   9 +-
 .../ContextPreservingUnrestrictedGrammar.cpp  |   2 +-
 .../ContextPreservingUnrestrictedGrammar.h    |   2 +-
 .../Unrestricted/UnrestrictedGrammar.cpp      |   2 +-
 .../Unrestricted/UnrestrictedGrammar.h        |   2 +-
 atrim/makefile                                |  77 +++++-
 atrim/src/automaton/TrimFSM.cpp               | 121 ----------
 atrim/src/automaton/TrimFSM.h                 |  34 ---
 .../ContextFreeGrammarTransformations.cpp     | 138 -----------
 .../ContextFreeGrammarTransformations.h       |  51 ----
 37 files changed, 1157 insertions(+), 420 deletions(-)
 create mode 100644 alib2algo/src/trim/automaton/TrimFSM.cpp
 create mode 100644 alib2algo/src/trim/automaton/TrimFSM.h
 create mode 100644 alib2algo/src/trim/grammar/TrimCFG.cpp
 create mode 100644 alib2algo/src/trim/grammar/TrimCFG.h
 create mode 100644 alib2algo/test-src/trim/trimTest.cpp
 create mode 100644 alib2algo/test-src/trim/trimTest.h
 delete mode 100644 atrim/src/automaton/TrimFSM.cpp
 delete mode 100644 atrim/src/automaton/TrimFSM.h
 delete mode 100644 atrim/src/grammar/ContextFreeGrammarTransformations.cpp
 delete mode 100644 atrim/src/grammar/ContextFreeGrammarTransformations.h

diff --git a/alib2algo/src/trim/automaton/TrimFSM.cpp b/alib2algo/src/trim/automaton/TrimFSM.cpp
new file mode 100644
index 0000000000..4827fea136
--- /dev/null
+++ b/alib2algo/src/trim/automaton/TrimFSM.cpp
@@ -0,0 +1,225 @@
+/*
+ * TrimFSM.cpp
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "TrimFSM.h"
+
+#include <exception/AlibException.h>
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+namespace trim {
+
+template<class T>
+T TrimFSM::removeUselessStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getFinalStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & t : fsm.getTransitionsToState( p ) )
+				Qi.at( i ).insert( t.first.first );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+	const std::set<automaton::State>& Qu = Qi.at( i );
+
+	// 2.
+	T M;
+
+	for( const auto & q : Qu )
+		M.addState( q );
+
+	for( const auto & a : fsm.getInputAlphabet( ) )
+		M.addInputSymbol( a );
+
+	for( const auto & t : fsm.getTransitions( ) )
+		for( const auto & to : t.second )
+			if( /* TODO test this Qu.count(t.first.first) ) && */ Qu.count(to) )
+				M.addTransition( t.first.first, t.first.second, to );
+
+	for( const auto & q : fsm.getInitialStates( ) )
+		M.addInitialState( q );
+
+	for( const auto & q : fsm.getFinalStates( ) )
+		M.addFinalState( q );
+
+	return M;
+}
+
+template automaton::EpsilonNFA TrimFSM::removeUselessStates( const automaton::EpsilonNFA & fsm );
+template automaton::NFA TrimFSM::removeUselessStates( const automaton::NFA & fsm );
+template automaton::CompactNFA TrimFSM::removeUselessStates( const automaton::CompactNFA & fsm );
+template automaton::ExtendedNFA TrimFSM::removeUselessStates( const automaton::ExtendedNFA & fsm );
+
+template<>
+automaton::DFA TrimFSM::removeUselessStates( const automaton::DFA & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getFinalStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & t : fsm.getTransitionsToState( p ) )
+				Qi.at( i ).insert( t.first.first );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+	const std::set<automaton::State>& Qu = Qi.at( i );
+
+	// 2.
+	automaton::DFA M ( fsm.getInitialState () );
+
+	for( const auto & q : Qu )
+		M.addState( q );
+
+	for( const auto & a : fsm.getInputAlphabet( ) )
+		M.addInputSymbol( a );
+
+	for( const auto & t : fsm.getTransitions( ) )
+		if( /* TODO test this Qu.count( t.first.first ) && */ Qu.count( t.second ) )
+			M.addTransition( t.first.first, t.first.second, t.second );
+
+	for( const auto & q : fsm.getFinalStates( ) )
+		M.addFinalState( q );
+
+	return M;
+}
+
+template<class T>
+T TrimFSM::removeUnreachableStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getInitialStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & transition : fsm.getTransitionsFromState( p ) )
+				Qi.at( i ).insert( transition.second.begin(), transition.second.end() );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	const std::set<automaton::State> Qa = Qi.at( i );
+
+	// 2
+	T M;
+
+	for( const auto & q : Qa )
+		M.addState( q );
+
+	for( const auto & a : fsm.getInputAlphabet( ) )
+		M.addInputSymbol( a );
+
+	for( const auto & transition : fsm.getTransitions( ) )
+		if( Qa.count( transition.first.first ) )
+			for(const auto& to : transition.second )
+				M.addTransition( transition.first.first, transition.first.second, to );
+
+	for( const auto & q : fsm.getInitialStates( ) )
+		M.addInitialState( q );
+
+	std::set<automaton::State> intersect;
+	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
+	for( auto const & state : intersect )
+		M.addFinalState( state );
+
+	return M;
+}
+
+template automaton::EpsilonNFA TrimFSM::removeUnreachableStates( const automaton::EpsilonNFA & fsm );
+template automaton::NFA TrimFSM::removeUnreachableStates( const automaton::NFA & fsm );
+template automaton::CompactNFA TrimFSM::removeUnreachableStates( const automaton::CompactNFA & fsm );
+template automaton::ExtendedNFA TrimFSM::removeUnreachableStates( const automaton::ExtendedNFA & fsm );
+
+template<>
+automaton::DFA TrimFSM::removeUnreachableStates( const automaton::DFA & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ). insert( fsm.getInitialState( ) );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & transition : fsm.getTransitionsFromState( p ) )
+				Qi.at( i ).insert( transition.second );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	const std::set<automaton::State> Qa = Qi.at( i );
+
+	// 2
+	automaton::DFA M(fsm.getInitialState() );
+
+	for( const auto & q : Qa )
+		M.addState( q );
+
+	for( const auto & a : fsm.getInputAlphabet( ) )
+		M.addInputSymbol( a );
+
+	for( const auto & transition : fsm.getTransitions( ) )
+		if( Qa.count( transition.first.first ) )
+			M.addTransition( transition.first.first, transition.first.second, transition.second );
+
+	std::set<automaton::State> intersect;
+	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
+	for( auto const & state : intersect )
+		M.addFinalState( state );
+
+	return M;
+}
+
+template<class T>
+T TrimFSM::trim( const T & fsm ) {
+	return removeUnreachableStates(removeUselessStates(fsm));
+}
+
+template automaton::EpsilonNFA TrimFSM::trim( const automaton::EpsilonNFA & fsm );
+template automaton::NFA TrimFSM::trim( const automaton::NFA & fsm );
+template automaton::CompactNFA TrimFSM::trim( const automaton::CompactNFA & fsm );
+template automaton::ExtendedNFA TrimFSM::trim( const automaton::ExtendedNFA & fsm );
+template automaton::DFA TrimFSM::trim( const automaton::DFA & fsm );
+
+}
+
diff --git a/alib2algo/src/trim/automaton/TrimFSM.h b/alib2algo/src/trim/automaton/TrimFSM.h
new file mode 100644
index 0000000000..45ba49a6d1
--- /dev/null
+++ b/alib2algo/src/trim/automaton/TrimFSM.h
@@ -0,0 +1,40 @@
+/*
+ * TrimFSM.h
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef TRIM_FSM_H_
+#define TRIM_FSM_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+namespace trim {
+
+class TrimFSM {
+public:
+	/**
+	 * Removes dead states from FSM. Melichar 2.32
+	 */
+	template<class T>
+	static T removeUselessStates( const T & fsm );
+
+	/**
+	 * Removes dead states from FSM. Melichar 2.29
+	 */
+	template<class T>
+	static T removeUnreachableStates( const T & fsm );
+
+	/**
+	 * Removes dead states from FSM. Melichar 2.29
+	 */
+	template<class T>
+	static T trim( const T & fsm );
+};
+
+}
+
+#endif /* TRIM_FSM_H_ */
diff --git a/alib2algo/src/trim/grammar/TrimCFG.cpp b/alib2algo/src/trim/grammar/TrimCFG.cpp
new file mode 100644
index 0000000000..119e96544f
--- /dev/null
+++ b/alib2algo/src/trim/grammar/TrimCFG.cpp
@@ -0,0 +1,224 @@
+/*
+ * TrimCFG.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "TrimCFG.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.h>
+#include <grammar/ContextFree/LG.h>
+#include <grammar/Regular/LeftLG.h>
+#include <grammar/Regular/LeftRG.h>
+#include <grammar/Regular/RightLG.h>
+#include <grammar/Regular/RightRG.h>
+
+#include <std/set.hpp>
+
+namespace trim {
+
+template<class T>
+std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const T & grammar ) {
+	// 1.
+	std::deque<std::set<alphabet::Symbol>> Ni;
+	Ni.push_back( std::set<alphabet::Symbol>( ) );
+
+	int i = 1;
+
+	// 2.
+	while( true ) {
+		Ni.push_back( Ni.at( i - 1 ) );
+
+		for( const auto & rule : grammar.getRawRules( ) ) {
+			for( const auto & rhs : rule.second ) {
+				if( std::all_of( rhs.begin( ), rhs.end( ), [ i, Ni, grammar ]( const alphabet::Symbol & symbol ) -> bool {
+					return Ni.at( i - 1 ) . count( symbol ) || grammar.getTerminalAlphabet( ). count( symbol );
+				} ) )
+					Ni.at( i ).insert( rule.first );
+			}
+		}
+
+		if( Ni.at( i ) == Ni.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	// 3.
+	return Ni.at( i );
+}
+
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::CFG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::GNF & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::CNF & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::LG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::LeftLG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::LeftRG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::RightLG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getProductiveNonterminals( const grammar::RightRG & grammar );
+
+template<class T>
+bool TrimCFG::isLanguageEmpty( const T & grammar ) {
+	return getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+}
+
+template bool TrimCFG::isLanguageEmpty( const grammar::CFG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::GNF & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::CNF & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::LG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::LeftLG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::LeftRG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::RightLG & grammar );
+template bool TrimCFG::isLanguageEmpty( const grammar::RightRG & grammar );
+
+template<class T>
+std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const T & grammar ) {
+	// 1
+	std::deque<std::set<alphabet::Symbol>> Vi;
+	Vi.push_back( std::set<alphabet::Symbol>( ) );
+	Vi.at( 0 ).insert( grammar.getInitialSymbol( ) );
+
+	int i = 1;
+
+	// 2.
+	while( true ) {
+		Vi.push_back( Vi.at( i - 1 ) );
+
+		for( const auto & rule : grammar.getRawRules( ) ) {
+			if( Vi.at( i - 1 ).count( rule.first ) ) {
+				for( const auto & rhs : rule.second ) {
+					Vi.at( i ).insert( rhs.begin( ), rhs.end( ) );
+				}
+			}
+		}
+
+
+		if( Vi.at( i ) == Vi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	// 3.
+	return Vi.at( i );
+}
+
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::CFG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::GNF & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::CNF & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::LG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::LeftLG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::LeftRG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::RightLG & grammar );
+template std::set<alphabet::Symbol> TrimCFG::getUnreachableSymbols( const grammar::RightRG & grammar );
+
+template<class T>
+T TrimCFG::removeUnreachableSymbols( const T & grammar) {
+	// 1.
+	std::set<alphabet::Symbol> Vt = getUnreachableSymbols( grammar );
+
+	T ret(grammar.getInitialSymbol( ) );
+
+	std::set<alphabet::Symbol> newNonTerminals, newTerminals;
+
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) );
+	for( const auto & symbol : newNonTerminals )
+		ret.addNonterminalSymbol( symbol );
+
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) );
+	for( const auto & symbol : newTerminals )
+		ret.addTerminalSymbol( symbol );
+
+	// A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P
+	for( const auto & rule : grammar.getRawRules( ) ) {
+		if( newNonTerminals.count( rule.first ) ) {
+			for( const auto& rhs : rule.second ) {
+				if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( alphabet::Symbol const& symb ) -> bool {
+					return Vt.count( symb );
+				} ) )
+					ret.addRawRule( rule.first, rhs );
+			}
+	}	
+	}
+
+	// 2.
+	return ret;
+}
+
+template grammar::CFG TrimCFG::removeUnreachableSymbols( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG TrimCFG::removeUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF TrimCFG::removeUnreachableSymbols( const grammar::GNF & grammar );
+template grammar::CNF TrimCFG::removeUnreachableSymbols( const grammar::CNF & grammar );
+template grammar::LG TrimCFG::removeUnreachableSymbols( const grammar::LG & grammar );
+template grammar::LeftLG TrimCFG::removeUnreachableSymbols( const grammar::LeftLG & grammar );
+template grammar::LeftRG TrimCFG::removeUnreachableSymbols( const grammar::LeftRG & grammar );
+template grammar::RightLG TrimCFG::removeUnreachableSymbols( const grammar::RightLG & grammar );
+template grammar::RightRG TrimCFG::removeUnreachableSymbols( const grammar::RightRG & grammar );
+
+template<class T>
+T TrimCFG::removeUnproductiveSymbols( const T & grammar ) {
+	// 1.
+	std::set<alphabet::Symbol> Nt = getProductiveNonterminals( grammar );
+
+	T ret(grammar.getInitialSymbol( ) );
+
+	for( const auto & symbol : Nt )
+		ret.addNonterminalSymbol( symbol );
+
+	for( const auto & symbol : grammar.getTerminalAlphabet( ) )
+		ret.addTerminalSymbol( symbol );
+
+	const std::set<alphabet::Symbol> & terminals = ret.getTerminalAlphabet( );
+	for( const auto & rule : grammar.getRawRules( ) ) {
+		if( Nt.count( rule.first ) ) {
+			for( const auto & rhs : rule.second ) {
+				if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const alphabet::Symbol & symbol ) {
+						return Nt.count( symbol ) || terminals.count( symbol );
+				} ) )
+					ret.addRawRule( rule.first, rhs );
+			}
+		}
+	}
+
+
+	/* if( ! G1.getNonTerminalSymbols( ) . count( grammar.getInitialSymbol( ) ) )
+		throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." ); */
+
+	// 2.
+	return ret;
+}
+
+template grammar::CFG TrimCFG::removeUnproductiveSymbols( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG TrimCFG::removeUnproductiveSymbols( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF TrimCFG::removeUnproductiveSymbols( const grammar::GNF & grammar );
+template grammar::CNF TrimCFG::removeUnproductiveSymbols( const grammar::CNF & grammar );
+template grammar::LG TrimCFG::removeUnproductiveSymbols( const grammar::LG & grammar );
+template grammar::LeftLG TrimCFG::removeUnproductiveSymbols( const grammar::LeftLG & grammar );
+template grammar::LeftRG TrimCFG::removeUnproductiveSymbols( const grammar::LeftRG & grammar );
+template grammar::RightLG TrimCFG::removeUnproductiveSymbols( const grammar::RightLG & grammar );
+template grammar::RightRG TrimCFG::removeUnproductiveSymbols( const grammar::RightRG & grammar );
+
+template<class T>
+T TrimCFG::trim( const T & grammar ) {
+	return removeUnreachableSymbols( removeUnproductiveSymbols( grammar ) );
+}
+
+template grammar::CFG TrimCFG::trim( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG TrimCFG::trim( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF TrimCFG::trim( const grammar::GNF & grammar );
+template grammar::CNF TrimCFG::trim( const grammar::CNF & grammar );
+template grammar::LG TrimCFG::trim( const grammar::LG & grammar );
+template grammar::LeftLG TrimCFG::trim( const grammar::LeftLG & grammar );
+template grammar::LeftRG TrimCFG::trim( const grammar::LeftRG & grammar );
+template grammar::RightLG TrimCFG::trim( const grammar::RightLG & grammar );
+template grammar::RightRG TrimCFG::trim( const grammar::RightRG & grammar );
+
+}
+
diff --git a/alib2algo/src/trim/grammar/TrimCFG.h b/alib2algo/src/trim/grammar/TrimCFG.h
new file mode 100644
index 0000000000..97a0c60e8a
--- /dev/null
+++ b/alib2algo/src/trim/grammar/TrimCFG.h
@@ -0,0 +1,69 @@
+/*
+ * TrimCFG.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef TRIM_CFG_H_
+#define TRIM_CFG_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+
+#include <alphabet/Symbol.h>
+
+namespace trim {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class TrimCFG {
+public:
+	/*
+	 * Melichar 3.6 - decides whether L( grammar ) = \0
+	 *
+	 * Severals steps implemented in method CFGTransformations::getProductiveNonTerminals();
+	 * @see getProductiveNonTerminals
+	 */
+	template<class T>
+	static bool isLanguageEmpty( const T & grammar );
+
+	/*
+	 * Removes unreachable symbols - Melichar 3.9
+	 */
+	template<class T>
+	static T removeUnreachableSymbols( const T & grammar );
+
+	/**
+	 * Removes unproductive (or useless - terminology) symbols - Melichar 3.12
+	 */
+	template<class T>
+	static T removeUnproductiveSymbols( const T & grammar );
+
+	/**
+	 * Removes unproductive and useless symbols - Melichar 3.12
+	 */
+	template<class T>
+	static T trim( const T & grammar );
+
+private:
+	/**
+	 * Implements steps 1 through 3 in Melichar 3.6
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
+
+	/**
+	 * Implements 
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
+};
+
+}
+
+#endif /* TRIM_CFG_H_ */
diff --git a/alib2algo/test-src/trim/trimTest.cpp b/alib2algo/test-src/trim/trimTest.cpp
new file mode 100644
index 0000000000..e416d5ea5c
--- /dev/null
+++ b/alib2algo/test-src/trim/trimTest.cpp
@@ -0,0 +1,69 @@
+#include <list>
+#include "trimTest.h"
+
+#include "label/StringLabel.h"
+#include "label/IntegerLabel.h"
+#include "label/Label.h"
+#include "alphabet/LabeledSymbol.h"
+
+#include "trim/automaton/TrimFSM.h"
+#include "trim/grammar/TrimCFG.h"
+
+#include "automaton/FSM/DFA.h"
+#include "grammar/Regular/RightRG.h"
+
+#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
+
+CPPUNIT_TEST_SUITE_REGISTRATION( trimTest );
+
+void trimTest::setUp() {
+}
+
+void trimTest::tearDown() {
+}
+
+void trimTest::testTrimAutomaton() {
+  automaton::DFA automaton(automaton::State(label::Label(label::IntegerLabel(1))));
+
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(1))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(2))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(3))));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
+  
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), automaton::State(label::Label(label::IntegerLabel(2))));
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), automaton::State(label::Label(label::IntegerLabel(1))));
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), automaton::State(label::Label(label::IntegerLabel(1))));
+
+  automaton.addFinalState(automaton::State(label::Label(label::IntegerLabel(1))));
+  
+  automaton::DFA trimed = trim::TrimFSM::trim(automaton);
+
+  CPPUNIT_ASSERT(trimed.getStates().size() == 2);
+}
+
+void trimTest::testTrimGrammar() {
+  grammar::RightRG rrGrammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))));
+
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))));
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))));
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))));
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))));
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5)))));
+  rrGrammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(6)))));
+  rrGrammar.addTerminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  rrGrammar.addTerminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
+  
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))));
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3))))));
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5))))));
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))));
+  rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(6)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(6))))));
+
+  grammar::RightRG trimed = trim::TrimCFG::trim(rrGrammar);
+
+  CPPUNIT_ASSERT(trimed.getNonterminalAlphabet().size() == 3);
+}
diff --git a/alib2algo/test-src/trim/trimTest.h b/alib2algo/test-src/trim/trimTest.h
new file mode 100644
index 0000000000..b23af79d17
--- /dev/null
+++ b/alib2algo/test-src/trim/trimTest.h
@@ -0,0 +1,21 @@
+#ifndef TRIM_TEST_H_
+#define TRIM_TEST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class trimTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( trimTest );
+  CPPUNIT_TEST( testTrimAutomaton );
+  CPPUNIT_TEST( testTrimGrammar );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testTrimAutomaton();
+  void testTrimGrammar();
+};
+
+#endif  // TRIM_TEST_H_
diff --git a/alib2data/src/grammar/ContextFree/CFG.cpp b/alib2data/src/grammar/ContextFree/CFG.cpp
index 3ffeb0635e..6c2eca1b20 100644
--- a/alib2data/src/grammar/ContextFree/CFG.cpp
+++ b/alib2data/src/grammar/ContextFree/CFG.cpp
@@ -69,10 +69,22 @@ bool CFG::addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphab
 	return rules[leftHandSide].insert(rightHandSide).second;
 }
 
-const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> CFG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> & CFG::getRules() const {
 	return rules;
 }
 
+bool CFG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	return addRule(leftHandSide, rightHandSide);
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> CFG::getRawRules() const {
+	return rules;
+}
+
+bool CFG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	return removeRule(leftHandSide, rightHandSide);
+}
+
 bool CFG::removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
 	return rules[leftHandSide].erase(rightHandSide);
 }
diff --git a/alib2data/src/grammar/ContextFree/CFG.h b/alib2data/src/grammar/ContextFree/CFG.h
index 069cefbeab..0132bb0836 100644
--- a/alib2data/src/grammar/ContextFree/CFG.h
+++ b/alib2data/src/grammar/ContextFree/CFG.h
@@ -32,10 +32,16 @@ public:
 
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/ContextFree/CNF.cpp b/alib2data/src/grammar/ContextFree/CNF.cpp
index 8e94c29d35..03da6a5575 100644
--- a/alib2data/src/grammar/ContextFree/CNF.cpp
+++ b/alib2data/src/grammar/ContextFree/CNF.cpp
@@ -93,7 +93,7 @@ bool CNF::addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet
 	return addRule(leftHandSide, rhs);
 }
 
-const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> CNF::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & CNF::getRules() const {
 	return rules;
 }
 
@@ -111,6 +111,58 @@ bool CNF::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alpha
 	return removeRule(leftHandSide, rhs);
 }
 
+bool CNF::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(true);
+		return !res;
+	} else if(rightHandSide.size() == 1) {
+		return addRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return addRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> CNF::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<alphabet::Symbol>()) {
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhs.get<alphabet::Symbol>());
+				res[rule.first].insert(tmp);
+			} else {
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhs.get<std::pair<alphabet::Symbol, alphabet::Symbol>>().first);
+				tmp.push_back(rhs.get<std::pair<alphabet::Symbol, alphabet::Symbol>>().second);
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	if(getGeneratesEpsilon()) {
+		res[getInitialSymbol()].insert(std::vector<alphabet::Symbol> {});
+	}
+	return res;
+}
+
+bool CNF::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else if(rightHandSide.size() == 1) {
+		return removeRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return removeRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
 void CNF::setGeneratesEpsilon(bool genEps) {
 	generatesEpsilon = genEps;
 }
diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h
index c3f33a27ef..cd45d106e5 100644
--- a/alib2data/src/grammar/ContextFree/CNF.h
+++ b/alib2data/src/grammar/ContextFree/CNF.h
@@ -36,12 +36,18 @@ public:
 	bool addRule(const alphabet::Symbol& leftHandSide, const alphabet::Symbol& rightHandSide);
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, alphabet::Symbol>& rightHandSide);
 
-	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const alphabet::Symbol& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
index 4e23cf482f..081e3bddc4 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
@@ -76,7 +76,7 @@ bool EpsilonFreeCFG::addRule(const alphabet::Symbol& leftHandSide, const std::ve
 	}
 }
 
-const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> EpsilonFreeCFG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> & EpsilonFreeCFG::getRules() const {
 	return rules;
 }
 
@@ -84,6 +84,36 @@ bool EpsilonFreeCFG::removeRule(const alphabet::Symbol& leftHandSide, const std:
 	return rules[leftHandSide].erase(rightHandSide);
 }
 
+bool EpsilonFreeCFG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(true);
+		return !res;
+	} else {
+		return addRule(leftHandSide, rightHandSide);
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> EpsilonFreeCFG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res(getRules().begin(), getRules().end());
+	if(getGeneratesEpsilon()) {
+		res[getInitialSymbol()].insert(std::vector<alphabet::Symbol> {});
+	}
+	return rules;
+}
+
+bool EpsilonFreeCFG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else {
+		return removeRule(leftHandSide, rightHandSide);
+	}
+}
+
 void EpsilonFreeCFG::setGeneratesEpsilon(bool genEps) {
 	generatesEpsilon = genEps;
 }
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
index e96e89f4d2..ee3b555469 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
@@ -33,10 +33,16 @@ public:
 
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/ContextFree/GNF.cpp b/alib2data/src/grammar/ContextFree/GNF.cpp
index 0f96349c41..802169e44e 100644
--- a/alib2data/src/grammar/ContextFree/GNF.cpp
+++ b/alib2data/src/grammar/ContextFree/GNF.cpp
@@ -72,7 +72,7 @@ bool GNF::addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet
 	return rules[leftHandSide].insert(rightHandSide).second;
 }
 
-const std::map<alphabet::Symbol, std::set<std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >> > GNF::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >> > & GNF::getRules() const {
 	return rules;
 }
 
@@ -80,6 +80,48 @@ bool GNF::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alpha
 	return rules[leftHandSide].erase(rightHandSide);
 }
 
+bool GNF::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(true);
+		return !res;
+	} else {
+		alphabet::Symbol first = rightHandSide[0];
+		std::vector<alphabet::Symbol> rest(rightHandSide.begin() + 1, rightHandSide.end());
+		return addRule(leftHandSide, std::make_pair(first, rest));
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> GNF::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			std::vector<alphabet::Symbol> tmp;
+			tmp.push_back(rhs.first);
+			tmp.insert(tmp.end(), rhs.second.begin(), rhs.second.end());
+			res[rule.first].insert(tmp);
+		}
+	}
+	if(getGeneratesEpsilon()) {
+		res[getInitialSymbol()].insert(std::vector<alphabet::Symbol> {});
+	}
+	return res;
+}
+
+bool GNF::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else {
+		alphabet::Symbol first = rightHandSide[0];
+		std::vector<alphabet::Symbol> rest(rightHandSide.begin() + 1, rightHandSide.end());
+		return removeRule(leftHandSide, std::make_pair(first, rest));
+	}
+}
+
 void GNF::setGeneratesEpsilon(bool genEps) {
 	generatesEpsilon = genEps;
 }
diff --git a/alib2data/src/grammar/ContextFree/GNF.h b/alib2data/src/grammar/ContextFree/GNF.h
index cb63da3a7d..b81535d0c1 100644
--- a/alib2data/src/grammar/ContextFree/GNF.h
+++ b/alib2data/src/grammar/ContextFree/GNF.h
@@ -33,10 +33,16 @@ public:
 
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >& rightHandSide);
 
-	const std::map<alphabet::Symbol, std::set<std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >> > getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >> > & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, std::vector<alphabet::Symbol> >& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/ContextFree/LG.cpp b/alib2data/src/grammar/ContextFree/LG.cpp
index 10b68bf2f3..630de907b3 100644
--- a/alib2data/src/grammar/ContextFree/LG.cpp
+++ b/alib2data/src/grammar/ContextFree/LG.cpp
@@ -117,6 +117,24 @@ bool LG::addRule(const alphabet::Symbol& leftHandSide, const std::tuple<std::vec
 	return addRule(leftHandSide, rhs);
 }
 
+const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >> > & LG::getRules() const {
+	return rules;
+}
+
+bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >& rightHandSide) {
+	return rules[leftHandSide].erase(rightHandSide);
+}
+
+bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> > rhs(rightHandSide);
+	return removeRule(leftHandSide, rhs);
+}
+
+bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide) {
+	std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> > rhs(rightHandSide);
+	return removeRule(leftHandSide, rhs);
+}
+
 bool LG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
 	std::vector<alphabet::Symbol>::const_iterator nonterminalPosition = rightHandSide.begin();
 	for(; nonterminalPosition != rightHandSide.end(); nonterminalPosition++) {
@@ -130,22 +148,36 @@ bool LG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alph
 	}
 }
 
-const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >> > LG::getRules() const {
-	return rules;
-}
-
-bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >& rightHandSide) {
-	return rules[leftHandSide].erase(rightHandSide);
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> LG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<std::vector<alphabet::Symbol>>()) {
+				res[rule.first].insert(rhs.get<std::vector<alphabet::Symbol>>());
+			} else {
+				const auto& rhsTuple = rhs.get<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>>();
+				std::vector<alphabet::Symbol> tmp;
+				tmp.insert(tmp.end(), std::get<0>(rhsTuple).begin(), std::get<0>(rhsTuple).end());
+				tmp.push_back(std::get<1>(rhsTuple));
+				tmp.insert(tmp.end(), std::get<2>(rhsTuple).begin(), std::get<2>(rhsTuple).end());
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	return res;
 }
 
-bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
-	std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> > rhs(rightHandSide);
-	return removeRule(leftHandSide, rhs);
-}
+bool LG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	std::vector<alphabet::Symbol>::const_iterator nonterminalPosition = rightHandSide.begin();
+	for(; nonterminalPosition != rightHandSide.end(); nonterminalPosition++) {
+		if(nonterminalAlphabet.count(*nonterminalPosition)) break;
+	}
 
-bool LG::removeRule(const alphabet::Symbol& leftHandSide, const std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide) {
-	std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> > rhs(rightHandSide);
-	return removeRule(leftHandSide, rhs);
+	if(nonterminalPosition == rightHandSide.end()) {
+		return removeRule(leftHandSide, rightHandSide);
+	} else {
+		return removeRule(leftHandSide, std::make_tuple(std::vector<alphabet::Symbol>(rightHandSide.begin(), nonterminalPosition), *nonterminalPosition, std::vector<alphabet::Symbol>(nonterminalPosition + 1, rightHandSide.end())));
+	}
 }
 
 bool LG::operator==(const ObjectBase& other) const {
diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h
index 7660ea0dc7..47374f1bba 100644
--- a/alib2data/src/grammar/ContextFree/LG.h
+++ b/alib2data/src/grammar/ContextFree/LG.h
@@ -36,14 +36,18 @@ public:
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide);
 
-	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
-
-	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >> > getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >> > & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::variant<std::vector<alphabet::Symbol>, std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>> >& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.cpp b/alib2data/src/grammar/ContextSensitive/CSG.cpp
index 3271b3a505..77e48595d3 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.cpp
+++ b/alib2data/src/grammar/ContextSensitive/CSG.cpp
@@ -103,7 +103,7 @@ bool CSG::addRule(const std::vector<alphabet::Symbol>& lContext, const alphabet:
 	}
 }
 
-const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> CSG::getRules() const {
+const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> & CSG::getRules() const {
 	return rules;
 }
 
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.h b/alib2data/src/grammar/ContextSensitive/CSG.h
index 34a12e508f..0389c7ffe1 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.h
+++ b/alib2data/src/grammar/ContextSensitive/CSG.h
@@ -32,7 +32,7 @@ public:
 
 	bool addRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
index 5f8b2ea48f..922140c3b9 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
@@ -84,7 +84,7 @@ bool NonContractingGrammar::addRule(const std::vector<alphabet::Symbol>& leftHan
 	return rules[leftHandSide].insert(rightHandSide).second;
 }
 
-const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> NonContractingGrammar::getRules() const {
+const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> & NonContractingGrammar::getRules() const {
 	return rules;
 }
 
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
index 5cf1851fdd..1223f714b6 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
@@ -32,7 +32,7 @@ public:
 
 	bool addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
diff --git a/alib2data/src/grammar/Regular/LeftLG.cpp b/alib2data/src/grammar/Regular/LeftLG.cpp
index 497c488da1..1c66201141 100644
--- a/alib2data/src/grammar/Regular/LeftLG.cpp
+++ b/alib2data/src/grammar/Regular/LeftLG.cpp
@@ -109,17 +109,7 @@ bool LeftLG::addRule(const alphabet::Symbol& leftHandSide, const std::pair<alpha
 	return addRule(leftHandSide, rhs);
 }
 
-bool LeftLG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
-	if(rightHandSide.size() == 0) {
-		return addRule(leftHandSide, rightHandSide);
-	} else if(nonterminalAlphabet.count(rightHandSide[0])) {
-		return addRule(leftHandSide, std::make_pair(rightHandSide[0], std::vector<alphabet::Symbol>(rightHandSide.begin() + 1, rightHandSide.end())));
-	} else {
-		return addRule(leftHandSide, rightHandSide);
-	}
-}
-
-const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>> >> > LeftLG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>> >> > & LeftLG::getRules() const {
 	return rules;
 }
 
@@ -137,6 +127,44 @@ bool LeftLG::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<al
 	return removeRule(leftHandSide, rhs);
 }
 
+bool LeftLG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		return addRule(leftHandSide, rightHandSide);
+	} else if(nonterminalAlphabet.count(rightHandSide[0])) {
+		return addRule(leftHandSide, std::make_pair(rightHandSide[0], std::vector<alphabet::Symbol>(rightHandSide.begin() + 1, rightHandSide.end())));
+	} else {
+		return addRule(leftHandSide, rightHandSide);
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> LeftLG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<std::vector<alphabet::Symbol>>()) {
+				res[rule.first].insert(rhs.get<std::vector<alphabet::Symbol>>());
+			} else {
+				const auto& rhsTuple = rhs.get<std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>>>();
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhsTuple.first);
+				tmp.insert(tmp.end(), rhsTuple.second.begin(), rhsTuple.second.end());
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	return res;
+}
+
+bool LeftLG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		return removeRule(leftHandSide, rightHandSide);
+	} else if(nonterminalAlphabet.count(rightHandSide[0])) {
+		return removeRule(leftHandSide, std::make_pair(rightHandSide[0], std::vector<alphabet::Symbol>(rightHandSide.begin() + 1, rightHandSide.end())));
+	} else {
+		return removeRule(leftHandSide, rightHandSide);
+	}
+}
+
 bool LeftLG::operator==(const ObjectBase& other) const {
 	return other == *this;
 }
diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h
index cf5db657e9..00cc4eab63 100644
--- a/alib2data/src/grammar/Regular/LeftLG.h
+++ b/alib2data/src/grammar/Regular/LeftLG.h
@@ -34,14 +34,18 @@ public:
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide);
 
-	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
-
-	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>> >> > getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>> >> > & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::variant<std::vector<alphabet::Symbol>, std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>> >& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, std::vector<alphabet::Symbol>>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/Regular/LeftRG.cpp b/alib2data/src/grammar/Regular/LeftRG.cpp
index 2c16f35f73..3f789ea2cb 100644
--- a/alib2data/src/grammar/Regular/LeftRG.cpp
+++ b/alib2data/src/grammar/Regular/LeftRG.cpp
@@ -90,7 +90,7 @@ bool LeftRG::addRule(const alphabet::Symbol& leftHandSide, const std::pair<alpha
 	return addRule(leftHandSide, rhs);
 }
 
-const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> LeftRG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & LeftRG::getRules() const {
 	return rules;
 }
 
@@ -108,6 +108,59 @@ bool LeftRG::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<al
 	return removeRule(leftHandSide, rhs);
 }
 
+bool LeftRG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else if(rightHandSide.size() == 1) {
+		return addRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return addRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> LeftRG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<alphabet::Symbol>()) {
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhs.get<alphabet::Symbol>());
+				res[rule.first].insert(tmp);
+			} else {
+				const auto& rhsPair = rhs.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhsPair.first);
+				tmp.push_back(rhsPair.second);
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	if(getGeneratesEpsilon()) {
+		res[getInitialSymbol()].insert(std::vector<alphabet::Symbol> {});
+	}
+	return res;
+}
+
+bool LeftRG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else if(rightHandSide.size() == 1) {
+		return removeRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return removeRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
 void LeftRG::setGeneratesEpsilon(bool genEps) {
 	generatesEpsilon = genEps;
 }
diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h
index 409b6aaf97..e4c5470a89 100644
--- a/alib2data/src/grammar/Regular/LeftRG.h
+++ b/alib2data/src/grammar/Regular/LeftRG.h
@@ -10,6 +10,7 @@
 
 #include "../GrammarBase.h"
 #include <map>
+#include <vector>
 #include "../../std/variant.hpp"
 #include "../common/TerminalNonterminalAlphabetInitialSymbol.h"
 
@@ -76,7 +77,7 @@ public:
 	/**
 	 * Get rules of the grammar
 	 */
-	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & getRules() const;
 
 	/**
 	 * Add a new rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T
@@ -93,6 +94,12 @@ public:
 	 */
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	/**
 	 * @copydoc TerminalNonterminalAlphabetInitialSymbol::removeTerminalSymbol()
 	 */
diff --git a/alib2data/src/grammar/Regular/RightLG.cpp b/alib2data/src/grammar/Regular/RightLG.cpp
index 48604cb83a..08faa71a17 100644
--- a/alib2data/src/grammar/Regular/RightLG.cpp
+++ b/alib2data/src/grammar/Regular/RightLG.cpp
@@ -109,17 +109,7 @@ bool RightLG::addRule(const alphabet::Symbol& leftHandSide, const std::pair<std:
 	return addRule(leftHandSide, rhs);
 }
 
-bool RightLG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
-	if(rightHandSide.size() == 0) {
-		return addRule(leftHandSide, rightHandSide);
-	} else if(nonterminalAlphabet.count(rightHandSide[rightHandSide.size() - 1])) {
-		return addRule(leftHandSide, std::make_pair(std::vector<alphabet::Symbol>(rightHandSide.begin(), rightHandSide.end() - 1), rightHandSide[rightHandSide.size() - 1]));
-	} else {
-		return addRule(leftHandSide, rightHandSide);
-	}
-}
-
-const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol> >> > RightLG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol> >> > & RightLG::getRules() const {
 	return rules;
 }
 
@@ -137,6 +127,44 @@ bool RightLG::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<s
 	return removeRule(leftHandSide, rhs);
 }
 
+bool RightLG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		return addRule(leftHandSide, rightHandSide);
+	} else if(nonterminalAlphabet.count(rightHandSide[rightHandSide.size() - 1])) {
+		return addRule(leftHandSide, std::make_pair(std::vector<alphabet::Symbol>(rightHandSide.begin(), rightHandSide.end() - 1), rightHandSide[rightHandSide.size() - 1]));
+	} else {
+		return addRule(leftHandSide, rightHandSide);
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> RightLG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<std::vector<alphabet::Symbol>>()) {
+				res[rule.first].insert(rhs.get<std::vector<alphabet::Symbol>>());
+			} else {
+				const auto& rhsTuple = rhs.get<std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol>>();
+				std::vector<alphabet::Symbol> tmp;
+				tmp.insert(tmp.end(), rhsTuple.first.begin(), rhsTuple.first.end());
+				tmp.push_back(rhsTuple.second);
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	return res;
+}
+
+bool RightLG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		return removeRule(leftHandSide, rightHandSide);
+	} else if(nonterminalAlphabet.count(rightHandSide[rightHandSide.size() - 1])) {
+		return removeRule(leftHandSide, std::make_pair(std::vector<alphabet::Symbol>(rightHandSide.begin(), rightHandSide.end() - 1), rightHandSide[rightHandSide.size() - 1]));
+	} else {
+		return removeRule(leftHandSide, rightHandSide);
+	}
+}
+
 bool RightLG::operator==(const ObjectBase& other) const {
 	return other == *this;
 }
diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h
index 1cadeeba57..ffe784f00c 100644
--- a/alib2data/src/grammar/Regular/RightLG.h
+++ b/alib2data/src/grammar/Regular/RightLG.h
@@ -34,14 +34,18 @@ public:
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol>& rightHandSide);
 
-	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
-
-	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol> >> > getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<std::vector<alphabet::Symbol>, std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol> >> > & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::variant<std::vector<alphabet::Symbol>, std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol> >& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<std::vector<alphabet::Symbol>, alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/Regular/RightRG.cpp b/alib2data/src/grammar/Regular/RightRG.cpp
index c1c357de8e..07eb323a39 100644
--- a/alib2data/src/grammar/Regular/RightRG.cpp
+++ b/alib2data/src/grammar/Regular/RightRG.cpp
@@ -90,7 +90,7 @@ bool RightRG::addRule(const alphabet::Symbol& leftHandSide, const std::pair<alph
 	return addRule(leftHandSide, rhs);
 }
 
-const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> RightRG::getRules() const {
+const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & RightRG::getRules() const {
 	return rules;
 }
 
@@ -108,6 +108,59 @@ bool RightRG::removeRule(const alphabet::Symbol& leftHandSide, const std::pair<a
 	return removeRule(leftHandSide, rhs);
 }
 
+bool RightRG::addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else if(rightHandSide.size() == 1) {
+		return addRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return addRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
+std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> RightRG::getRawRules() const {
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> res;
+	for(const auto& rule : getRules()) {
+		for(const auto& rhs : rule.second) {
+			if(rhs.is<alphabet::Symbol>()) {
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhs.get<alphabet::Symbol>());
+				res[rule.first].insert(tmp);
+			} else {
+				const auto& rhsPair = rhs.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				std::vector<alphabet::Symbol> tmp;
+				tmp.push_back(rhsPair.first);
+				tmp.push_back(rhsPair.second);
+				res[rule.first].insert(tmp);
+			}
+		}
+	}
+	if(getGeneratesEpsilon()) {
+		res[getInitialSymbol()].insert(std::vector<alphabet::Symbol> {});
+	}
+	return res;
+}
+
+bool RightRG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	if(rightHandSide.size() == 0) {
+		if(leftHandSide != initialSymbol) throw exception::AlibException("Illegal left hand side of epsilon rule");
+		bool res = getGeneratesEpsilon();
+		setGeneratesEpsilon(false);
+		return res;
+	} else if(rightHandSide.size() == 1) {
+		return removeRule(leftHandSide, rightHandSide[0]);
+	} else if(rightHandSide.size() == 2) {
+		return removeRule(leftHandSide, std::make_pair(rightHandSide[0], rightHandSide[1]));
+	} else {
+		throw exception::AlibException("Invalid right hand side");
+	}
+}
+
 void RightRG::setGeneratesEpsilon(bool genEps) {
 	generatesEpsilon = genEps;
 }
diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h
index 4073501e4e..3182e4f463 100644
--- a/alib2data/src/grammar/Regular/RightRG.h
+++ b/alib2data/src/grammar/Regular/RightRG.h
@@ -10,6 +10,7 @@
 
 #include "../GrammarBase.h"
 #include <map>
+#include <vector>
 #include "../../std/variant.hpp"
 #include "../common/TerminalNonterminalAlphabetInitialSymbol.h"
 
@@ -50,12 +51,18 @@ public:
 	bool addRule(const alphabet::Symbol& leftHandSide, const alphabet::Symbol& rightHandSide);
 	bool addRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, alphabet::Symbol>& rightHandSide);
 
-	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> getRules() const;
+	const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>>> & getRules() const;
 
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::variant<alphabet::Symbol, std::pair<alphabet::Symbol, alphabet::Symbol>>& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const alphabet::Symbol& rightHandSide);
 	bool removeRule(const alphabet::Symbol& leftHandSide, const std::pair<alphabet::Symbol, alphabet::Symbol>& rightHandSide);
 
+	bool addRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> getRawRules() const;
+
+	bool removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
 	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
diff --git a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
index ef7b540687..f600000099 100644
--- a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
+++ b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
@@ -97,7 +97,7 @@ bool ContextPreservingUnrestrictedGrammar::addRule(const std::vector<alphabet::S
 	return rules[make_tuple(lContext, leftHandSide, rContext)].insert(rightHandSide).second;
 }
 
-const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> ContextPreservingUnrestrictedGrammar::getRules() const {
+const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> & ContextPreservingUnrestrictedGrammar::getRules() const {
 	return rules;
 }
 
diff --git a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
index f35bfa3d98..958478e057 100644
--- a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
@@ -31,7 +31,7 @@ public:
 
 	bool addRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
diff --git a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
index f653dd4800..e5417bac4b 100644
--- a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
+++ b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
@@ -78,7 +78,7 @@ bool UnrestrictedGrammar::addRule(const std::vector<alphabet::Symbol>& leftHandS
 	return rules[leftHandSide].insert(rightHandSide).second;
 }
 
-const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> UnrestrictedGrammar::getRules() const {
+const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> & UnrestrictedGrammar::getRules() const {
 	return rules;
 }
 
diff --git a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
index 9b15d7c84e..bcb7f71437 100644
--- a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
@@ -32,7 +32,7 @@ public:
 
 	bool addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
-	const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+	const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> & getRules() const;
 
 	bool removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
 
diff --git a/atrim/makefile b/atrim/makefile
index 4a13ffc802..0ae3f4208e 100644
--- a/atrim/makefile
+++ b/atrim/makefile
@@ -1,20 +1,73 @@
-CC=g++
-EXECUTABLE=atrim
-CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -I/usr/include/libxml2/
-LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,.
+SHELL:=/bin/bash
+EXECUTABLE:=aepsilon2
 
-SOURCES=$(shell find src/ -name *cpp)
-OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
+LDFLAGS= -L../alib2data/lib -L../alib2algo/lib -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
 
-all: $(SOURCES) bin/$(EXECUTABLE)
+OBJECTS:=$(patsubst src/%.cpp, obj/%.o, $(shell find src/ -name *cpp))
 
-bin/$(EXECUTABLE): $(OBJECTS)
+.PHONY: all build clean
+
+all: build
+
+
+
+bin/$(EXECUTABLE): obj/ $(OBJECTS)
 	mkdir -p bin
-	$(CC) $(OBJECTS) -o $@ $(LDFLAGS)
+	$(CXX) $(OBJECTS) -o $@ $(LDFLAGS)
 
-obj/%.o: src/%.cpp
+obj/makefile: makefile
 	mkdir -p $(dir $@)
-	$(CC) $(CCFLAGS) $< -o $@
+	echo "SHELL:=/bin/bash" >> $@
+	echo "SRCDIR:=" >> $@
+	echo "DEPTH:=" >> $@
+	echo "" >> $@
+	echo "CXXFLAGS:= -std=c++11 -Og -g -c -Wall -pedantic -Wextra -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src -I/usr/include/libxml2/" >> $@
+	echo "" >> $@
+	echo "SOURCES:= \$$(shell find ../\$$(DEPTH)src/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")" >> $@
+	echo "DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)obj/\$$(SRCDIR)%.d, \$$(SOURCES))" >> $@
+	echo "OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))" >> $@
+	echo "SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)src/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)" >> $@
+	echo "OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)src/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))" >> $@
+	echo "OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))" >> $@
+	echo "" >> $@
+	echo ".PHONY: all" >> $@
+	echo ".PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)" >> $@
+	echo "" >> $@
+	echo "all: \$$(OBJECTS_DIRS) \$$(OBJECTS)" >> $@
+	echo "" >> $@
+	echo "%.d:" >> $@
+	echo "	@echo \"\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)obj/\$$(SRCDIR)%.d,../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)obj/\$$(SRCDIR)%.d,../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\" >> \$$@" >> $@
+	echo "	@echo \"\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\"))\" >> \$$@" >> $@
+	echo "	@echo \"	\\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\" >> \$$@" >> $@
+	echo "" >> $@
+	echo "%/makefile:" >> $@
+	echo "	mkdir -p \$$(dir \$$@)" >> $@
+	echo "	cp makefile \$$@" >> $@
+	echo "" >> $@
+	echo "%/: FORCE | %/makefile" >> $@
+	echo "	@accesstime=\`stat -c %Y \$$@\` && \\" >> $@
+	echo "	\$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ && \\" >> $@
+	echo "	accesstime2=\`stat -c %Y \$$@\` && \\" >> $@
+	echo "	if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\" >> $@
+	echo "		touch .; \\" >> $@
+	echo "	fi" >> $@
+	echo "" >> $@
+	echo "FORCE:" >> $@
+	echo "" >> $@
+	echo "-include \$$(DEPENDENCIES)" >> $@
+
+obj/: FORCE | obj/makefile
+	$(MAKE) -C $@
+
+$(OBJECTS): obj/
+
+
+build: bin/$(EXECUTABLE)
+
+
 
 clean:
-	$(RM) -r *.o *.d bin obj
+	$(RM) -r *.o *.d bin lib obj test-bin test-obj
+
+FORCE:
+
diff --git a/atrim/src/automaton/TrimFSM.cpp b/atrim/src/automaton/TrimFSM.cpp
deleted file mode 100644
index f28a1a0823..0000000000
--- a/atrim/src/automaton/TrimFSM.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * TrimFSM.cpp
- *
- *  Created on: 23. 3. 2014
- *      Author: tomas
- */
-
-#include "TrimFSM.h"
-
-using namespace alib;
-using namespace automaton;
-using namespace std;
-
-FSM TrimFSM::removeUselessStates( const FSM & fsm )
-{
-    // 1a
-    deque<set<State>> Qi;
-    Qi.push_back( set<State>( ) );
-    Qi.at( 0 ) = fsm.getFinalStates( );
-
-    int i = 1;
-
-    // 1bc
-    while( true )
-    {
-        Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
-        for( const auto & p : Qi.at( i - 1 ) )
-            for( const auto & t : fsm.getTransitionsToState( p ) )
-                Qi.at( i ).insert( t.getFrom( ) );
-
-        if( Qi.at( i ) == Qi.at( i - 1 ) )
-            break;
-
-        i = i + 1;
-    }
-    const set<State> Qu = Qi.at( i );
-
-    // 2.
-
-    FSM M;
-
-    for( const auto & q : Qu )
-        M.addState( q );
-
-    for( const auto & a : fsm.getInputAlphabet( ) )
-        M.addInputSymbol( a );
-
-    for( const auto & t : fsm.getTransitions( ) )
-    {
-        if( isInSet( t.getFrom( ), Qu ) && isInSet( t.getTo( ), Qu ) )
-        {
-            M.addTransition( t );
-        }
-    }
-
-    for( const auto & q : fsm.getInitialStates( ) )
-        M.addInitialState( q );
-
-    for( const auto & q : fsm.getFinalStates( ) )
-        M.addFinalState( q );
-
-    return M;
-}
-
-
-FSM TrimFSM::removeUnreachableStates( const FSM & fsm )
-{
-    if( fsm.getInitialStates( ).size( ) != 1 )
-        throw AlibException( "NFA must have exactly one initial state." );
-
-    // 1a
-    deque<set<State>> Qi;
-    Qi.push_back( set<State>( ) );
-    Qi.at( 0 ).insert( * fsm.getInitialStates( ).begin( ) );
-
-    int i = 1;
-
-    // 1bc
-    while( true )
-    {
-        Qi.push_back( Qi.at( i - 1 ) );
-
-        for( const auto & p : Qi.at( i - 1 ) )
-        {
-            for( const auto & transition : fsm.getTransitionsFromState( p ) )
-            {
-                Qi.at( i ).insert( transition.getTo( ) );
-            }
-        }
-
-        if( Qi.at( i ) == Qi.at( i - 1 ) )
-            break;
-
-        i = i + 1;
-    }
-
-    const set<State> Qa = Qi.at( i );
-
-
-    // 2
-
-    FSM M;
-
-    for( const auto & q : Qa )
-        M.addState( q );
-    for( const auto & a : fsm.getInputAlphabet( ) )
-        M.addInputSymbol( a );
-
-    for( const auto & transition : fsm.getTransitions( ) )
-        if( isInSet( transition.getFrom( ), Qa ) )
-            M.addTransition( transition );
-
-    M.addInitialState( * fsm.getInitialStates( ).begin( ) );
-
-    set<State> intersect;
-    set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), inserter( intersect, intersect.begin( ) ) );
-    for( auto const & state : intersect )
-        M.addFinalState( state );
-
-    return M;
-}
diff --git a/atrim/src/automaton/TrimFSM.h b/atrim/src/automaton/TrimFSM.h
deleted file mode 100644
index 394104d8f5..0000000000
--- a/atrim/src/automaton/TrimFSM.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * TrimFSM.h
- *
- *  Created on: 23. 3. 2014
- *      Author: tomas
- */
-
-#ifndef TRIMFSM_H_
-#define TRIMFSM_H_
-
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <AlibException.h>
-#include <automaton/FSM/FSM.h>
-
-#define isInSet(x,set) ( (set).find((x)) != (set).end())
-
-class TrimFSM
-{
-public:
-    /**
-     * Removes dead states from FSM. Melichar 2.32
-     */
-    static automaton::FSM removeUselessStates( const automaton::FSM & fsm );
-
-    /**
-     * Removes dead states from FSM. Melichar 2.29
-     */
-    static automaton::FSM removeUnreachableStates( const automaton::FSM & fsm );
-};
-
-#endif /* TRIMFSM_H_ */
diff --git a/atrim/src/grammar/ContextFreeGrammarTransformations.cpp b/atrim/src/grammar/ContextFreeGrammarTransformations.cpp
deleted file mode 100644
index aa4af83ded..0000000000
--- a/atrim/src/grammar/ContextFreeGrammarTransformations.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * ContextFreeGrammarTransformations.cpp
- *
- *  Created on: 22. 3. 2014
- *      Author: tomas
- */
-
-#include "ContextFreeGrammarTransformations.h"
-
-using namespace alib;
-using namespace grammar;
-using namespace std;
-
-set<Symbol> ContextFreeGrammarTransformations::getProductiveNonTerminals( const ContextFreeGrammar & grammar )
-{
-    // 1.
-    deque<set<Symbol>> Ni;
-    Ni.push_back( set<Symbol>( ) );
-
-    int i = 1;
-
-    // 2.
-    while( true )
-    {
-        Ni.push_back( Ni.at( i - 1 ) );
-
-        for( const auto & rule : grammar.getRules( ) )
-        {
-            if( all_of( rule.getRightSide( ).begin( ), rule.getRightSide( ).end( ), [ i, Ni, grammar ]( Symbol const& symbol ) -> bool {
-                return isInSet( symbol, Ni.at( i - 1 ) ) || isInSet( symbol, grammar.getTerminalSymbols( ) );
-            } ) )
-                Ni.at( i ).insert( rule.getLeftSide( ).front( ) );
-        }
-
-        if( Ni.at( i ) == Ni.at( i - 1 ) )
-            break;
-
-        i = i + 1;
-    }
-
-    // 3.
-    return Ni.at( i );
-}
-
-bool ContextFreeGrammarTransformations::isLanguageEmpty( const grammar::ContextFreeGrammar & grammar )
-{
-    return isInSet( grammar.getStartSymbol( ), getProductiveNonTerminals( grammar ) );
-}
-
-ContextFreeGrammar ContextFreeGrammarTransformations::removeUnreachableSymbols( const ContextFreeGrammar & grammar )
-{
-    // 1
-    deque<set<Symbol>> Vi;
-    Vi.push_back( set<Symbol>( ) );
-    Vi.at( 0 ).insert( grammar.getStartSymbol( ) );
-
-    int i = 1;
-
-    // 2.
-    while( true )
-    {
-        Vi.push_back( Vi.at( i - 1 ) );
-
-        for( const auto & rule : grammar.getRules( ) )
-        {
-            if( isInSet( rule.getLeftSide( ).front( ), Vi.at( i - 1 ) ) )
-            {
-                Vi.at( i ).insert( rule.getRightSide( ).begin( ), rule.getRightSide( ).end( ) );
-            }
-        }
-
-
-        if( Vi.at( i ) == Vi.at( i - 1 ) )
-            break;
-
-        i = i + 1;
-    }
-
-    // 3.
-    ContextFreeGrammar ret;
-
-    set<Symbol> newNonTerminals, newTerminals;
-
-    set_intersection( Vi.at( i ).begin( ), Vi.at( i ).end( ), grammar.getNonTerminalSymbols( ).begin( ), grammar.getNonTerminalSymbols( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) );
-    for( const auto & symbol : newNonTerminals )
-        ret.addNonTerminalSymbol( symbol );
-
-    set_intersection( Vi.at( i ).begin( ), Vi.at( i ).end( ), grammar.getTerminalSymbols( ).begin( ), grammar.getTerminalSymbols( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) );
-    for( const auto & symbol : newTerminals )
-        ret.addTerminalSymbol( symbol );
-
-    // A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P
-    for( const auto & rule : grammar.getRules( ) )
-    {
-        if( isInSet( rule.getLeftSide( ).front( ) , newNonTerminals ) && all_of( rule.getRightSide( ).begin( ), rule.getRightSide( ).end( ), [ Vi, i ]( Symbol const& symb ) -> bool {
-            return isInSet( symb, Vi.at( i ) );
-        } ) )
-        {
-            ret.addRule( rule );
-        }
-    }
-
-    ret.setStartSymbol( grammar.getStartSymbol( ) );
-
-    return ret;
-}
-
-ContextFreeGrammar ContextFreeGrammarTransformations::removeUnproductiveSymbols( const ContextFreeGrammar & grammar )
-{
-    // 1.
-    set<Symbol> Nt = getProductiveNonTerminals( grammar );
-
-    ContextFreeGrammar G1;
-
-    for( const auto & symbol : Nt )
-        G1.addNonTerminalSymbol( symbol );
-
-    for( const auto & symbol : grammar.getTerminalSymbols( ) )
-        G1.addTerminalSymbol( symbol );
-
-    const set<Symbol> & T = G1.getTerminalSymbols( );
-    for( const auto & rule : grammar.getRules( ) )
-    {
-        if( isInSet( rule.getLeftSide( ).front( ), Nt ) &&
-            all_of( rule.getRightSide( ).begin( ), rule.getRightSide( ).end( ), [ Nt, T ]( const Symbol & symbol ){ return isInSet( symbol, Nt ) || isInSet( symbol, T ); } ) )
-        {
-            G1.addRule( rule );
-        }
-    }
-
-    if( ! isInSet( grammar.getStartSymbol( ), G1.getNonTerminalSymbols( ) ) )
-        throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." );
-
-    G1.setStartSymbol( grammar.getStartSymbol( ) );
-
-    // 2.
-    return removeUnreachableSymbols( G1 );
-}
diff --git a/atrim/src/grammar/ContextFreeGrammarTransformations.h b/atrim/src/grammar/ContextFreeGrammarTransformations.h
deleted file mode 100644
index 3745b0776c..0000000000
--- a/atrim/src/grammar/ContextFreeGrammarTransformations.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ContextFreeGrammarTransformations.h
- *
- *  Created on: 22. 3. 2014
- *      Author: tomas
- */
-
-#ifndef CONTEXTFREEGRAMMARTRANSFORMATIONS_H_
-#define CONTEXTFREEGRAMMARTRANSFORMATIONS_H_
-
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <AlibException.h>
-#include <grammar/ContextFree/ContextFreeGrammar.h>
-
-#define isInSet(x,set) ( (set).find((x)) != (set).end())
-
-/**
- * Implements algorithms from Melichar, chapter 3.3
- */
-class ContextFreeGrammarTransformations
-{
-public:
-    /*
-     * Melichar 3.6 - decides whether L( grammar ) = \0
-     *
-     * Severals steps implemented in method ContextFreeGrammarTransformations::getProductiveNonTerminals();
-     * @see getProductiveNonTerminals
-     */
-    static bool isLanguageEmpty( const grammar::ContextFreeGrammar & grammar );
-
-    /*
-     * Removes unreachable symbols - Melichar 3.9
-     */
-    static grammar::ContextFreeGrammar removeUnreachableSymbols( const grammar::ContextFreeGrammar & grammar );
-
-    /**
-     * Removes unproductive (or useless - terminology) symbols - Melichar 3.12
-     */
-    static grammar::ContextFreeGrammar removeUnproductiveSymbols( const grammar::ContextFreeGrammar & grammar );
-
-private:
-    /**
-     * Implements steps 1 through 3 in Melichar 3.6
-     */
-    static std::set<alphabet::Symbol> getProductiveNonTerminals( const grammar::ContextFreeGrammar & grammar );
-};
-
-#endif /* CONTEXTFREEGRAMMARTRANSFORMATIONS_H_ */
-- 
GitLab