From 10444ab6ae6ca0eefd033d55f596f5d4f56b7023 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 1 Dec 2016 21:55:10 +0100
Subject: [PATCH] template properties retrieving algorithms

---
 .../grammar/properties/IsLanguageEmpty.cpp    | 17 +-----
 .../src/grammar/properties/IsLanguageEmpty.h  | 17 ++++++
 .../IsLanguageGeneratingEpsilon.cpp           | 17 +-----
 .../properties/IsLanguageGeneratingEpsilon.h  | 17 ++++++
 .../properties/NonterminalUnitRuleCycle.cpp   | 46 ---------------
 .../properties/NonterminalUnitRuleCycle.h     | 50 +++++++++++++++-
 .../properties/NullableNonterminals.cpp       | 44 ++------------
 .../grammar/properties/NullableNonterminals.h | 44 +++++++++++++-
 .../properties/ProductiveNonterminals.cpp     | 49 ++--------------
 .../properties/ProductiveNonterminals.h       | 49 +++++++++++++++-
 .../properties/RecursiveNonterminal.cpp       | 52 -----------------
 .../grammar/properties/RecursiveNonterminal.h | 57 ++++++++++++++++++-
 .../grammar/properties/UnreachableSymbols.cpp | 50 ++--------------
 .../grammar/properties/UnreachableSymbols.h   | 48 +++++++++++++++-
 14 files changed, 289 insertions(+), 268 deletions(-)

diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
index bba4aa3ffe..c0caf51f88 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -7,25 +7,12 @@
 
 #include "IsLanguageEmpty.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 "../properties/ProductiveNonterminals.h"
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) {
-	return grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+bool IsLanguageEmpty::isLanguageEmpty(const grammar::Grammar& grammar) {
+	return dispatch(grammar.getData());
 }
 
 auto IsLanguageEmptyCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CFG < > >(IsLanguageEmpty::isLanguageEmpty);
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
index 8a67a20b9a..14e1916604 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.h
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
@@ -12,6 +12,18 @@
 
 #include <grammar/Grammar.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 <grammar/properties/ProductiveNonterminals.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,6 +45,11 @@ public:
 	static bool isLanguageEmpty( const T & grammar );
 };
 
+template<class T>
+bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) {
+	return grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
index b030f827c6..d8666e129f 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
@@ -7,25 +7,12 @@
 
 #include "IsLanguageGeneratingEpsilon.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 "../properties/NullableNonterminals.h"
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const T & grammar ) {
-	return grammar::properties::NullableNonterminals::getNullableNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon(const grammar::Grammar& grammar) {
+	return dispatch(grammar.getData());
 }
 
 auto IsLanguageGeneratingEpsilonCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CFG < > >(IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
index 9ed1f538b4..ce9293508d 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
@@ -12,6 +12,18 @@
 
 #include <grammar/Grammar.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 <grammar/properties/NullableNonterminals.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,6 +45,11 @@ public:
 	static bool isLanguageGeneratingEpsilon( const T & grammar );
 };
 
+template<class T>
+bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const T & grammar ) {
+	return grammar::properties::NullableNonterminals::getNullableNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
index c3bd13edc9..e58c4e9460 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
@@ -7,56 +7,10 @@
 
 #include "NonterminalUnitRuleCycle.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 <set>
-#include <deque>
-
-#include <exception/CommonException.h>
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal) {
-	if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) {
-		throw exception::CommonException("Nonterminal symbol \"" + (std::string) nonterminal + "\" is not present in grammar.");
-	}
-
-	std::deque<std::set<alphabet::Symbol>> Ni;
-	Ni.push_back(std::set<alphabet::Symbol>{nonterminal});
-	int i = 1;
-
-	while(true) {
-		Ni.push_back(Ni.at(i-1));
-		for(const auto&rule : grammar.getRawRules()) {
-			const alphabet::Symbol& lhs = rule.first;
-
-			for(const auto& rhs : rule.second) {
-				if(Ni.at(i-1).count(lhs) && rhs.size() == 1 && grammar.getNonterminalAlphabet().count(rhs.front())) {
-					Ni.at(i).insert(rhs.front());
-				}
-			}
-		}
-
-		if(Ni.at(i) == Ni.at(i-1))
-			break;
-		
-		i += 1;
-	}
-
-	return Ni.at(i);
-}
-
 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);
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
index 3080c7b7b4..3103915791 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
@@ -13,6 +13,21 @@
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.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 <set>
+#include <deque>
+
+#include <exception/CommonException.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,10 +48,41 @@ public:
 	 * @param nonterminal nonterminal
 	 * @return set of nonterminals for which we can be derived from giveUnitRuleCyclen nonterminals in finite number of steps
 	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal);
+	template<class T, class SymbolType>
+	static std::set<SymbolType> getNonterminalUnitRuleCycle(const T& grammar, const SymbolType& nonterminal);
 };
 
+template<class T, class SymbolType >
+std::set<SymbolType> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const T& grammar, const SymbolType& nonterminal) {
+	if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) {
+		throw exception::CommonException("Nonterminal symbol \"" + std::to_string ( nonterminal ) + "\" is not present in grammar.");
+	}
+
+	std::deque<std::set<SymbolType>> Ni;
+	Ni.push_back(std::set<SymbolType>{nonterminal});
+	int i = 1;
+
+	while(true) {
+		Ni.push_back(Ni.at(i-1));
+		for(const auto &rule : grammar.getRawRules()) {
+			const SymbolType& lhs = rule.first;
+
+			for(const auto& rhs : rule.second) {
+				if(Ni.at(i-1).count(lhs) && rhs.size() == 1 && grammar.getNonterminalAlphabet().count(rhs.front())) {
+					Ni.at(i).insert(rhs.front());
+				}
+			}
+		}
+
+		if(Ni.at(i) == Ni.at(i-1))
+			break;
+		
+		i += 1;
+	}
+
+	return Ni.at(i);
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
index 754c52aba4..1d503d0034 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
@@ -7,50 +7,10 @@
 
 #include "NullableNonterminals.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 <set>
-#include <deque>
-#include <algorithm>
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const T& grammar) {
-	std::deque<std::set<alphabet::Symbol>> Ni;
-
-	Ni.push_back(std::set<alphabet::Symbol>{ });
-	int i = 1;
-
-	while(true) {
-		Ni.push_back(std::set<alphabet::Symbol>{ });
-		for(const auto& rule : grammar.getRawRules()) {
-			for(const auto& rhs : rule.second) {
-				if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const alphabet::Symbol& symb){return Ni.at(i-1).count(symb);})) {
-					Ni.at(i).insert(rule.first);
-				}
-			}
-		}
-
-		if(Ni.at(i) == Ni.at(i-1))
-			break;
-
-		i += 1;
-	}
-
-	return Ni.at(i);
-}
-
 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);
@@ -61,6 +21,10 @@ auto NullableNonterminalsLeftRG = NullableNonterminals::RegistratorWrapper<std::
 auto NullableNonterminalsRightLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG < > >(NullableNonterminals::getNullableNonterminals);
 auto NullableNonterminalsRightRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG < > >(NullableNonterminals::getNullableNonterminals);
 
+std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const grammar::Grammar& grammar ) {
+	return dispatch(grammar.getData());
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h
index 34edd8f8eb..9423ac9ac6 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.h
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.h
@@ -13,6 +13,20 @@
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.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 <set>
+#include <deque>
+#include <algorithm>
+
 namespace grammar {
 
 namespace properties {
@@ -33,10 +47,36 @@ public:
 	 * @param grammar grammar
 	 * @return set of nullable nonterminals from grammar
 	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar);
+	template<class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static std::set<SymbolType> getNullableNonterminals(const T& grammar);
 };
 
+template<class T, class SymbolType >
+std::set<SymbolType> NullableNonterminals::getNullableNonterminals(const T& grammar) {
+	std::deque<std::set<SymbolType>> Ni;
+
+	Ni.push_back(std::set<SymbolType>{ });
+	int i = 1;
+
+	while(true) {
+		Ni.push_back(std::set<SymbolType>{ });
+		for(const auto& rule : grammar.getRawRules()) {
+			for(const auto& rhs : rule.second) {
+				if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const SymbolType& symb){return Ni.at(i-1).count(symb);})) {
+					Ni.at(i).insert(rule.first);
+				}
+			}
+		}
+
+		if(Ni.at(i) == Ni.at(i-1))
+			break;
+
+		i += 1;
+	}
+
+	return Ni.at(i);
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
index 8e9a83d0a0..a62f6c3c2e 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -7,55 +7,10 @@
 
 #include "ProductiveNonterminals.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 <set>
-#include <deque>
-#include <algorithm>
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-std::set<alphabet::Symbol> ProductiveNonterminals::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 );
-}
-
 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);
@@ -66,6 +21,10 @@ auto ProductiveNonterminalsLeftRG = ProductiveNonterminals::RegistratorWrapper<s
 auto ProductiveNonterminalsRightLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG < > >(ProductiveNonterminals::getProductiveNonterminals);
 auto ProductiveNonterminalsRightRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG < > >(ProductiveNonterminals::getProductiveNonterminals);
 
+std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals(const grammar::Grammar& grammar ) {
+	return dispatch(grammar.getData());
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
index e2f63416d0..a5c6d46415 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
@@ -13,6 +13,20 @@
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.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 <set>
+#include <deque>
+#include <algorithm>
+
 namespace grammar {
 
 namespace properties {
@@ -27,10 +41,41 @@ public:
 	/**
 	 * Implements steps 1 through 3 in Melichar 3.6
 	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
+	template<class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static std::set<SymbolType> getProductiveNonterminals( const T & grammar );
 };
 
+template<class T, class SymbolType >
+std::set<SymbolType> ProductiveNonterminals::getProductiveNonterminals( const T & grammar ) {
+	// 1.
+	std::deque<std::set<SymbolType>> Ni;
+	Ni.push_back( std::set<SymbolType>( ) );
+
+	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 SymbolType & 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 );
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
index e390e5676a..20ecaa30ac 100644
--- a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
+++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
@@ -6,63 +6,11 @@
  */
 
 #include "RecursiveNonterminal.h"
-#include "NullableNonterminals.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 <set>
-#include <deque>
-
-#include <exception/CommonException.h>
 
 namespace grammar {
 
 namespace properties {
 
-template < class T >
-bool RecursiveNonterminal::isNonterminalRecursive ( const T & grammar, const alphabet::Symbol & nonterminal ) {
-	if ( grammar.getNonterminalAlphabet ( ).count ( nonterminal ) == 0 )
-		throw exception::CommonException ( "Nonterminal symbol \"" + ( std::string ) nonterminal + "\" is not present in grammar." );
-
-	std::deque < std::set < alphabet::Symbol > > Ni;
-	Ni.push_back ( std::set < alphabet::Symbol > { nonterminal } );
-	unsigned i = 1;
-
-	auto rawRules = grammar.getRawRules ( );
-	auto nullable = grammar::properties::NullableNonterminals::getNullableNonterminals ( grammar );
-
-	while ( i <= grammar.getNonterminalAlphabet ( ).size ( ) ) {
-		Ni.push_back ( std::set < alphabet::Symbol > { } );
-
-		for ( const alphabet::Symbol & lhs : Ni.at ( i - 1 ) )
-			if ( rawRules.find ( lhs ) != rawRules.end ( ) )
-				for ( const std::vector < alphabet::Symbol > & rhs : rawRules.find ( lhs )->second )
-					for ( const alphabet::Symbol & rhsSymbol : rhs ) {
-						if ( grammar.getTerminalAlphabet ( ).count ( rhsSymbol ) ) break;
-
-						Ni.at ( i ).insert ( rhsSymbol );
-
-						if ( !nullable.count ( rhsSymbol ) ) break;
-					}
-
-
-
-		if ( Ni.at ( i ).count ( nonterminal ) ) return true;
-
-		i += 1;
-	}
-
-	return false;
-}
-
 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 );
diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.h b/alib2algo/src/grammar/properties/RecursiveNonterminal.h
index b6b9c288be..f5a63e3777 100644
--- a/alib2algo/src/grammar/properties/RecursiveNonterminal.h
+++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.h
@@ -13,6 +13,23 @@
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
+#include "NullableNonterminals.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 <set>
+#include <deque>
+
+#include <exception/CommonException.h>
+
 namespace grammar {
 
 namespace properties {
@@ -31,11 +48,47 @@ public:
 	 * @param nonterminal nonterminal
 	 * @return bool which denote whether the nonterminal is recursive in the grammar
 	 */
-	template < class T >
-	static bool isNonterminalRecursive ( const T & grammar, const alphabet::Symbol & nonterminal );
+	template < class T, class SymbolType  >
+	static bool isNonterminalRecursive ( const T & grammar, const SymbolType & nonterminal );
 
 };
 
+template < class T, class SymbolType  >
+bool RecursiveNonterminal::isNonterminalRecursive ( const T & grammar, const SymbolType & nonterminal ) {
+	if ( grammar.getNonterminalAlphabet ( ).count ( nonterminal ) == 0 )
+		throw exception::CommonException ( "Nonterminal symbol \"" + ( std::string ) nonterminal + "\" is not present in grammar." );
+
+	std::deque < std::set < SymbolType > > Ni;
+	Ni.push_back ( std::set < SymbolType > { nonterminal } );
+	unsigned i = 1;
+
+	auto rawRules = grammar.getRawRules ( );
+	auto nullable = grammar::properties::NullableNonterminals::getNullableNonterminals ( grammar );
+
+	while ( i <= grammar.getNonterminalAlphabet ( ).size ( ) ) {
+		Ni.push_back ( std::set < SymbolType > { } );
+
+		for ( const SymbolType & lhs : Ni.at ( i - 1 ) )
+			if ( rawRules.find ( lhs ) != rawRules.end ( ) )
+				for ( const std::vector < SymbolType > & rhs : rawRules.find ( lhs )->second )
+					for ( const SymbolType & rhsSymbol : rhs ) {
+						if ( grammar.getTerminalAlphabet ( ).count ( rhsSymbol ) ) break;
+
+						Ni.at ( i ).insert ( rhsSymbol );
+
+						if ( !nullable.count ( rhsSymbol ) ) break;
+					}
+
+
+
+		if ( Ni.at ( i ).count ( nonterminal ) ) return true;
+
+		i += 1;
+	}
+
+	return false;
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
index 33422b3cea..3dbf6be5a2 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
@@ -7,56 +7,10 @@
 
 #include "UnreachableSymbols.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 <algorithm>
-#include <deque>
-#include <set>
-
 namespace grammar {
 
 namespace properties {
 
-template<class T>
-std::set<alphabet::Symbol> UnreachableSymbols::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 );
-}
-
 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);
@@ -67,6 +21,10 @@ auto UnreachableSymbolsLeftRG = UnreachableSymbols::RegistratorWrapper<std::set<
 auto UnreachableSymbolsRightLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG < > >(UnreachableSymbols::getUnreachableSymbols);
 auto UnreachableSymbolsRightRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG < > >(UnreachableSymbols::getUnreachableSymbols);
 
+std::set < alphabet::Symbol > UnreachableSymbols::getUnreachableSymbols ( const grammar::Grammar & grammar ) {
+	return dispatch ( grammar.getData ( ) );
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h
index e4b1979225..e09346d906 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.h
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h
@@ -13,6 +13,20 @@
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.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 <algorithm>
+#include <deque>
+#include <set>
+
 namespace grammar {
 
 namespace properties {
@@ -27,10 +41,42 @@ public:
 	/**
 	 * Implements
 	 */
-	template<class T>
+	template<class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
 	static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
 };
 
+template<class T, class SymbolType >
+std::set<alphabet::Symbol> UnreachableSymbols::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 );
+}
+
 } /* namespace properties */
 
 } /* namespace grammar */
-- 
GitLab