From 0ad5dec5b0b6e2af8091aaa5aea6047e16d3e049 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 13 Nov 2014 19:27:36 +0100
Subject: [PATCH] Vistor plus cleanup for IsLanguage* and Trim

---
 .../grammar/properties/IsLanguageEmpty.cpp    |  71 ++++++++++-
 .../src/grammar/properties/IsLanguageEmpty.h  |  29 +++--
 .../IsLanguageGeneratingEpsilon.cpp           | 113 ++++++++++++++++++
 .../properties/IsLanguageGeneratingEpsilon.h  |  55 +++++++++
 alib2algo/src/grammar/simplify/Trim.cpp       |   2 -
 alib2algo/src/grammar/simplify/Trim.h         |   8 +-
 6 files changed, 259 insertions(+), 19 deletions(-)
 create mode 100644 alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
 create mode 100644 alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h

diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
index 05d5808b08..2cf3e291bf 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -17,8 +17,6 @@
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
 
-#include <std/set.hpp>
-
 #include "../properties/ProductiveNonterminals.h"
 
 namespace grammar {
@@ -40,6 +38,75 @@ template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftRG & grammar
 template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightLG & grammar );
 template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightRG & grammar );
 
+bool IsLanguageEmpty::isLanguageEmpty(const grammar::Grammar& grammar) {
+	bool out;
+	grammar.getData().Accept((void*) &out, IsLanguageEmpty::IS_LANGUAGE_EMPTY);
+	return out;
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::LeftLG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::LeftRG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::RightLG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::RightRG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::LG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::CFG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::CNF& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void* data, const grammar::GNF& grammar) const {
+	bool & out = *((bool*) data);
+	out = this->isLanguageEmpty(grammar);
+}
+
+void IsLanguageEmpty::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void IsLanguageEmpty::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void IsLanguageEmpty::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void IsLanguageEmpty::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const IsLanguageEmpty IsLanguageEmpty::IS_LANGUAGE_EMPTY;
+
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
index 8aa3a2e135..ccfd0b6004 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.h
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
@@ -8,13 +8,7 @@
 #ifndef IS_LANGUAGE_EMPTY_H_
 #define IS_LANGUAGE_EMPTY_H_
 
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <exception/AlibException.h>
-
-#include <alphabet/Symbol.h>
+#include <grammar/Grammar.h>
 
 namespace grammar {
 
@@ -23,8 +17,10 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class IsLanguageEmpty {
+class IsLanguageEmpty : public grammar::VisitableGrammarBase::const_visitor_type {
 public:
+	static bool isLanguageEmpty( const grammar::Grammar & grammar );
+
 	/*
 	 * Melichar 3.6 - decides whether L( grammar ) = \0
 	 *
@@ -33,6 +29,23 @@ public:
 	 */
 	template<class T>
 	static bool isLanguageEmpty( const T & grammar );
+
+private:
+	void Visit(void*, const grammar::LeftLG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LG& grammar) const;
+	void Visit(void*, const grammar::CFG& grammar) const;
+	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
+	void Visit(void*, const grammar::CNF& grammar) const;
+	void Visit(void*, const grammar::GNF& grammar) const;
+	void Visit(void*, const grammar::CSG& grammar) const;
+	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
+	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
+	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
+
+	static const IsLanguageEmpty IS_LANGUAGE_EMPTY;
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
new file mode 100644
index 0000000000..eedaab2b1c
--- /dev/null
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
@@ -0,0 +1,113 @@
+/*
+ * IsLanguageGeneratingEpsilon.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#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( ) );
+}
+
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CFG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::EpsilonFreeCFG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::GNF & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CNF & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftLG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftRG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightLG & grammar );
+template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightRG & grammar );
+
+bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon(const grammar::Grammar& grammar) {
+	bool out;
+	grammar.getData().Accept((void*) &out, IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON);
+	return out;
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftLG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftRG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightLG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightRG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CFG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CNF& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::GNF& grammar) const {
+	bool & out = *((bool*) data);
+	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const IsLanguageGeneratingEpsilon IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON;
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
new file mode 100644
index 0000000000..0eb20a7505
--- /dev/null
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
@@ -0,0 +1,55 @@
+/*
+ * IsLanguageGeneratingEpsilon.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef IS_LANGUAGE_GENERATING_EPSILON_H_
+#define IS_LANGUAGE_GENERATING_EPSILON_H_
+
+#include <grammar/Grammar.h>
+
+namespace grammar {
+
+namespace properties {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class IsLanguageGeneratingEpsilon : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	static bool isLanguageGeneratingEpsilon( const grammar::Grammar & grammar );
+
+	/*
+	 * Melichar 3.6 - decides whether L( grammar ) = \0
+	 *
+	 * Severals steps implemented in method CFGTransformations::getProductiveNonTerminals();
+	 * @see getProductiveNonTerminals
+	 */
+	template<class T>
+	static bool isLanguageGeneratingEpsilon( const T & grammar );
+
+private:
+	void Visit(void*, const grammar::LeftLG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LG& grammar) const;
+	void Visit(void*, const grammar::CFG& grammar) const;
+	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
+	void Visit(void*, const grammar::CNF& grammar) const;
+	void Visit(void*, const grammar::GNF& grammar) const;
+	void Visit(void*, const grammar::CSG& grammar) const;
+	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
+	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
+	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
+
+	static const IsLanguageGeneratingEpsilon IS_LANGUAGE_GENERATING_EPSILON;
+};
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
+#endif /* IS_LANGUAGE_GENERATING_EPSILON_H_ */
diff --git a/alib2algo/src/grammar/simplify/Trim.cpp b/alib2algo/src/grammar/simplify/Trim.cpp
index 862cbbc621..e294dd266e 100644
--- a/alib2algo/src/grammar/simplify/Trim.cpp
+++ b/alib2algo/src/grammar/simplify/Trim.cpp
@@ -17,8 +17,6 @@
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
 
-#include <std/set.hpp>
-
 #include "UnreachableSymbolsRemover.h"
 #include "UnproductiveSymbolsRemover.h"
 
diff --git a/alib2algo/src/grammar/simplify/Trim.h b/alib2algo/src/grammar/simplify/Trim.h
index 30b78b8365..25cb46cdd3 100644
--- a/alib2algo/src/grammar/simplify/Trim.h
+++ b/alib2algo/src/grammar/simplify/Trim.h
@@ -8,13 +8,7 @@
 #ifndef GRAMMAR_TRIM_H_
 #define GRAMMAR_TRIM_H_
 
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <exception/AlibException.h>
 #include <grammar/Grammar.h>
-#include <alphabet/Symbol.h>
 
 namespace grammar {
 
@@ -25,7 +19,7 @@ namespace simplify {
  */
 class Trim : public grammar::VisitableGrammarBase::const_visitor_type {
 public:
-	static grammar::Grammar trim( const grammar::Grammar & automaton );
+	static grammar::Grammar trim( const grammar::Grammar & grammar );
 
 	/**
 	 * Removes unproductive and useless symbols - Melichar 3.12
-- 
GitLab