From 4dc06b480793850df0dd02276a5de5e4d22dc063 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 14 Sep 2016 09:32:22 +0200
Subject: [PATCH] template CNF grammar

---
 acompare2/src/GrammarCompare.cpp              |   8 +-
 acompare2/src/GrammarCompare.h                |   6 +-
 .../grammar/generate/CockeYoungerKasami.cpp   |   4 +-
 .../src/grammar/generate/CockeYoungerKasami.h |   2 +-
 .../grammar/generate/GenerateUpToLength.cpp   |   2 +-
 alib2algo/src/grammar/parsing/First.cpp       |   4 +-
 alib2algo/src/grammar/parsing/Follow.cpp      |   4 +-
 .../src/grammar/parsing/LL1ParseTable.cpp     |   2 +-
 .../grammar/properties/IsLanguageEmpty.cpp    |   2 +-
 .../IsLanguageGeneratingEpsilon.cpp           |   2 +-
 .../properties/NonterminalUnitRuleCycle.cpp   |   2 +-
 .../properties/NullableNonterminals.cpp       |   2 +-
 .../properties/ProductiveNonterminals.cpp     |   2 +-
 .../properties/RecursiveNonterminal.cpp       |   2 +-
 .../grammar/properties/UnreachableSymbols.cpp |   2 +-
 .../src/grammar/simplify/EpsilonRemover.cpp   |   4 +-
 .../src/grammar/simplify/EpsilonRemover.h     |   2 +-
 .../grammar/simplify/LeftRecursionRemover.cpp |   4 +-
 .../grammar/simplify/LeftRecursionRemover.h   |   2 +-
 .../grammar/simplify/SimpleRulesRemover.cpp   |   4 +-
 .../src/grammar/simplify/SimpleRulesRemover.h |   2 +-
 alib2algo/src/grammar/simplify/ToCNF.cpp      |  40 +-
 alib2algo/src/grammar/simplify/ToCNF.h        |  18 +-
 alib2algo/src/grammar/simplify/ToGNF.cpp      |   4 +-
 alib2algo/src/grammar/simplify/ToGNF.h        |   2 +-
 alib2algo/src/grammar/simplify/Trim.cpp       |   2 +-
 .../simplify/UnproductiveSymbolsRemover.cpp   |   2 +-
 .../simplify/UnreachableSymbolsRemover.cpp    |   2 +-
 .../grammar/simplify/GrammarToCNFTest.cpp     |   8 +-
 alib2data/src/grammar/ContextFree/CNF.cpp     | 229 +----------
 alib2data/src/grammar/ContextFree/CNF.h       | 360 +++++++++++++++---
 alib2data/src/grammar/GrammarFeatures.h       |   1 +
 alib2data/test-src/grammar/GrammarTest.cpp    |   4 +-
 .../src/grammar/GrammarFromStringParser.cpp   |   4 +-
 .../src/grammar/GrammarFromStringParser.h     |   2 +-
 .../src/grammar/GrammarToStringComposer.cpp   |   4 +-
 .../src/grammar/GrammarToStringComposer.h     |   2 +-
 37 files changed, 384 insertions(+), 364 deletions(-)

diff --git a/acompare2/src/GrammarCompare.cpp b/acompare2/src/GrammarCompare.cpp
index a963e8733c..0d17824838 100644
--- a/acompare2/src/GrammarCompare.cpp
+++ b/acompare2/src/GrammarCompare.cpp
@@ -79,7 +79,7 @@ bool GrammarCompare::testCompare(const grammar::EpsilonFreeCFG& a, const grammar
 			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    ;
 }
 
-bool GrammarCompare::testCompare(const grammar::CNF& a, const grammar::CNF& b) {
+bool GrammarCompare::testCompare(const grammar::CNF < > & a, const grammar::CNF < > & b) {
 	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
 			a.getRules()               == b.getRules()               &&
 			a.getInitialSymbol()       == b.getInitialSymbol()       &&
@@ -379,7 +379,7 @@ void GrammarCompare::printCompare(const grammar::EpsilonFreeCFG& a, const gramma
 	}
 }
 
-void GrammarCompare::printCompare(const grammar::CNF& a, const grammar::CNF& b) {
+void GrammarCompare::printCompare(const grammar::CNF < > & a, const grammar::CNF < > & b) {
 	std::cout << "GrammarCompareer" << std::endl;
 
 	if(a.getNonterminalAlphabet() != b.getNonterminalAlphabet()) {
@@ -636,7 +636,7 @@ int GrammarCompare::compare(const grammar::EpsilonFreeCFG& a, const grammar::Eps
 
 auto GrammarCompareEpsilonFreeCFG = GrammarCompare::RegistratorWrapper<int, grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(GrammarCompare::compare);
 
-int GrammarCompare::compare(const grammar::CNF& a, const grammar::CNF& b) {
+int GrammarCompare::compare(const grammar::CNF < > & a, const grammar::CNF < > & b) {
 	if(!GrammarCompare::testCompare(a, b)) {
 	  GrammarCompare::printCompare(a, b);
 	  return 1;
@@ -645,7 +645,7 @@ int GrammarCompare::compare(const grammar::CNF& a, const grammar::CNF& b) {
 	}
 }
 
-auto GrammarCompareCNF = GrammarCompare::RegistratorWrapper<int, grammar::CNF, grammar::CNF>(GrammarCompare::compare);
+auto GrammarCompareCNF = GrammarCompare::RegistratorWrapper<int, grammar::CNF < >, grammar::CNF < > >(GrammarCompare::compare);
 
 int GrammarCompare::compare(const grammar::GNF& a, const grammar::GNF& b) {
 	if(!GrammarCompare::testCompare(a, b)) {
diff --git a/acompare2/src/GrammarCompare.h b/acompare2/src/GrammarCompare.h
index 7bb70fef34..04706ec611 100644
--- a/acompare2/src/GrammarCompare.h
+++ b/acompare2/src/GrammarCompare.h
@@ -41,8 +41,8 @@ private:
 	static bool testCompare(const grammar::EpsilonFreeCFG& a, const grammar::EpsilonFreeCFG& b);
 	static void printCompare(const grammar::EpsilonFreeCFG& a, const grammar::EpsilonFreeCFG& b);
 
-	static bool testCompare(const grammar::CNF& a, const grammar::CNF& b);
-	static void printCompare(const grammar::CNF& a, const grammar::CNF& b);
+	static bool testCompare(const grammar::CNF < > & a, const grammar::CNF < > & b);
+	static void printCompare(const grammar::CNF < > & a, const grammar::CNF < > & b);
 
 	static bool testCompare(const grammar::GNF& a, const grammar::GNF& b);
 	static void printCompare(const grammar::GNF& a, const grammar::GNF& b);
@@ -70,7 +70,7 @@ public:
 	static int compare(const grammar::LG& a, const grammar::LG& b);
 	static int compare(const grammar::CFG < > & a, const grammar::CFG < > & b);
 	static int compare(const grammar::EpsilonFreeCFG& a, const grammar::EpsilonFreeCFG& b);
-	static int compare(const grammar::CNF& a, const grammar::CNF& b);
+	static int compare(const grammar::CNF < > & a, const grammar::CNF < > & b);
 	static int compare(const grammar::GNF& a, const grammar::GNF& b);
 	static int compare(const grammar::CSG& a, const grammar::CSG& b);
 	static int compare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b);
diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp b/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp
index 76e4b3b977..76c1ae8dc4 100644
--- a/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp
+++ b/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp
@@ -12,7 +12,7 @@ namespace grammar {
 
 namespace generate {
 
-bool CockeYoungerKasami::generate ( const grammar::CNF & grammar, const string::LinearString < > & string ) {
+bool CockeYoungerKasami::generate ( const grammar::CNF < > & grammar, const string::LinearString < > & string ) {
 	unsigned stringSize = string.getContent ( ).size ( );
 
 	if ( ( stringSize == 0 ) && grammar.getGeneratesEpsilon ( ) ) return true;
@@ -76,7 +76,7 @@ bool CockeYoungerKasami::generate ( const grammar::CNF & grammar, const string::
 	return data[stringSize - 1][0].count ( grammar.getInitialSymbol ( ) );
 }
 
-auto CockeYoungerKasamiCNF = CockeYoungerKasami::RegistratorWrapper < bool, grammar::CNF > ( CockeYoungerKasami::generate );
+auto CockeYoungerKasamiCNF = CockeYoungerKasami::RegistratorWrapper < bool, grammar::CNF < > > ( CockeYoungerKasami::generate );
 
 bool CockeYoungerKasami::generate ( const grammar::Grammar & grammar, const string::LinearString < > & string ) {
 	return dispatch ( grammar.getData ( ), string );
diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasami.h b/alib2algo/src/grammar/generate/CockeYoungerKasami.h
index 147778863c..8926099d0a 100644
--- a/alib2algo/src/grammar/generate/CockeYoungerKasami.h
+++ b/alib2algo/src/grammar/generate/CockeYoungerKasami.h
@@ -25,7 +25,7 @@ class CockeYoungerKasami : public std::SingleDispatch < CockeYoungerKasami, bool
 public:
 	static bool generate ( const grammar::Grammar & grammar, const string::LinearString < > & string );
 
-	static bool generate ( const grammar::CNF & grammar, const string::LinearString < > & string );
+	static bool generate ( const grammar::CNF < > & grammar, const string::LinearString < > & string );
 
 };
 
diff --git a/alib2algo/src/grammar/generate/GenerateUpToLength.cpp b/alib2algo/src/grammar/generate/GenerateUpToLength.cpp
index 93631bb7b1..d73c8f9a93 100644
--- a/alib2algo/src/grammar/generate/GenerateUpToLength.cpp
+++ b/alib2algo/src/grammar/generate/GenerateUpToLength.cpp
@@ -63,7 +63,7 @@ std::set<string::LinearString < >> GenerateUpToLength::generate( const T & gramm
 
 auto GenerateUpToLengthEpsilonFreeCFG = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::EpsilonFreeCFG>(GenerateUpToLength::generate);
 auto GenerateUpToLengthGNF = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::GNF>(GenerateUpToLength::generate);
-auto GenerateUpToLengthCNF = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::CNF>(GenerateUpToLength::generate);
+auto GenerateUpToLengthCNF = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::CNF < > >(GenerateUpToLength::generate);
 auto GenerateUpToLengthLeftRG = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::LeftRG>(GenerateUpToLength::generate);
 auto GenerateUpToLengthRightRG = GenerateUpToLength::RegistratorWrapper<std::set<string::LinearString < >>, grammar::RightRG>(GenerateUpToLength::generate);
 
diff --git a/alib2algo/src/grammar/parsing/First.cpp b/alib2algo/src/grammar/parsing/First.cpp
index 69ad70d6d3..e06a448ea2 100644
--- a/alib2algo/src/grammar/parsing/First.cpp
+++ b/alib2algo/src/grammar/parsing/First.cpp
@@ -107,7 +107,7 @@ std::set < std::variant < alphabet::Symbol, string::Epsilon < > > > First::first
 auto FirstCFG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::CFG < > > ( First::first );
 auto FirstEpsilonFreeCFG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::EpsilonFreeCFG > ( First::first );
 auto FirstGNF = FirstBase1::RegistratorWrapper < FirstResult1, grammar::GNF > ( First::first );
-auto FirstCNF = FirstBase1::RegistratorWrapper < FirstResult1, grammar::CNF > ( First::first );
+auto FirstCNF = FirstBase1::RegistratorWrapper < FirstResult1, grammar::CNF < > > ( First::first );
 auto FirstLG  = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LG > ( First::first );
 auto FirstLeftLG  = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LeftLG > ( First::first );
 auto FirstLeftRG  = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LeftRG > ( First::first );
@@ -121,7 +121,7 @@ std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet:
 auto FirstCFG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::CFG < > > ( First::first );
 auto FirstEpsilonFreeCFG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::EpsilonFreeCFG > ( First::first );
 auto FirstGNF2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::GNF > ( First::first );
-auto FirstCNF2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::CNF > ( First::first );
+auto FirstCNF2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::CNF < > > ( First::first );
 auto FirstLG2  = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LG > ( First::first );
 auto FirstLeftLG2  = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LeftLG > ( First::first );
 auto FirstLeftRG2  = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LeftRG > ( First::first );
diff --git a/alib2algo/src/grammar/parsing/Follow.cpp b/alib2algo/src/grammar/parsing/Follow.cpp
index bf1baec674..a53082d7ed 100644
--- a/alib2algo/src/grammar/parsing/Follow.cpp
+++ b/alib2algo/src/grammar/parsing/Follow.cpp
@@ -95,7 +95,7 @@ std::set < std::variant < alphabet::Symbol, string::Epsilon < > > > Follow::foll
 auto FollowCFG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::CFG < > > ( Follow::follow );
 auto FollowEpsilonFreeCFG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::EpsilonFreeCFG > ( Follow::follow );
 auto FollowGNF = FollowBase1::RegistratorWrapper < FollowResult1, grammar::GNF > ( Follow::follow );
-auto FollowCNF = FollowBase1::RegistratorWrapper < FollowResult1, grammar::CNF > ( Follow::follow );
+auto FollowCNF = FollowBase1::RegistratorWrapper < FollowResult1, grammar::CNF < > > ( Follow::follow );
 auto FollowLG  = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LG > ( Follow::follow );
 auto FollowLeftLG  = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LeftLG > ( Follow::follow );
 auto FollowLeftRG  = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LeftRG > ( Follow::follow );
@@ -109,7 +109,7 @@ std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string:
 auto FollowCFG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::CFG < > > ( Follow::follow );
 auto FollowEpsilonFreeCFG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::EpsilonFreeCFG > ( Follow::follow );
 auto FollowGNF2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::GNF > ( Follow::follow );
-auto FollowCNF2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::CNF > ( Follow::follow );
+auto FollowCNF2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::CNF < > > ( Follow::follow );
 auto FollowLG2	= FollowBase2::RegistratorWrapper < FollowResult2, grammar::LG > ( Follow::follow );
 auto FollowLeftLG2	= FollowBase2::RegistratorWrapper < FollowResult2, grammar::LeftLG > ( Follow::follow );
 auto FollowLeftRG2	= FollowBase2::RegistratorWrapper < FollowResult2, grammar::LeftRG > ( Follow::follow );
diff --git a/alib2algo/src/grammar/parsing/LL1ParseTable.cpp b/alib2algo/src/grammar/parsing/LL1ParseTable.cpp
index 8fafa150e3..0b38f895de 100644
--- a/alib2algo/src/grammar/parsing/LL1ParseTable.cpp
+++ b/alib2algo/src/grammar/parsing/LL1ParseTable.cpp
@@ -53,7 +53,7 @@ std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, a
 auto LL1ParseTableCFG = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::CFG < > > ( LL1ParseTable::parseTable );
 auto LL1ParseTableEpsilonFreeCFG = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::EpsilonFreeCFG > ( LL1ParseTable::parseTable );
 auto LL1ParseTableGNF = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::GNF > ( LL1ParseTable::parseTable );
-auto LL1ParseTableCNF = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::CNF > ( LL1ParseTable::parseTable );
+auto LL1ParseTableCNF = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::CNF < > > ( LL1ParseTable::parseTable );
 auto LL1ParseTableLG  = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::LG > ( LL1ParseTable::parseTable );
 auto LL1ParseTableLeftLG  = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::LeftLG > ( LL1ParseTable::parseTable );
 auto LL1ParseTableLeftRG  = LL1ParseTable::RegistratorWrapper < std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon < > >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > >, grammar::LeftRG > ( LL1ParseTable::parseTable );
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
index b87f4d6c3f..d922d57b21 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -31,7 +31,7 @@ bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) {
 auto IsLanguageEmptyCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CFG < > >(IsLanguageEmpty::isLanguageEmpty);
 auto IsLanguageEmptyEpsilonFreeCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageEmpty::isLanguageEmpty);
 auto IsLanguageEmptyGNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::GNF>(IsLanguageEmpty::isLanguageEmpty);
-auto IsLanguageEmptyCNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CNF>(IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyCNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CNF < > >(IsLanguageEmpty::isLanguageEmpty);
 auto IsLanguageEmptyLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LG>(IsLanguageEmpty::isLanguageEmpty);
 auto IsLanguageEmptyLeftLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageEmpty::isLanguageEmpty);
 auto IsLanguageEmptyLeftRG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageEmpty::isLanguageEmpty);
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
index 96e43c1272..8f7eb6473a 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
@@ -31,7 +31,7 @@ bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const T & grammar
 auto IsLanguageGeneratingEpsilonCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CFG < > >(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 auto IsLanguageGeneratingEpsilonEpsilonFreeCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 auto IsLanguageGeneratingEpsilonGNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::GNF>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
-auto IsLanguageGeneratingEpsilonCNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CNF>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonCNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CNF < > >(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 auto IsLanguageGeneratingEpsilonLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LG>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 auto IsLanguageGeneratingEpsilonLeftLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 auto IsLanguageGeneratingEpsilonLeftRG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
index 0b2f0db390..8d3bff5ab4 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
@@ -60,7 +60,7 @@ std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle
 auto NonterminalUnitRuleCycleCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG < > >(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 auto NonterminalUnitRuleCycleEpsilonFreeCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 auto NonterminalUnitRuleCycleGNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
-auto NonterminalUnitRuleCycleCNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleCNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF < > >(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 auto NonterminalUnitRuleCycleLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 auto NonterminalUnitRuleCycleLeftLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 auto NonterminalUnitRuleCycleLeftRG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
index 3927cfd5f5..24309166fb 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
@@ -54,7 +54,7 @@ std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const T
 auto NullableNonterminalsCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG < > >(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsEpsilonFreeCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsGNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NullableNonterminals::getNullableNonterminals);
-auto NullableNonterminalsCNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsCNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF < > >(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsLeftLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsLeftRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NullableNonterminals::getNullableNonterminals);
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
index b3fc404935..f2218607d8 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -59,7 +59,7 @@ std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( co
 auto ProductiveNonterminalsCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG < > >(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsEpsilonFreeCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsGNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(ProductiveNonterminals::getProductiveNonterminals);
-auto ProductiveNonterminalsCNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsCNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF < > >(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsLeftLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsLeftRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(ProductiveNonterminals::getProductiveNonterminals);
diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
index 6c42a179f2..ff7eeb64b3 100644
--- a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
+++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
@@ -66,7 +66,7 @@ bool RecursiveNonterminal::isNonterminalRecursive ( const T & grammar, const alp
 auto RecursiveNonterminalCFG = RecursiveNonterminal::RegistratorWrapper < bool, grammar::CFG < > > ( RecursiveNonterminal::isNonterminalRecursive );
 auto RecursiveNonterminalEpsilonFreeCFG = RecursiveNonterminal::RegistratorWrapper < bool, grammar::EpsilonFreeCFG > ( RecursiveNonterminal::isNonterminalRecursive );
 auto RecursiveNonterminalGNF = RecursiveNonterminal::RegistratorWrapper < bool, grammar::GNF > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalCNF = RecursiveNonterminal::RegistratorWrapper < bool, grammar::CNF > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalCNF = RecursiveNonterminal::RegistratorWrapper < bool, grammar::CNF < > > ( RecursiveNonterminal::isNonterminalRecursive );
 auto RecursiveNonterminalLG	 = RecursiveNonterminal::RegistratorWrapper < bool, grammar::LG > ( RecursiveNonterminal::isNonterminalRecursive );
 auto RecursiveNonterminalLeftLG	 = RecursiveNonterminal::RegistratorWrapper < bool, grammar::LeftLG > ( RecursiveNonterminal::isNonterminalRecursive );
 auto RecursiveNonterminalLeftRG	 = RecursiveNonterminal::RegistratorWrapper < bool, grammar::LeftRG > ( RecursiveNonterminal::isNonterminalRecursive );
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
index ee9cffa795..5e506269b3 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
@@ -60,7 +60,7 @@ std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const T &
 auto UnreachableSymbolsCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG < > >(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsEpsilonFreeCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsGNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(UnreachableSymbols::getUnreachableSymbols);
-auto UnreachableSymbolsCNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsCNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF < > >(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsLeftLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsLeftRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(UnreachableSymbols::getUnreachableSymbols);
diff --git a/alib2algo/src/grammar/simplify/EpsilonRemover.cpp b/alib2algo/src/grammar/simplify/EpsilonRemover.cpp
index 9ce978849a..06e7020f9b 100644
--- a/alib2algo/src/grammar/simplify/EpsilonRemover.cpp
+++ b/alib2algo/src/grammar/simplify/EpsilonRemover.cpp
@@ -64,11 +64,11 @@ grammar::EpsilonFreeCFG EpsilonRemover::remove(const grammar::EpsilonFreeCFG& or
 
 auto EpsilonRemoverEpsilonFreeCFG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(EpsilonRemover::remove);
 
-grammar::CNF EpsilonRemover::remove(const grammar::CNF& origGrammar) {
+grammar::CNF < > EpsilonRemover::remove(const grammar::CNF < > & origGrammar) {
 	return origGrammar;
 }
 
-auto EpsilonRemoverCNF = EpsilonRemover::RegistratorWrapper<grammar::CNF, grammar::CNF>(EpsilonRemover::remove);
+auto EpsilonRemoverCNF = EpsilonRemover::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(EpsilonRemover::remove);
 
 grammar::GNF EpsilonRemover::remove(const grammar::GNF& origGrammar) {
 	return origGrammar;
diff --git a/alib2algo/src/grammar/simplify/EpsilonRemover.h b/alib2algo/src/grammar/simplify/EpsilonRemover.h
index 22a53a41f8..ced488b28b 100644
--- a/alib2algo/src/grammar/simplify/EpsilonRemover.h
+++ b/alib2algo/src/grammar/simplify/EpsilonRemover.h
@@ -35,7 +35,7 @@ public:
 	static grammar::EpsilonFreeCFG remove( const grammar::CFG < > & grammar );
 	static grammar::EpsilonFreeCFG remove( const grammar::EpsilonFreeCFG & grammar );
 	static grammar::GNF remove( const grammar::GNF & grammar );
-	static grammar::CNF remove( const grammar::CNF & grammar );
+	static grammar::CNF < > remove( const grammar::CNF < > & grammar );
 	static grammar::EpsilonFreeCFG remove( const grammar::LG & grammar );
 	static grammar::EpsilonFreeCFG remove( const grammar::LeftLG & grammar );
 	static grammar::LeftRG remove( const grammar::LeftRG & grammar );
diff --git a/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp b/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
index 859d53bb1d..bd0c38723e 100644
--- a/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
+++ b/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
@@ -128,7 +128,7 @@ grammar::EpsilonFreeCFG LeftRecursionRemover::remove(const grammar::EpsilonFreeC
 
 auto LeftRecursionRemoverEpsilonFreeCFG = LeftRecursionRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(LeftRecursionRemover::remove);
 
-grammar::EpsilonFreeCFG LeftRecursionRemover::remove(const grammar::CNF& origGrammar) {
+grammar::EpsilonFreeCFG LeftRecursionRemover::remove(const grammar::CNF < > & origGrammar) {
 	EpsilonFreeCFG tmp(origGrammar.getInitialSymbol());
 	tmp.setTerminalAlphabet(origGrammar.getTerminalAlphabet());
 	tmp.setNonterminalAlphabet(origGrammar.getNonterminalAlphabet());
@@ -146,7 +146,7 @@ grammar::EpsilonFreeCFG LeftRecursionRemover::remove(const grammar::CNF& origGra
 	return remove(tmp);
 }
 
-auto LeftRecursionRemoverCNF = LeftRecursionRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::CNF>(LeftRecursionRemover::remove);
+auto LeftRecursionRemoverCNF = LeftRecursionRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::CNF < > >(LeftRecursionRemover::remove);
 
 grammar::GNF LeftRecursionRemover::remove(const grammar::GNF& origGrammar) {
 	return origGrammar;
diff --git a/alib2algo/src/grammar/simplify/LeftRecursionRemover.h b/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
index f98cdaf478..dd04837ed6 100644
--- a/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
+++ b/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
@@ -33,7 +33,7 @@ public:
 	static grammar::Grammar remove( const grammar::Grammar & grammar );
 
 	static grammar::EpsilonFreeCFG remove( const grammar::EpsilonFreeCFG & grammar );
-	static grammar::EpsilonFreeCFG remove( const grammar::CNF & grammar );
+	static grammar::EpsilonFreeCFG remove( const grammar::CNF < > & grammar );
 	static grammar::GNF remove( const grammar::GNF & grammar );
 	static grammar::RightRG remove( const grammar::RightRG & grammar );
 	static grammar::RightLG remove( const grammar::RightLG & grammar );
diff --git a/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp b/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
index efd19e41d7..01884d1454 100644
--- a/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
+++ b/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
@@ -79,11 +79,11 @@ grammar::EpsilonFreeCFG SimpleRulesRemover::remove(const grammar::EpsilonFreeCFG
 
 auto SimpleRulesRemoverEpsilonFreeCFG = SimpleRulesRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(SimpleRulesRemover::remove);
 
-grammar::CNF SimpleRulesRemover::remove(const grammar::CNF& origGrammar) {
+grammar::CNF < > SimpleRulesRemover::remove(const grammar::CNF < > & origGrammar) {
 	return origGrammar;
 }
 
-auto SimpleRulesRemoverCNF = SimpleRulesRemover::RegistratorWrapper<grammar::CNF, grammar::CNF>(SimpleRulesRemover::remove);
+auto SimpleRulesRemoverCNF = SimpleRulesRemover::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(SimpleRulesRemover::remove);
 
 grammar::GNF SimpleRulesRemover::remove(const grammar::GNF& origGrammar) {
 	return origGrammar;
diff --git a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
index d579194192..a72bf3982e 100644
--- a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
+++ b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
@@ -35,7 +35,7 @@ public:
 	static grammar::CFG < > remove( const grammar::CFG < > & grammar );
 	static grammar::EpsilonFreeCFG remove( const grammar::EpsilonFreeCFG & grammar );
 	static grammar::GNF remove( const grammar::GNF & grammar );
-	static grammar::CNF remove( const grammar::CNF & grammar );
+	static grammar::CNF < > remove( const grammar::CNF < > & grammar );
 	static grammar::LG remove( const grammar::LG & grammar );
 	static grammar::LeftLG remove( const grammar::LeftLG & grammar );
 	static grammar::LeftRG remove( const grammar::LeftRG & grammar );
diff --git a/alib2algo/src/grammar/simplify/ToCNF.cpp b/alib2algo/src/grammar/simplify/ToCNF.cpp
index 6c0e6b0d57..2b95ee47c0 100644
--- a/alib2algo/src/grammar/simplify/ToCNF.cpp
+++ b/alib2algo/src/grammar/simplify/ToCNF.cpp
@@ -55,7 +55,7 @@ std::pair<alphabet::Symbol, alphabet::Symbol> splitToPairs(T& grammar, const std
 }
 
 template<class T>
-grammar::CNF convertInternal( const T & origGrammar ) {
+grammar::CNF < > convertInternal( const T & origGrammar ) {
 	T grammarTmp(origGrammar.getInitialSymbol());
 
 	grammarTmp.setNonterminalAlphabet(origGrammar.getNonterminalAlphabet() );
@@ -77,7 +77,7 @@ grammar::CNF convertInternal( const T & origGrammar ) {
 
 	grammarTmp.setGeneratesEpsilon(origGrammar.getGeneratesEpsilon());
 
-	grammar::CNF grammar(grammarTmp.getInitialSymbol());
+	grammar::CNF < > grammar(grammarTmp.getInitialSymbol());
 
 	grammar.setNonterminalAlphabet( grammarTmp.getNonterminalAlphabet() );
 	grammar.setTerminalAlphabet( grammarTmp.getTerminalAlphabet() );
@@ -117,59 +117,59 @@ grammar::CNF convertInternal( const T & origGrammar ) {
 	return grammar;
 }
 
-grammar::CNF ToCNF::convert(const grammar::CFG < > & origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::CFG < > & origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-auto ToCNFCFG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::CFG < > >(ToCNF::convert);
+auto ToCNFCFG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::CFG < > >(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::EpsilonFreeCFG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::EpsilonFreeCFG& origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(origGrammar));
 }
 
-auto ToCNFEpsilonFreeCFG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::EpsilonFreeCFG>(ToCNF::convert);
+auto ToCNFEpsilonFreeCFG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::EpsilonFreeCFG>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::CNF& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::CNF < > & origGrammar) {
 	return origGrammar;
 }
 
-auto ToCNFCNF = ToCNF::RegistratorWrapper<grammar::CNF, grammar::CNF>(ToCNF::convert);
+auto ToCNFCNF = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::GNF& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::GNF& origGrammar) {
 	return convertInternal(origGrammar);
 }
 
-auto ToCNFGNF = ToCNF::RegistratorWrapper<grammar::CNF, grammar::GNF>(ToCNF::convert);
+auto ToCNFGNF = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::GNF>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::LG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::LG& origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-auto ToCNFLG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::LG>(ToCNF::convert);
+auto ToCNFLG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::LG>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::LeftLG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::LeftLG& origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-auto ToCNFLeftLG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::LeftLG>(ToCNF::convert);
+auto ToCNFLeftLG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::LeftLG>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::LeftRG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::LeftRG& origGrammar) {
 	return convertInternal(origGrammar);
 }
 
-auto ToCNFLeftRG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::LeftRG>(ToCNF::convert);
+auto ToCNFLeftRG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::LeftRG>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::RightLG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::RightLG& origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-auto ToCNFRightLG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::RightLG>(ToCNF::convert);
+auto ToCNFRightLG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::RightLG>(ToCNF::convert);
 
-grammar::CNF ToCNF::convert(const grammar::RightRG& origGrammar) {
+grammar::CNF < > ToCNF::convert(const grammar::RightRG& origGrammar) {
 	return convertInternal(origGrammar);
 }
 
-auto ToCNFRightRG = ToCNF::RegistratorWrapper<grammar::CNF, grammar::RightRG>(ToCNF::convert);
+auto ToCNFRightRG = ToCNF::RegistratorWrapper<grammar::CNF < >, grammar::RightRG>(ToCNF::convert);
 
 grammar::Grammar ToCNF::convert(const grammar::Grammar& grammar) {
 	return dispatch(grammar.getData());
diff --git a/alib2algo/src/grammar/simplify/ToCNF.h b/alib2algo/src/grammar/simplify/ToCNF.h
index 750e7c5ecb..dde38142d8 100644
--- a/alib2algo/src/grammar/simplify/ToCNF.h
+++ b/alib2algo/src/grammar/simplify/ToCNF.h
@@ -32,15 +32,15 @@ class ToCNF : public std::SingleDispatch<ToCNF, grammar::Grammar, const grammar:
 public:
 	static grammar::Grammar convert( const grammar::Grammar & grammar );
 
-	static grammar::CNF convert( const grammar::CFG < > & grammar );
-	static grammar::CNF convert( const grammar::EpsilonFreeCFG & grammar );
-	static grammar::CNF convert( const grammar::GNF & grammar );
-	static grammar::CNF convert( const grammar::CNF & grammar );
-	static grammar::CNF convert( const grammar::LG & grammar );
-	static grammar::CNF convert( const grammar::LeftLG & grammar );
-	static grammar::CNF convert( const grammar::LeftRG & grammar );
-	static grammar::CNF convert( const grammar::RightLG & grammar );
-	static grammar::CNF convert( const grammar::RightRG & grammar );
+	static grammar::CNF < > convert( const grammar::CFG < > & grammar );
+	static grammar::CNF < > convert( const grammar::EpsilonFreeCFG & grammar );
+	static grammar::CNF < > convert( const grammar::GNF & grammar );
+	static grammar::CNF < > convert( const grammar::CNF < > & grammar );
+	static grammar::CNF < > convert( const grammar::LG & grammar );
+	static grammar::CNF < > convert( const grammar::LeftLG & grammar );
+	static grammar::CNF < > convert( const grammar::LeftRG & grammar );
+	static grammar::CNF < > convert( const grammar::RightLG & grammar );
+	static grammar::CNF < > convert( const grammar::RightRG & grammar );
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/grammar/simplify/ToGNF.cpp b/alib2algo/src/grammar/simplify/ToGNF.cpp
index 2fedfb2fae..09da1b78a6 100644
--- a/alib2algo/src/grammar/simplify/ToGNF.cpp
+++ b/alib2algo/src/grammar/simplify/ToGNF.cpp
@@ -99,11 +99,11 @@ grammar::GNF ToGNF::convert(const grammar::EpsilonFreeCFG& origGrammar) {
 
 auto ToGNFEpsilonFreeCFG = ToGNF::RegistratorWrapper<grammar::GNF, grammar::EpsilonFreeCFG>(ToGNF::convert);
 
-grammar::GNF ToGNF::convert(const grammar::CNF& origGrammar) {
+grammar::GNF ToGNF::convert(const grammar::CNF < > & origGrammar) {
 	return convertInternal(grammar::simplify::LeftRecursionRemover::remove(origGrammar));
 }
 
-auto ToGNFCNF = ToGNF::RegistratorWrapper<grammar::GNF, grammar::CNF>(ToGNF::convert);
+auto ToGNFCNF = ToGNF::RegistratorWrapper<grammar::GNF, grammar::CNF < > >(ToGNF::convert);
 
 grammar::GNF ToGNF::convert(const grammar::GNF& origGrammar) {
 	return origGrammar;
diff --git a/alib2algo/src/grammar/simplify/ToGNF.h b/alib2algo/src/grammar/simplify/ToGNF.h
index 7c2109729b..cbfbe4cc47 100644
--- a/alib2algo/src/grammar/simplify/ToGNF.h
+++ b/alib2algo/src/grammar/simplify/ToGNF.h
@@ -34,7 +34,7 @@ public:
 
 	static grammar::GNF convert( const grammar::CFG < > & grammar );
 	static grammar::GNF convert( const grammar::EpsilonFreeCFG & grammar );
-	static grammar::GNF convert( const grammar::CNF & grammar );
+	static grammar::GNF convert( const grammar::CNF < > & grammar );
 	static grammar::GNF convert( const grammar::GNF & grammar );
 	static grammar::GNF convert( const grammar::LG & grammar );
 	static grammar::GNF convert( const grammar::LeftLG & grammar );
diff --git a/alib2algo/src/grammar/simplify/Trim.cpp b/alib2algo/src/grammar/simplify/Trim.cpp
index 9edf5972ee..1fb02bb7eb 100644
--- a/alib2algo/src/grammar/simplify/Trim.cpp
+++ b/alib2algo/src/grammar/simplify/Trim.cpp
@@ -32,7 +32,7 @@ T Trim::trim( const T & grammar ) {
 auto TrimCFG = Trim::RegistratorWrapper<grammar::CFG < >, grammar::CFG < > >(Trim::trim);
 auto TrimEpsilonFreeCFG = Trim::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(Trim::trim);
 auto TrimGNF = Trim::RegistratorWrapper<grammar::GNF, grammar::GNF>(Trim::trim);
-auto TrimCNF = Trim::RegistratorWrapper<grammar::CNF, grammar::CNF>(Trim::trim);
+auto TrimCNF = Trim::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(Trim::trim);
 auto TrimLG = Trim::RegistratorWrapper<grammar::LG, grammar::LG>(Trim::trim);
 auto TrimLeftLG = Trim::RegistratorWrapper<grammar::LeftLG, grammar::LeftLG>(Trim::trim);
 auto TrimLeftRG = Trim::RegistratorWrapper<grammar::LeftRG, grammar::LeftRG>(Trim::trim);
diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
index dba75f1c7c..88206b7438 100644
--- a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
+++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
@@ -63,7 +63,7 @@ T UnproductiveSymbolsRemover::remove( const T & grammar ) {
 auto UnproductiveSymbolsRemoverCFG = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::CFG < >, grammar::CFG < > >(UnproductiveSymbolsRemover::remove);
 auto UnproductiveSymbolsRemoverEpsilonFreeCFG = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(UnproductiveSymbolsRemover::remove);
 auto UnproductiveSymbolsRemoverGNF = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::GNF, grammar::GNF>(UnproductiveSymbolsRemover::remove);
-auto UnproductiveSymbolsRemoverCNF = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::CNF, grammar::CNF>(UnproductiveSymbolsRemover::remove);
+auto UnproductiveSymbolsRemoverCNF = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(UnproductiveSymbolsRemover::remove);
 auto UnproductiveSymbolsRemoverLG = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::LG, grammar::LG>(UnproductiveSymbolsRemover::remove);
 auto UnproductiveSymbolsRemoverLeftLG = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::LeftLG, grammar::LeftLG>(UnproductiveSymbolsRemover::remove);
 auto UnproductiveSymbolsRemoverLeftRG = UnproductiveSymbolsRemover::RegistratorWrapper<grammar::LeftRG, grammar::LeftRG>(UnproductiveSymbolsRemover::remove);
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
index 73e3297659..7f0d9e4c03 100644
--- a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
@@ -62,7 +62,7 @@ T UnreachableSymbolsRemover::remove( const T & grammar) {
 auto UnreachableSymbolsRemoverCFG = UnreachableSymbolsRemover::RegistratorWrapper<grammar::CFG < >, grammar::CFG < > >(UnreachableSymbolsRemover::remove);
 auto UnreachableSymbolsRemoverEpsilonFreeCFG = UnreachableSymbolsRemover::RegistratorWrapper<grammar::EpsilonFreeCFG, grammar::EpsilonFreeCFG>(UnreachableSymbolsRemover::remove);
 auto UnreachableSymbolsRemoverGNF = UnreachableSymbolsRemover::RegistratorWrapper<grammar::GNF, grammar::GNF>(UnreachableSymbolsRemover::remove);
-auto UnreachableSymbolsRemoverCNF = UnreachableSymbolsRemover::RegistratorWrapper<grammar::CNF, grammar::CNF>(UnreachableSymbolsRemover::remove);
+auto UnreachableSymbolsRemoverCNF = UnreachableSymbolsRemover::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(UnreachableSymbolsRemover::remove);
 auto UnreachableSymbolsRemoverLG = UnreachableSymbolsRemover::RegistratorWrapper<grammar::LG, grammar::LG>(UnreachableSymbolsRemover::remove);
 auto UnreachableSymbolsRemoverLeftLG = UnreachableSymbolsRemover::RegistratorWrapper<grammar::LeftLG, grammar::LeftLG>(UnreachableSymbolsRemover::remove);
 auto UnreachableSymbolsRemoverLeftRG = UnreachableSymbolsRemover::RegistratorWrapper<grammar::LeftRG, grammar::LeftRG>(UnreachableSymbolsRemover::remove);
diff --git a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp
index 5dd2f56eb3..a85ef0af92 100644
--- a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp
+++ b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp
@@ -41,9 +41,9 @@ void GrammarToCNFTest::testToCNFRules1() {
 	grammar1.setNonterminalAlphabet({S, A, B, C, D});
 	grammar1.setTerminalAlphabet({a, b});
 
-	grammar::CNF grammar2 = grammar::simplify::ToCNF::convert(grammar1);
+	grammar::CNF < > grammar2 = grammar::simplify::ToCNF::convert(grammar1);
 
-	grammar::CNF grammar3(S);
+	grammar::CNF < > grammar3(S);
 	grammar3.setNonterminalAlphabet({S, A, B, C, D, aP, bP});
 	grammar3.setTerminalAlphabet({a, b});
 	grammar3.addRule(aP, a);
@@ -74,7 +74,7 @@ void GrammarToCNFTest::testToCNFRules2() {
 	grammar1.addRule({Y}, {X});
 	grammar1.addRule({Y}, {c});
 
-	grammar::CNF grammar2 = grammar::simplify::ToCNF::convert(grammar1);
+	grammar::CNF < > grammar2 = grammar::simplify::ToCNF::convert(grammar1);
 	alphabet::Symbol aP = alphabet::symbolFrom("a'");
 	alphabet::Symbol bP = alphabet::symbolFrom("b'");
 	alphabet::Symbol cP = alphabet::symbolFrom("c'");
@@ -82,7 +82,7 @@ void GrammarToCNFTest::testToCNFRules2() {
 	alphabet::Symbol aX = alphabet::Symbol(alphabet::Symbol(alphabet::SymbolPairSymbol(std::make_pair(a, X))));
 	alphabet::Symbol bX = alphabet::Symbol(alphabet::Symbol(alphabet::SymbolPairSymbol(std::make_pair(b, X))));
 
-	grammar::CNF grammar3(S);
+	grammar::CNF < > grammar3(S);
 	grammar3.setNonterminalAlphabet({S, X, Y, aP, bP, cP, Xb, aX, bX});
 	grammar3.setTerminalAlphabet({a, b, c});
 	grammar3.addRule(S, std::make_pair(aX, bX));
diff --git a/alib2data/src/grammar/ContextFree/CNF.cpp b/alib2data/src/grammar/ContextFree/CNF.cpp
index 5faeaf4838..4404ee4b7a 100644
--- a/alib2data/src/grammar/ContextFree/CNF.cpp
+++ b/alib2data/src/grammar/ContextFree/CNF.cpp
@@ -6,238 +6,13 @@
  */
 
 #include "CNF.h"
-#include <algorithm>
-#include <sstream>
-
-#include "../../alphabet/Symbol.h"
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/GrammarFromXMLParser.h"
-#include "../common/GrammarToXMLComposer.h"
 #include "../Grammar.h"
 #include <object/Object.h>
 #include <XmlApi.hpp>
 
-namespace grammar {
-
-CNF::CNF ( alphabet::Symbol initialSymbol ) : CNF ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) {
-}
-
-CNF::CNF ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < CNF, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) {
-}
-
-GrammarBase * CNF::clone ( ) const {
-	return new CNF ( * this );
-}
-
-GrammarBase * CNF::plunder ( ) && {
-	return new CNF ( std::move ( * this ) );
-}
-
-bool CNF::addRule ( alphabet::Symbol leftHandSide, std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rightHandSide ) {
-	if ( rightHandSide.is < alphabet::Symbol > ( ) ) {
-		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
-			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
-
-		if ( !getTerminalAlphabet ( ).count ( rightHandSide.get < alphabet::Symbol > ( ) ) )
-			throw GrammarException ( "Rule must rewrite to terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
-	} else {
-		const std::pair < alphabet::Symbol, alphabet::Symbol > rhs = rightHandSide.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( );
-
-		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
-			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
-
-		if ( !getNonterminalAlphabet ( ).count ( rhs.first ) )
-			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.first ) + "\" is not a nonterminal symbol" );
-
-		if ( !getNonterminalAlphabet ( ).count ( rhs.second ) )
-			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.second ) + "\" is not a nonterminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
-	}
-}
-
-bool CNF::addRule ( alphabet::Symbol leftHandSide, alphabet::Symbol rightHandSide ) {
-	std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rhs ( std::move ( rightHandSide ) );
-
-	return addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
-}
-
-bool CNF::addRule ( alphabet::Symbol leftHandSide, std::pair < alphabet::Symbol, alphabet::Symbol > rightHandSide ) {
-	std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rhs ( std::move ( rightHandSide ) );
-
-	return addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
-}
-
-const std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & CNF::getRules ( ) const {
-	return rules;
-}
-
-bool CNF::removeRule ( const alphabet::Symbol & leftHandSide, const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rightHandSide ) {
-	return rules[leftHandSide].erase ( rightHandSide );
-}
-
-bool CNF::removeRule ( const alphabet::Symbol & leftHandSide, const alphabet::Symbol & rightHandSide ) {
-	std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rhs ( rightHandSide );
-
-	return removeRule ( leftHandSide, rhs );
-}
-
-bool CNF::removeRule ( const alphabet::Symbol & leftHandSide, const std::pair < alphabet::Symbol, alphabet::Symbol > & rightHandSide ) {
-	std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rhs ( rightHandSide );
-
-	return removeRule ( leftHandSide, rhs );
-}
-
-bool CNF::addRawRule ( alphabet::Symbol leftHandSide, std::vector < alphabet::Symbol > rightHandSide ) {
-	if ( rightHandSide.size ( ) == 0 ) {
-		if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" );
-
-		bool res = getGeneratesEpsilon ( );
-		setGeneratesEpsilon ( true );
-		return !res;
-	} else if ( rightHandSide.size ( ) == 1 ) {
-		return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) );
-	} else if ( rightHandSide.size ( ) == 2 ) {
-		return addRule ( std::move ( leftHandSide ), std::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) );
-	} else {
-		throw GrammarException ( "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 { rhs.get < alphabet::Symbol > ( ) };
-				res[rule.first].insert ( std::move ( tmp ) );
-			} else {
-				const auto & realRHS = rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( );
-				std::vector < alphabet::Symbol > tmp { realRHS.first, realRHS.second };
-				res[rule.first].insert ( std::move ( 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 != getInitialSymbol ( ) ) throw GrammarException ( "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 GrammarException ( "Invalid right hand side" );
-	}
-}
-
-void CNF::setGeneratesEpsilon ( bool genEps ) {
-	generatesEpsilon = genEps;
-}
-
-bool CNF::getGeneratesEpsilon ( ) const {
-	return generatesEpsilon;
-}
-
-int CNF::compare ( const CNF & other ) const {
-	auto first = std::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules );
-	auto second = std::tie ( other.getTerminalAlphabet ( ), other.getNonterminalAlphabet ( ), other.getInitialSymbol ( ), other.rules );
-
-	std::compare < decltype ( first ) > comp;
-
-	return comp ( first, second );
-}
-
-void CNF::operator >>( std::ostream & out ) const {
-	out << "(CNF "
-	    << "nonterminalAlphabet = " << getNonterminalAlphabet ( )
-	    << "terminalAlphabet = " << getTerminalAlphabet ( )
-	    << "initialSymbol = " << getInitialSymbol ( )
-	    << "rules = " << rules
-	    << "generatesEpsilon = " << generatesEpsilon << ")";
-}
-
-CNF::operator std::string ( ) const {
-	std::stringstream ss;
-	ss << * this;
-	return ss.str ( );
-}
-
-CNF CNF::parse ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, CNF::getXmlTagName() );
-
-	std::set < alphabet::Symbol > nonterminalAlphabet = GrammarFromXMLParser::parseNonterminalAlphabet ( input );
-	std::set < alphabet::Symbol > terminalAlphabet = GrammarFromXMLParser::parseTerminalAlphabet ( input );
-	alphabet::Symbol initialSymbol = GrammarFromXMLParser::parseInitialSymbol ( input );
-
-	CNF grammar ( std::move ( initialSymbol ) );
-
-	grammar.setNonterminalAlphabet ( std::move ( nonterminalAlphabet ) );
-	grammar.setTerminalAlphabet ( std::move ( terminalAlphabet ) );
-
-	GrammarFromXMLParser::parseRules ( input, grammar );
-
-	bool generatesEpsilon = GrammarFromXMLParser::parseGeneratesEpsilon ( input );
-	grammar.setGeneratesEpsilon ( generatesEpsilon );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, CNF::getXmlTagName() );
-	return grammar;
-}
-
-void CNF::parseRule ( std::deque < sax::Token >::iterator & input, CNF & grammar ) {
-	alphabet::Symbol lhs = GrammarFromXMLParser::parseRuleSingleSymbolLHS ( input );
-	std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rhs = GrammarFromXMLParser::parseRuleOneOrTwoSymbolsRHS ( input );
-
-	grammar.addRule ( std::move ( lhs ), std::move ( rhs ) );
-}
-
-void CNF::compose ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( CNF::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
-
-	GrammarToXMLComposer::composeNonterminalAlphabet ( out, this->getNonterminalAlphabet ( ) );
-	GrammarToXMLComposer::composeTerminalAlphabet ( out, this->getTerminalAlphabet ( ) );
-	GrammarToXMLComposer::composeInitialSymbol ( out, this->getInitialSymbol ( ) );
-	composeRules ( out );
-	GrammarToXMLComposer::composeGeneratesEpsilon ( out, this->getGeneratesEpsilon ( ) );
-
-	out.emplace_back ( CNF::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
-}
-
-void CNF::composeRules ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( "rules", sax::Token::TokenType::START_ELEMENT );
-
-	for ( const auto & rule : this->getRules ( ) )
-
-		for ( const auto & rhs : rule.second ) {
-			out.emplace_back ( "rule", sax::Token::TokenType::START_ELEMENT );
-
-			GrammarToXMLComposer::composeRuleSingleSymbolLHS ( out, rule.first );
-			GrammarToXMLComposer::composeRuleOneOrTwoSymbolsRHS ( out, rhs );
-
-			out.emplace_back ( "rule", sax::Token::TokenType::END_ELEMENT );
-		}
-
-	out.emplace_back ( "rules", sax::Token::TokenType::END_ELEMENT );
-}
-
-} /* namespace grammar */
-
 namespace alib {
 
-auto CNFParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::CNF > ( );
-auto CNFParserRegister2 = xmlApi < alib::Object >::ParserRegister < grammar::CNF > ( );
+auto CNFParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::CNF < > > ( );
+auto CNFParserRegister2 = xmlApi < alib::Object >::ParserRegister < grammar::CNF < > > ( );
 
 } /* namespace alib */
diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h
index 341d890161..61cd02ed3a 100644
--- a/alib2data/src/grammar/ContextFree/CNF.h
+++ b/alib2data/src/grammar/ContextFree/CNF.h
@@ -8,82 +8,90 @@
 #ifndef CNF_H_
 #define CNF_H_
 
-#include "../GrammarException.h"
-#include "../GrammarBase.h"
 #include <map>
 #include <vector>
 #include <variant>
+#include <algorithm>
+#include <sstream>
+
 #include <core/components.hpp>
-#include "../../alphabet/Symbol.h"
+#include <sax/FromXMLParserHelper.h>
+
+#include "../GrammarBase.h"
+#include "../GrammarFeatures.h"
+#include "../GrammarException.h"
+#include "../common/GrammarFromXMLParser.h"
+#include "../common/GrammarToXMLComposer.h"
 
 namespace grammar {
 
 /**
- * Context free grammar in chomsky normal form. Type 2 in Chomsky hierarchy. Produces context free languages.
+ * Context free grammar in Chomsky normal form. Type 2 in Chomsky hierarchy. Produces context free languages.
  */
 class TerminalAlphabet;
 class NonterminalAlphabet;
 class InitialSymbol;
 
-class CNF : public GrammarBase, public std::Components < CNF, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > {
-	std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > rules;
+template < class SymbolType >
+class CNF : public GrammarBase, public std::Components < CNF < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > {
+	std::map < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > rules;
 	bool generatesEpsilon;
 
 public:
-	explicit CNF ( alphabet::Symbol initialSymbol );
+	explicit CNF ( SymbolType initialSymbol );
 
-	explicit CNF ( std::set < alphabet::Symbol > nonTerminalSymbols, std::set < alphabet::Symbol > terminalSymbols, alphabet::Symbol initialSymbol );
+	explicit CNF ( std::set < SymbolType > nonTerminalSymbols, std::set < SymbolType > terminalSymbols, SymbolType initialSymbol );
 
 	virtual GrammarBase * clone ( ) const;
 
 	virtual GrammarBase * plunder ( ) &&;
 
-	bool addRule ( alphabet::Symbol leftHandSide, std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > rightHandSide );
-	bool addRule ( alphabet::Symbol leftHandSide, alphabet::Symbol rightHandSide );
-	bool addRule ( alphabet::Symbol leftHandSide, std::pair < alphabet::Symbol, alphabet::Symbol > rightHandSide );
+	bool addRule ( SymbolType leftHandSide, std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rightHandSide );
+	bool addRule ( SymbolType leftHandSide, SymbolType rightHandSide );
+	bool addRule ( SymbolType leftHandSide, std::pair < SymbolType, SymbolType > rightHandSide );
 
-	const std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & getRules ( ) const;
+	const std::map < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > & 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 removeRule ( const SymbolType & leftHandSide, const std::variant < SymbolType, std::pair < SymbolType, SymbolType > > & rightHandSide );
+	bool removeRule ( const SymbolType & leftHandSide, const SymbolType & rightHandSide );
+	bool removeRule ( const SymbolType & leftHandSide, const std::pair < SymbolType, SymbolType > & rightHandSide );
 
-	bool addRawRule ( alphabet::Symbol leftHandSide, std::vector < alphabet::Symbol > rightHandSide );
+	bool addRawRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide );
 
-	std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > getRawRules ( ) const;
+	std::map < SymbolType, std::set < std::vector < SymbolType > > > getRawRules ( ) const;
 
-	bool removeRawRule ( const alphabet::Symbol & leftHandSide, const std::vector < alphabet::Symbol > & rightHandSide );
+	bool removeRawRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide );
 
-	const alphabet::Symbol & getInitialSymbol ( ) const {
-		return accessElement < InitialSymbol > ( ).get ( );
+	const SymbolType & getInitialSymbol ( ) const {
+		return this->template accessElement < InitialSymbol > ( ).get ( );
 	}
 
-	bool setInitialSymbol ( alphabet::Symbol symbol ) {
-		return accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) );
+	bool setInitialSymbol ( SymbolType symbol ) {
+		return this->template accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) );
 	}
 
-	const std::set < alphabet::Symbol > & getNonterminalAlphabet ( ) const {
-		return accessComponent < NonterminalAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getNonterminalAlphabet ( ) const {
+		return this->template accessComponent < NonterminalAlphabet > ( ).get ( );
 	}
 
-	bool addNonterminalSymbol ( alphabet::Symbol symbol ) {
-		return accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) );
+	bool addNonterminalSymbol ( SymbolType symbol ) {
+		return this->template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) );
 	}
 
-	void setNonterminalAlphabet ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) );
+	void setNonterminalAlphabet ( std::set < SymbolType > symbols ) {
+		this->template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) );
 	}
 
-	const std::set < alphabet::Symbol > & getTerminalAlphabet ( ) const {
-		return accessComponent < TerminalAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getTerminalAlphabet ( ) const {
+		return this->template accessComponent < TerminalAlphabet > ( ).get ( );
 	}
 
-	bool addTerminalSymbol ( alphabet::Symbol symbol ) {
-		return accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) );
+	bool addTerminalSymbol ( SymbolType symbol ) {
+		return this->template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) );
 	}
 
-	void setTerminalAlphabet ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) );
+	void setTerminalAlphabet ( std::set < SymbolType > symbols ) {
+		this->template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) );
 	}
 
 	void setGeneratesEpsilon ( bool genEps );
@@ -114,70 +122,306 @@ public:
 	void composeRules ( std::deque < sax::Token > & out ) const;
 };
 
+template < class SymbolType >
+CNF < SymbolType >::CNF ( SymbolType initialSymbol ) : CNF ( std::set < SymbolType > { initialSymbol }, std::set < SymbolType > ( ), initialSymbol ) {
+}
+
+template < class SymbolType >
+CNF < SymbolType >::CNF ( std::set < SymbolType > nonterminalAlphabet, std::set < SymbolType > terminalAlphabet, SymbolType initialSymbol ) : std::Components < CNF, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) {
+}
+
+template < class SymbolType >
+GrammarBase * CNF < SymbolType >::clone ( ) const {
+	return new CNF ( * this );
+}
+
+template < class SymbolType >
+GrammarBase * CNF < SymbolType >::plunder ( ) && {
+	return new CNF ( std::move ( * this ) );
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rightHandSide ) {
+	if ( rightHandSide.template is < SymbolType > ( ) ) {
+		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
+			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
+
+		if ( !getTerminalAlphabet ( ).count ( rightHandSide.template get < SymbolType > ( ) ) )
+			throw GrammarException ( "Rule must rewrite to terminal symbol" );
+
+		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
+	} else {
+		const std::pair < SymbolType, SymbolType > rhs = rightHandSide.template get < std::pair < SymbolType, SymbolType > > ( );
+
+		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
+			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
+
+		if ( !getNonterminalAlphabet ( ).count ( rhs.first ) )
+			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.first ) + "\" is not a nonterminal symbol" );
+
+		if ( !getNonterminalAlphabet ( ).count ( rhs.second ) )
+			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.second ) + "\" is not a nonterminal symbol" );
+
+		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
+	}
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::addRule ( SymbolType leftHandSide, SymbolType rightHandSide ) {
+	std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rhs ( std::move ( rightHandSide ) );
+
+	return addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::addRule ( SymbolType leftHandSide, std::pair < SymbolType, SymbolType > rightHandSide ) {
+	std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rhs ( std::move ( rightHandSide ) );
+
+	return addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
+}
+
+template < class SymbolType >
+const std::map < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > & CNF < SymbolType >::getRules ( ) const {
+	return rules;
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::removeRule ( const SymbolType & leftHandSide, const std::variant < SymbolType, std::pair < SymbolType, SymbolType > > & rightHandSide ) {
+	return rules[leftHandSide].erase ( rightHandSide );
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::removeRule ( const SymbolType & leftHandSide, const SymbolType & rightHandSide ) {
+	std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rhs ( rightHandSide );
+
+	return removeRule ( leftHandSide, rhs );
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::removeRule ( const SymbolType & leftHandSide, const std::pair < SymbolType, SymbolType > & rightHandSide ) {
+	std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rhs ( rightHandSide );
+
+	return removeRule ( leftHandSide, rhs );
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::addRawRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ) {
+	if ( rightHandSide.size ( ) == 0 ) {
+		if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" );
+
+		bool res = getGeneratesEpsilon ( );
+		setGeneratesEpsilon ( true );
+		return !res;
+	} else if ( rightHandSide.size ( ) == 1 ) {
+		return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) );
+	} else if ( rightHandSide.size ( ) == 2 ) {
+		return addRule ( std::move ( leftHandSide ), std::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) );
+	} else {
+		throw GrammarException ( "Invalid right hand side" );
+	}
+}
+
+template < class SymbolType >
+std::map < SymbolType, std::set < std::vector < SymbolType > > > CNF < SymbolType >::getRawRules ( ) const {
+	std::map < SymbolType, std::set < std::vector < SymbolType > > > res;
+
+	for ( const auto & rule : getRules ( ) )
+		for ( const auto & rhs : rule.second ) {
+			if ( rhs.template is < SymbolType > ( ) ) {
+				std::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) };
+				res[rule.first].insert ( std::move ( tmp ) );
+			} else {
+				const auto & realRHS = rhs.template get < std::pair < SymbolType, SymbolType > > ( );
+				std::vector < SymbolType > tmp { realRHS.first, realRHS.second };
+				res[rule.first].insert ( std::move ( tmp ) );
+			}
+		}
+
+	if ( getGeneratesEpsilon ( ) )
+		res[getInitialSymbol ( )].insert ( std::vector < SymbolType > { } );
+
+	return res;
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const std::vector < SymbolType > & rightHandSide ) {
+	if ( rightHandSide.size ( ) == 0 ) {
+		if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "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 GrammarException ( "Invalid right hand side" );
+	}
+}
+
+template < class SymbolType >
+void CNF < SymbolType >::setGeneratesEpsilon ( bool genEps ) {
+	generatesEpsilon = genEps;
+}
+
+template < class SymbolType >
+bool CNF < SymbolType >::getGeneratesEpsilon ( ) const {
+	return generatesEpsilon;
+}
+
+template < class SymbolType >
+int CNF < SymbolType >::compare ( const CNF & other ) const {
+	auto first = std::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules );
+	auto second = std::tie ( other.getTerminalAlphabet ( ), other.getNonterminalAlphabet ( ), other.getInitialSymbol ( ), other.rules );
+
+	std::compare < decltype ( first ) > comp;
+
+	return comp ( first, second );
+}
+
+template < class SymbolType >
+void CNF < SymbolType >::operator >>( std::ostream & out ) const {
+	out << "(CNF "
+	    << "nonterminalAlphabet = " << getNonterminalAlphabet ( )
+	    << "terminalAlphabet = " << getTerminalAlphabet ( )
+	    << "initialSymbol = " << getInitialSymbol ( )
+	    << "rules = " << rules
+	    << "generatesEpsilon = " << generatesEpsilon << ")";
+}
+
+template < class SymbolType >
+CNF < SymbolType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template < class SymbolType >
+CNF < SymbolType > CNF < SymbolType >::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, CNF::getXmlTagName() );
+
+	std::set < SymbolType > nonterminalAlphabet = GrammarFromXMLParser::parseNonterminalAlphabet ( input );
+	std::set < SymbolType > terminalAlphabet = GrammarFromXMLParser::parseTerminalAlphabet ( input );
+	SymbolType initialSymbol = GrammarFromXMLParser::parseInitialSymbol ( input );
+
+	CNF < SymbolType > grammar ( std::move ( initialSymbol ) );
+
+	grammar.setNonterminalAlphabet ( std::move ( nonterminalAlphabet ) );
+	grammar.setTerminalAlphabet ( std::move ( terminalAlphabet ) );
+
+	GrammarFromXMLParser::parseRules ( input, grammar );
+
+	bool generatesEpsilon = GrammarFromXMLParser::parseGeneratesEpsilon ( input );
+	grammar.setGeneratesEpsilon ( generatesEpsilon );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, CNF::getXmlTagName() );
+	return grammar;
+}
+
+template < class SymbolType >
+void CNF < SymbolType >::parseRule ( std::deque < sax::Token >::iterator & input, CNF & grammar ) {
+	SymbolType lhs = GrammarFromXMLParser::parseRuleSingleSymbolLHS ( input );
+	std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rhs = GrammarFromXMLParser::parseRuleOneOrTwoSymbolsRHS ( input );
+
+	grammar.addRule ( std::move ( lhs ), std::move ( rhs ) );
+}
+
+template < class SymbolType >
+void CNF < SymbolType >::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( CNF::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
+
+	GrammarToXMLComposer::composeNonterminalAlphabet ( out, this->getNonterminalAlphabet ( ) );
+	GrammarToXMLComposer::composeTerminalAlphabet ( out, this->getTerminalAlphabet ( ) );
+	GrammarToXMLComposer::composeInitialSymbol ( out, this->getInitialSymbol ( ) );
+	composeRules ( out );
+	GrammarToXMLComposer::composeGeneratesEpsilon ( out, this->getGeneratesEpsilon ( ) );
+
+	out.emplace_back ( CNF::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
+}
+
+template < class SymbolType >
+void CNF < SymbolType >::composeRules ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( "rules", sax::Token::TokenType::START_ELEMENT );
+
+	for ( const auto & rule : this->getRules ( ) )
+
+		for ( const auto & rhs : rule.second ) {
+			out.emplace_back ( "rule", sax::Token::TokenType::START_ELEMENT );
+
+			GrammarToXMLComposer::composeRuleSingleSymbolLHS ( out, rule.first );
+			GrammarToXMLComposer::composeRuleOneOrTwoSymbolsRHS ( out, rhs );
+
+			out.emplace_back ( "rule", sax::Token::TokenType::END_ELEMENT );
+		}
+
+	out.emplace_back ( "rules", sax::Token::TokenType::END_ELEMENT );
+}
+
 } /* namespace grammar */
 
 namespace std {
 
-template < >
-class ComponentConstraint< grammar::CNF, alphabet::Symbol, grammar::TerminalAlphabet > {
+template < class SymbolType >
+class ComponentConstraint< grammar::CNF < SymbolType >, SymbolType, grammar::TerminalAlphabet > {
 public:
-	static bool used ( const grammar::CNF & grammar, const alphabet::Symbol & symbol ) {
-		for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) )
-			for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second )
-				if ( ( rhs.is < alphabet::Symbol > ( ) && ( rhs.get < alphabet::Symbol > ( ) == symbol ) ) || ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).first == symbol ) )
+	static bool used ( const grammar::CNF < SymbolType > & grammar, const SymbolType & symbol ) {
+		for ( const std::pair < const SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > & rule : grammar.getRules ( ) )
+			for ( const std::variant < SymbolType, std::pair < SymbolType, SymbolType > > & rhs : rule.second )
+				if ( ( rhs.template is < SymbolType > ( ) && ( rhs.template get < SymbolType > ( ) == symbol ) ) || ( rhs.template get < std::pair < SymbolType, SymbolType > > ( ).first == symbol ) )
 					return true;
 
 		return false;
 	}
 
-	static bool available ( const grammar::CNF &, const alphabet::Symbol & ) {
+	static bool available ( const grammar::CNF < SymbolType > &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const grammar::CNF & grammar, const alphabet::Symbol & symbol ) {
-		if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) )
+	static void valid ( const grammar::CNF < SymbolType > & grammar, const SymbolType & symbol ) {
+		if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) )
 			throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in terminal alphabet since it is already nonterminal alphabet" );
 	}
 };
 
-template < >
-class ComponentConstraint< grammar::CNF, alphabet::Symbol, grammar::NonterminalAlphabet > {
+template < class SymbolType >
+class ComponentConstraint< grammar::CNF < SymbolType >, SymbolType, grammar::NonterminalAlphabet > {
 public:
-	static bool used ( const grammar::CNF & grammar, const alphabet::Symbol & symbol ) {
-		for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) {
+	static bool used ( const grammar::CNF < SymbolType > & grammar, const SymbolType & symbol ) {
+		for ( const std::pair < const SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > & rule : grammar.getRules ( ) ) {
 			if ( rule.first == symbol )
 				return true;
 
-			for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second )
-				if ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).second == symbol )
+			for ( const std::variant < SymbolType, std::pair < SymbolType, SymbolType > > & rhs : rule.second )
+				if ( rhs.template get < std::pair < SymbolType, SymbolType > > ( ).second == symbol )
 					return true;
 
 		}
 
-		if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol )
+		if ( grammar.template accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol )
 			return true;
 
 		return false;
 	}
 
-	static bool available ( const grammar::CNF &, const alphabet::Symbol & ) {
+	static bool available ( const grammar::CNF < SymbolType > &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const grammar::CNF & grammar, const alphabet::Symbol & symbol ) {
-		if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) )
+	static void valid ( const grammar::CNF < SymbolType > & grammar, const SymbolType & symbol ) {
+		if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) )
 			throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in nonterminal alphabet since it is already in terminal alphabet" );
 	}
 };
 
-template < >
-class ElementConstraint< grammar::CNF, alphabet::Symbol, grammar::InitialSymbol > {
+template < class SymbolType >
+class ElementConstraint< grammar::CNF < SymbolType >, SymbolType, grammar::InitialSymbol > {
 public:
-	static bool available ( const grammar::CNF & grammar, const alphabet::Symbol & symbol ) {
-		return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol );
+	static bool available ( const grammar::CNF < SymbolType > & grammar, const SymbolType & symbol ) {
+		return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol );
 	}
 
-	static void valid ( const grammar::CNF &, const alphabet::Symbol & ) {
+	static void valid ( const grammar::CNF < SymbolType > &, const SymbolType & ) {
 	}
 };
 
diff --git a/alib2data/src/grammar/GrammarFeatures.h b/alib2data/src/grammar/GrammarFeatures.h
index 1d00311fc7..2f506cabc1 100644
--- a/alib2data/src/grammar/GrammarFeatures.h
+++ b/alib2data/src/grammar/GrammarFeatures.h
@@ -39,6 +39,7 @@ class LG;
 template<class SymbolType = typename alphabet::Symbol >
 class CFG;
 class EpsilonFreeCFG;
+template<class SymbolType = typename alphabet::Symbol >
 class CNF;
 class GNF;
 class CSG;
diff --git a/alib2data/test-src/grammar/GrammarTest.cpp b/alib2data/test-src/grammar/GrammarTest.cpp
index c830c6d532..8b7c775507 100644
--- a/alib2data/test-src/grammar/GrammarTest.cpp
+++ b/alib2data/test-src/grammar/GrammarTest.cpp
@@ -235,7 +235,7 @@ void GrammarTest::testContextFreeParser() {
 		}
 	}
 	{
-		grammar::CNF grammar(alphabet::symbolFrom(1));
+		grammar::CNF < > grammar(alphabet::symbolFrom(1));
 
 		grammar.addNonterminalSymbol(alphabet::symbolFrom(1));
 		grammar.addNonterminalSymbol(alphabet::symbolFrom(2));
@@ -257,7 +257,7 @@ void GrammarTest::testContextFreeParser() {
 
 			std::deque<sax::Token> tokens2;
 			sax::SaxParseInterface::parseMemory(tmp, tokens2);
-			grammar::CNF grammar2 = alib::XmlDataFactory::fromTokens<grammar::CNF>(std::move(tokens2));
+			grammar::CNF < > grammar2 = alib::XmlDataFactory::fromTokens<grammar::CNF < > >(std::move(tokens2));
 
 			CPPUNIT_ASSERT( grammar == grammar2 );
 		}
diff --git a/alib2str/src/grammar/GrammarFromStringParser.cpp b/alib2str/src/grammar/GrammarFromStringParser.cpp
index fb04967309..93573ef115 100644
--- a/alib2str/src/grammar/GrammarFromStringParser.cpp
+++ b/alib2str/src/grammar/GrammarFromStringParser.cpp
@@ -521,13 +521,13 @@ GNF GrammarFromStringParser::parseGNF(std::istream& input) const {
 	return parseCFLikeGrammar<GNF>(input);
 }
 
-CNF GrammarFromStringParser::parseCNF(std::istream& input) const {
+CNF < > GrammarFromStringParser::parseCNF(std::istream& input) const {
 	GrammarFromStringLexer::Token token = m_GrammarLexer.next(input);
 	if(token.type != GrammarFromStringLexer::TokenType::CNF) {
 		throw exception::CommonException("Unrecognised CNF token.");
 	}
 
-	return parseCFLikeGrammar<CNF>(input);
+	return parseCFLikeGrammar<CNF < > >(input);
 }
 
 NonContractingGrammar GrammarFromStringParser::parseNonContractingGrammar(std::istream& input) const {
diff --git a/alib2str/src/grammar/GrammarFromStringParser.h b/alib2str/src/grammar/GrammarFromStringParser.h
index aa196afd74..a32eeeaea6 100644
--- a/alib2str/src/grammar/GrammarFromStringParser.h
+++ b/alib2str/src/grammar/GrammarFromStringParser.h
@@ -54,7 +54,7 @@ private:
 	CFG < > parseCFG(std::istream& input) const;
 	EpsilonFreeCFG parseEpsilonFreeCFG(std::istream& input) const;
 	GNF parseGNF(std::istream& input) const;
-	CNF parseCNF(std::istream& input) const;
+	CNF < > parseCNF(std::istream& input) const;
 
 	NonContractingGrammar parseNonContractingGrammar(std::istream& input) const;
 	CSG parseCSG(std::istream& input) const;
diff --git a/alib2str/src/grammar/GrammarToStringComposer.cpp b/alib2str/src/grammar/GrammarToStringComposer.cpp
index 7dee89edbf..7b1e6d3fb0 100644
--- a/alib2str/src/grammar/GrammarToStringComposer.cpp
+++ b/alib2str/src/grammar/GrammarToStringComposer.cpp
@@ -233,12 +233,12 @@ void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG
 
 GrammarToStringComposer::RegistratorWrapper<void, EpsilonFreeCFG> GrammarToStringComposerEpsilonFreeCFG = GrammarToStringComposer::RegistratorWrapper<void, EpsilonFreeCFG>(GrammarToStringComposer::compose);
 
-void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) {
+void GrammarToStringComposer::compose(std::ostream& output, const CNF < > & grammar) {
 	output << "CNF";
 	composeCFLikeGrammar(output, grammar);
 }
 
-GrammarToStringComposer::RegistratorWrapper<void, CNF> GrammarToStringComposerCNF = GrammarToStringComposer::RegistratorWrapper<void, CNF>(GrammarToStringComposer::compose);
+GrammarToStringComposer::RegistratorWrapper<void, CNF < > > GrammarToStringComposerCNF = GrammarToStringComposer::RegistratorWrapper<void, CNF < > >(GrammarToStringComposer::compose);
 
 void GrammarToStringComposer::compose(std::ostream& output, const GNF& grammar) {
 	output << "GNF";
diff --git a/alib2str/src/grammar/GrammarToStringComposer.h b/alib2str/src/grammar/GrammarToStringComposer.h
index 31576856fb..b82475965c 100644
--- a/alib2str/src/grammar/GrammarToStringComposer.h
+++ b/alib2str/src/grammar/GrammarToStringComposer.h
@@ -31,7 +31,7 @@ public:
 	static void compose(std::ostream& output, const LG& grammar);
 	static void compose(std::ostream& output, const CFG < > & grammar);
 	static void compose(std::ostream& output, const EpsilonFreeCFG& grammar);
-	static void compose(std::ostream& output, const CNF& grammar);
+	static void compose(std::ostream& output, const CNF < > & grammar);
 	static void compose(std::ostream& output, const GNF& grammar);
 	static void compose(std::ostream& output, const CSG& grammar);
 	static void compose(std::ostream& output, const NonContractingGrammar& grammar);
-- 
GitLab