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