diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index afda692fa116d3b259174cc8c777b3d66deb1a03..99955d0f316c62077b76c6e3c9623520b97b8a31 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -7,25 +7,24 @@ #include "ConversionHandler.h" -#include "conversions/fa2re/StateElimination.h" -#include "conversions/fa2re/Algebraic.h" +#include "automaton/convert/ToRegExpStateElimination.h" +#include "automaton/convert/ToRegExpAlgebraic.h" +#include "automaton/convert/ToGrammarLeftRG.h" +#include "automaton/convert/ToGrammarRightRG.h" -#include "conversions/re2fa/GlushkovNFA.h" -#include "conversions/re2fa/Thompson.h" -#include "conversions/re2fa/BrzozowskiDerivation.h" +#include "regexp/convert/ToAutomatonGlushkov.h" +#include "regexp/convert/ToAutomatonThompson.h" +#include "regexp/convert/ToAutomatonDerivation.h" -#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h" -#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h" +#include "grammar/convert/ToAutomaton.h" -#include "conversions/rg2fa/RGtoFA.h" +#include "grammar/convert/ToRegExpAlgebraic.h" -#include "conversions/rg2re/Algebraic.h" +#include "regexp/convert/ToGrammarRightRGGlushkov.h" +#include "regexp/convert/ToGrammarRightRGDerivation.h" -#include "conversions/re2rg/re2rrg/GlushkovNFA.h" -#include "conversions/re2rg/re2rrg/BrzozowskiDerivation.h" - -#include "conversions/rg2rg/LeftToRightRegularGrammar.h" -#include "conversions/rg2rg/RightToLeftRegularGrammar.h" +#include "grammar/convert/ToGrammarRightRG.h" +#include "grammar/convert/ToGrammarLeftRG.h" using namespace alib; @@ -107,11 +106,11 @@ void ConversionHandler::convertFSMtoRE( void ) std::string xmlMark = m_tokens.front( ).getData( ); if( xmlMark == "NFA") { const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens ); - regexp::UnboundedRegExp re = conversions::fa2re::Algebraic::convert( fsm ); + regexp::UnboundedRegExp re = automaton::convert::ToRegExpAlgebraic::convert( fsm ); alib::DataFactory::toStdout(re); } else if( xmlMark == "DFA") { const automaton::DFA fsm = alib::DataFactory::fromTokens<automaton::DFA>( m_tokens ); - regexp::UnboundedRegExp re = conversions::fa2re::Algebraic::convert( fsm ); + regexp::UnboundedRegExp re = automaton::convert::ToRegExpAlgebraic::convert( fsm ); alib::DataFactory::toStdout(re); } else { throw exception::AlibException("Unrecognised formalism"); @@ -120,7 +119,7 @@ void ConversionHandler::convertFSMtoRE( void ) } case STATE_ELIMINATION: default: { - alib::DataFactory::toStdout(conversions::fa2re::StateElimination::convert(automaton)); + alib::DataFactory::toStdout(automaton::convert::ToRegExpStateElimination::convert(automaton)); break; } } @@ -143,8 +142,7 @@ void ConversionHandler::convertFSMtoRRG( void ) switch( m_algorithm ) { default: { - conversions::fa2rg::FAtoRRGConverter conv; - alib::DataFactory::toStdout(conv.convert(fsm)); + alib::DataFactory::toStdout(automaton::convert::ToGrammarRightRG::convert(fsm)); break; } } @@ -157,8 +155,7 @@ void ConversionHandler::convertFSMtoLRG( void ) switch( m_algorithm ) { default: { - conversions::fa2rg::FAtoLRGConverter conv; - alib::DataFactory::toStdout(conv.convert(fsm)); + alib::DataFactory::toStdout(automaton::convert::ToGrammarLeftRG::convert(fsm)); break; } } @@ -173,16 +170,16 @@ void ConversionHandler::convertREtoFSM( void ) switch( m_algorithm ) { case BRZOZOWSKI_DERIVATION: { - alib::DataFactory::toStdout(conversions::re2fa::BrzozowskiDerivation::convert(regexp)); + alib::DataFactory::toStdout(regexp::convert::ToAutomatonDerivation::convert(regexp)); break; } case THOMPSON_NFA: { - alib::DataFactory::toStdout(conversions::re2fa::Thompson::convert(regexp)); + alib::DataFactory::toStdout(regexp::convert::ToAutomatonThompson::convert(regexp)); break; } case GLUSHKOV_NFA: default: { - alib::DataFactory::toStdout(conversions::re2fa::GlushkovNFA::convert(regexp)); + alib::DataFactory::toStdout(regexp::convert::ToAutomatonGlushkov::convert(regexp)); break; } } @@ -205,11 +202,11 @@ void ConversionHandler::convertREtoRRG( void ) switch(m_algorithm) { case BRZOZOWSKI_DERIVATION: { - alib::DataFactory::toStdout(conversions::re2rg::BrzozowskiDerivation::convert(regexp)); + alib::DataFactory::toStdout(regexp::convert::ToGrammarRightRGDerivation::convert(regexp)); break; } default: { - alib::DataFactory::toStdout(conversions::re2rg::GlushkovNFA::convert(regexp)); + alib::DataFactory::toStdout(regexp::convert::ToGrammarRightRGGlushkov::convert(regexp)); break; } } @@ -220,7 +217,7 @@ void ConversionHandler::convertREtoRRG( void ) void ConversionHandler::convertRGtoFSM( void ) { const grammar::Grammar grammar = alib::DataFactory::fromTokens<grammar::Grammar>(m_tokens); - alib::DataFactory::toStdout(conversions::rg2fa::RGtoFA::convert(grammar)); + alib::DataFactory::toStdout(grammar::convert::ToAutomaton::convert(grammar)); } void ConversionHandler::convertRGtoRG( void ) @@ -245,7 +242,7 @@ void ConversionHandler::convertRGtoRE( void ) { case BRZOZOWSKI_ALGEBRAIC: default: - alib::DataFactory::toStdout(conversions::rg2re::Algebraic::convert(grammar)); + alib::DataFactory::toStdout(grammar::convert::ToRegExpAlgebraic::convert(grammar)); break; } } @@ -257,7 +254,7 @@ void ConversionHandler::convertLRGtoRRG( void ) switch( m_algorithm ) { default: - alib::DataFactory::toStdout(conversions::rg2rg::LeftToRightRegularGrammar::convert(lrg)); + alib::DataFactory::toStdout(grammar::convert::ToGrammarRightRG::convert(lrg)); break; } } @@ -269,7 +266,7 @@ void ConversionHandler::convertRRGtoLRG( void ) switch( m_algorithm ) { default: - alib::DataFactory::toStdout(conversions::rg2rg::RightToLeftRegularGrammar::convert(rrg)); + alib::DataFactory::toStdout(grammar::convert::ToGrammarLeftRG::convert(rrg)); break; } } diff --git a/aderivation2/src/aderivation.cpp b/aderivation2/src/aderivation.cpp index a4eb0bb26d53be2df8322b1725e77c0642546a98..b3021c88dccdc1f9cb160b954442e1e321929e0b 100644 --- a/aderivation2/src/aderivation.cpp +++ b/aderivation2/src/aderivation.cpp @@ -10,7 +10,7 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "regexp/RegExpDerivation.h" +#include "regexp/transform/RegExpDerivation.h" int main(int argc, char** argv) { diff --git a/adeterminize2/src/adeterminize.cpp b/adeterminize2/src/adeterminize.cpp index 3b8086cbb2205a0ec3224ac23138c04631147cd9..8b37b6a25af7d0bdbad5c21abd0b6d46ca6f1bce 100644 --- a/adeterminize2/src/adeterminize.cpp +++ b/adeterminize2/src/adeterminize.cpp @@ -10,12 +10,9 @@ #include "factory/DataFactory.hpp" #include "exception/AlibException.h" -#include "determinize/nfa/NFADeterminizer.h" -#include "determinize/idpda/IDPDADeterminizer.h" -#include "determinize/vpa/VPADeterminizer.h" -#include "determinize/hdpda/HDPDADeterminizer.h" -#include "automaton/PDAToRHPDA.h" -#include "automaton/RHPDAToPDA.h" +#include "automaton/determinize/Determinize.h" +#include "automaton/transform/PDAToRHPDA.h" +#include "automaton/transform/RHPDAToPDA.h" #define VERSION "0.0.1" @@ -93,7 +90,7 @@ int main(int argc, char** argv) { std::string xmlMark = tokens.front( ).getData( ); if(xmlMark == "NFA") { automaton::NFA nfa = alib::DataFactory::fromTokens<automaton::NFA>(tokens); - automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa); + automaton::DFA dfa = automaton::determinize::Determinize::determinize(nfa); alib::DataFactory::toStdout(dfa); return 0; } else if(xmlMark == "DFA") { @@ -106,18 +103,18 @@ int main(int argc, char** argv) { } else if (type == TYPE_IDPDA) { automaton::InputDrivenNPDA npda = alib::DataFactory::fromTokens<automaton::InputDrivenNPDA>(tokens); - automaton::DPDA dpda = determinize::IDPDADeterminizer::determinize(npda); + automaton::DPDA dpda = automaton::determinize::Determinize::determinize(npda); alib::DataFactory::toStdout(dpda); return 0; } else if (type == TYPE_VPA) { automaton::VisiblyPushdownNPDA npda = alib::DataFactory::fromTokens<automaton::VisiblyPushdownNPDA>(tokens); - automaton::VisiblyPushdownDPDA dpda = determinize::VPADeterminizer::determinize(npda); + automaton::VisiblyPushdownDPDA dpda = automaton::determinize::Determinize::determinize(npda); alib::DataFactory::toStdout(dpda); return 0; } else if (type == TYPE_RHDPDA) { automaton::NPDA npda = alib::DataFactory::fromTokens<automaton::NPDA>(tokens); automaton::RealTimeHeightDeterministicNPDA rhpda = automaton::PDAToRHPDA::convert(npda); - automaton::RealTimeHeightDeterministicDPDA dpda = determinize::HDPDADeterminizer::determinize(rhpda); + automaton::RealTimeHeightDeterministicDPDA dpda = automaton::determinize::Determinize::determinize(rhpda); automaton::DPDA dpda2 = automaton::RHPDAToPDA::convert(dpda); alib::DataFactory::toStdout(dpda2); return 0; diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp index 2baf53dc82a8e98287a078c6d89316368a4db80d..0256a31544d80620a1918386877f46efd574c891 100644 --- a/aepsilon2/src/aepsilon.cpp +++ b/aepsilon2/src/aepsilon.cpp @@ -8,7 +8,7 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "epsilon/fsm/FSMEpsilonRemover.h" +#include "automaton/simplify/EpsilonRemover.h" int main(int argc, char** argv) { @@ -17,9 +17,9 @@ int main(int argc, char** argv) { std::cout << "Remove epsilon transitions from automaton." << std::endl << "Usage: aepsilon [automaton.xml]" << std::endl; return -1; } else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) { - alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>())); + alib::DataFactory::toStdout(automaton::simplify::EpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>())); } else if (argc == 2) { - alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>())); + alib::DataFactory::toStdout(automaton::simplify::EpsilonRemover::remove(alib::DataFactory::fromFile<automaton::Automaton>(argv[1]))); } else { std::cout << "Automaton minimize require deterministic finite automaton" << std::endl; return 1; diff --git a/aintegral2/src/aintegral.cpp b/aintegral2/src/aintegral.cpp index 9ca873cc68f49cae022f5b125b36c58ccd94c753..0a4d0e9a56e6a473284876a9602d32125972c46b 100644 --- a/aintegral2/src/aintegral.cpp +++ b/aintegral2/src/aintegral.cpp @@ -10,7 +10,7 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "regexp/RegExpIntegral.h" +#include "regexp/transform/RegExpIntegral.h" int main(int argc, char** argv) { diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d182191a0aa40d7a01859d263d4813f478e36ed0 --- /dev/null +++ b/alib2algo/src/automaton/convert/ToGrammar.cpp @@ -0,0 +1,94 @@ +/* + * ToGrammarLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#include "ToGrammar.h" +#include "ToGrammarRightRG.h" +#include <exception/AlibException.h> + +namespace automaton { + +namespace convert { + +grammar::Grammar ToGrammar::convert(const automaton::Automaton& automaton) { + grammar::Grammar* out = NULL; + automaton.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void ToGrammar::Visit(void*, const automaton::EpsilonNFA& ) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void ToGrammar::Visit(void*, const automaton::MultiInitialStateNFA& ) const { + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void ToGrammar::Visit(void* data, const automaton::NFA& automaton) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(ToGrammarRightRG::convert(automaton)); +} + +void ToGrammar::Visit(void* data, const automaton::DFA& automaton) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(ToGrammarRightRG::convert(automaton)); +} + +void ToGrammar::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void ToGrammar::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void ToGrammar::Visit(void*, const DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void ToGrammar::Visit(void*, const SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void ToGrammar::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void ToGrammar::Visit(void*, const VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void ToGrammar::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void ToGrammar::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void ToGrammar::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void ToGrammar::Visit(void*, const NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void ToGrammar::Visit(void*, const SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void ToGrammar::Visit(void*, const OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const ToGrammar ToGrammar::TO_GRAMMAR; + +} /* namespace convert */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h new file mode 100644 index 0000000000000000000000000000000000000000..5a25ba02cb7e845e89115acaac28c2587d52a295 --- /dev/null +++ b/alib2algo/src/automaton/convert/ToGrammar.h @@ -0,0 +1,55 @@ +/* + * ToGrammar.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _AUTOMATON_TO_GRAMMAR_H__ +#define _AUTOMATON_TO_GRAMMAR_H__ + +#include <grammar/Regular/LeftRG.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/DFA.h> + +#include <grammar/Grammar.h> +#include <automaton/Automaton.h> + +namespace automaton { + +namespace convert { + +class ToGrammar : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static grammar::Grammar convert(const automaton::Automaton& automaton); + +private: + void Visit(void*, const EpsilonNFA& automaton) const; + void Visit(void*, const MultiInitialStateNFA& automaton) const; + void Visit(void*, const NFA& automaton) const; + void Visit(void*, const DFA& automaton) const; + void Visit(void*, const ExtendedNFA& automaton) const; + void Visit(void*, const CompactNFA& automaton) const; + void Visit(void*, const DPDA& automaton) const; + void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownDPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; + void Visit(void*, const OneTapeDTM& automaton) const; + + static const ToGrammar TO_GRAMMAR; +}; + +} /* namespace convert */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_TO_GRAMMAR_H__ */ diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp similarity index 77% rename from alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp rename to alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp index 5fffa8038cc2c02c8d46eb9d80d2630e6fe572f9..f82e91eeb5c61004e466b06b7b0cdcecf02d2a30 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp +++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp @@ -1,17 +1,22 @@ -#include "FAtoLRGConverter.h" +/* + * ToGrammarLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#include "ToGrammarLeftRG.h" #include <map> #include <alphabet/LabeledSymbol.h> #include <exception/AlibException.h> -namespace conversions -{ +namespace automaton { -namespace fa2rg -{ +namespace convert { -grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton) +grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA& automaton) { std::map<automaton::State, alphabet::Symbol> nonterminalMap; // step 2 @@ -59,7 +64,7 @@ grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton) return grammar; } -grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton) +grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA& automaton) { std::map<automaton::State, alphabet::Symbol> nonterminalMap; // step 2 @@ -105,42 +110,42 @@ grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton) return grammar; } -grammar::Grammar FAtoLRGConverter::convert(const automaton::Automaton& automaton) { +grammar::Grammar ToGrammarLeftRG::convert(const automaton::Automaton& automaton) { grammar::Grammar* out = NULL; - automaton.getData().Accept((void*) &out, FAtoLRGConverter::FA_TO_LRG_CONVERTER); + automaton.getData().Accept((void*) &out, ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG); grammar::Grammar res = std::move(*out); delete out; return res; } -void FAtoLRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const { +void ToGrammarLeftRG::Visit(void*, const automaton::EpsilonNFA& ) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void FAtoLRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const { +void ToGrammarLeftRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void FAtoLRGConverter::Visit(void* data, const automaton::NFA& automaton) const { +void ToGrammarLeftRG::Visit(void* data, const automaton::NFA& automaton) const { grammar::Grammar* & out = *((grammar::Grammar**) data); out = new grammar::Grammar(this->convert(automaton)); } -void FAtoLRGConverter::Visit(void* data, const automaton::DFA& automaton) const { +void ToGrammarLeftRG::Visit(void* data, const automaton::DFA& automaton) const { grammar::Grammar* & out = *((grammar::Grammar**) data); out = new grammar::Grammar(this->convert(automaton)); } -void FAtoLRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const { +void ToGrammarLeftRG::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FAtoLRGConverter::Visit(void*, const automaton::CompactNFA& ) const { +void ToGrammarLeftRG::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const FAtoLRGConverter FAtoLRGConverter::FA_TO_LRG_CONVERTER; +const ToGrammarLeftRG ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h similarity index 70% rename from alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h rename to alib2algo/src/automaton/convert/ToGrammarLeftRG.h index 37056683d83d9f8b557e7e2b2ef7ebf461f800e2..26e7f96752801e4e64d3172026879e10694fb0b7 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h +++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h @@ -1,5 +1,12 @@ -#ifndef __FATOLRGCONVERTER_H__ -#define __FATOLRGCONVERTER_H__ +/* + * ToGrammarLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#ifndef __TO_GRAMMAR_LEFT_RG_H__ +#define __TO_GRAMMAR_LEFT_RG_H__ #include <grammar/Regular/LeftRG.h> #include <automaton/FSM/NFA.h> @@ -8,18 +15,15 @@ #include <grammar/Grammar.h> #include <automaton/Automaton.h> -namespace conversions -{ +namespace automaton { -namespace fa2rg -{ +namespace convert { /** * Finite automaton to right regular grammar converter. * Source: My own :) */ -class FAtoLRGConverter : public automaton::VisitableConstFSMBase -{ +class ToGrammarLeftRG : public automaton::VisitableConstFSMBase { public: /** * Performs conversion. @@ -38,11 +42,11 @@ private: void Visit(void*, const automaton::ExtendedNFA& automaton) const; void Visit(void*, const automaton::CompactNFA& automaton) const; - static const FAtoLRGConverter FA_TO_LRG_CONVERTER; + static const ToGrammarLeftRG TO_GRAMMAR_LEFT_RG; }; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* __FATOLRGCONVERTER_H__ */ +#endif /* __TO_GRAMMAR_LEFT_RG_H__ */ diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp similarity index 81% rename from alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp rename to alib2algo/src/automaton/convert/ToGrammarRightRG.cpp index 4825bf5e7a6667b97b7756c40a9381d8acdd155a..39e72428a7f24a1c41f3f648eed49f33354f32b5 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp +++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp @@ -1,16 +1,19 @@ -#include "FAtoRRGConverter.h" - +/* + * ToGrammarRightRG.cpp + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#include "ToGrammarRightRG.h" #include <alphabet/LabeledSymbol.h> - #include <exception/AlibException.h> -namespace conversions -{ +namespace automaton { -namespace fa2rg -{ +namespace convert { -grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton) +grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA& automaton) { std::map<automaton::State, alphabet::Symbol> nonterminalMap; @@ -55,7 +58,7 @@ grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton) return grammar; } -grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton) +grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA& automaton) { std::map<automaton::State, alphabet::Symbol> nonterminalMap; @@ -99,41 +102,41 @@ grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton) return grammar; } -grammar::Grammar FAtoRRGConverter::convert(const automaton::Automaton& automaton) { +grammar::Grammar ToGrammarRightRG::convert(const automaton::Automaton& automaton) { grammar::Grammar* out = NULL; - automaton.getData().Accept((void*) &out, FAtoRRGConverter::FA_TO_RRG_CONVERTER); + automaton.getData().Accept((void*) &out, ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG); grammar::Grammar res = std::move(*out); delete out; return res; } -void FAtoRRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const { +void ToGrammarRightRG::Visit(void*, const automaton::EpsilonNFA& ) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void FAtoRRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const { +void ToGrammarRightRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void FAtoRRGConverter::Visit(void* data, const automaton::NFA& automaton) const { +void ToGrammarRightRG::Visit(void* data, const automaton::NFA& automaton) const { grammar::Grammar* & out = *((grammar::Grammar**) data); out = new grammar::Grammar(this->convert(automaton)); } -void FAtoRRGConverter::Visit(void* data, const automaton::DFA& automaton) const { +void ToGrammarRightRG::Visit(void* data, const automaton::DFA& automaton) const { grammar::Grammar* & out = *((grammar::Grammar**) data); out = new grammar::Grammar(this->convert(automaton)); } -void FAtoRRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const { +void ToGrammarRightRG::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FAtoRRGConverter::Visit(void*, const automaton::CompactNFA& ) const { +void ToGrammarRightRG::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const FAtoRRGConverter FAtoRRGConverter::FA_TO_RRG_CONVERTER; +const ToGrammarRightRG ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h similarity index 70% rename from alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h rename to alib2algo/src/automaton/convert/ToGrammarRightRG.h index 1c301fc2b62da66b78625d149d0bab4389229cc0..448e32e38cb9f9282e733e859da2a37484020b57 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h +++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h @@ -1,5 +1,12 @@ -#ifndef __FATORRGCONVERTER_H__ -#define __FATORRGCONVERTER_H__ +/* + * ToGrammarRightRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#ifndef __TO_GRAMMAR_RIGHT_RG_H__ +#define __TO_GRAMMAR_RIGHT_RG_H__ #include <grammar/Regular/RightRG.h> #include <automaton/FSM/NFA.h> @@ -8,18 +15,15 @@ #include <grammar/Grammar.h> #include <automaton/Automaton.h> -namespace conversions -{ +namespace automaton { -namespace fa2rg -{ +namespace convert { /** * Finite automaton to right regular grammar converter. * Source: Melichar 2.104 */ -class FAtoRRGConverter : public automaton::VisitableConstFSMBase -{ +class ToGrammarRightRG : public automaton::VisitableConstFSMBase { public: /** * Performs conversion. @@ -38,11 +42,11 @@ private: void Visit(void*, const automaton::ExtendedNFA& automaton) const; void Visit(void*, const automaton::CompactNFA& automaton) const; - static const FAtoRRGConverter FA_TO_RRG_CONVERTER; + static const ToGrammarRightRG TO_GRAMMAR_RIGHT_RG; }; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* __FATORRGCONVERTER_H__ */ +#endif /* __TO_GRAMMAR_RIGHT_RG_H__ */ diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9335fe353db028e7b743db90870eb6ed37741341 --- /dev/null +++ b/alib2algo/src/automaton/convert/ToRegExp.cpp @@ -0,0 +1,98 @@ +/* + * ToRegExpLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#include "ToRegExp.h" +#include "ToRegExpStateElimination.h" +#include <exception/AlibException.h> + +namespace automaton { + +namespace convert { + +regexp::RegExp ToRegExp::convert(const automaton::Automaton& automaton) { + regexp::RegExp* out = NULL; + automaton.getData().Accept((void*) &out, ToRegExp::TO_REGEXP); + regexp::RegExp res = std::move(*out); + delete out; + return res; +} + +void ToRegExp::Visit(void* data, const automaton::EpsilonNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::NFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::DFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::ExtendedNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::CompactNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void*, const DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void ToRegExp::Visit(void*, const SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void ToRegExp::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void ToRegExp::Visit(void*, const VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void ToRegExp::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void ToRegExp::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void ToRegExp::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void ToRegExp::Visit(void*, const NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void ToRegExp::Visit(void*, const SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void ToRegExp::Visit(void*, const OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const ToRegExp ToRegExp::TO_REGEXP; + +} /* namespace convert */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h new file mode 100644 index 0000000000000000000000000000000000000000..b5251819501291bee36f5e3556a8c1fa074e6dd9 --- /dev/null +++ b/alib2algo/src/automaton/convert/ToRegExp.h @@ -0,0 +1,56 @@ +/* + * ToRegExp.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _AUTOMATON_TO_REGEXP_H__ +#define _AUTOMATON_TO_REGEXP_H__ + +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/EpsilonNFA.h> +#include <regexp/unbounded/UnboundedRegExp.h> + +#include <automaton/Automaton.h> +#include <regexp/RegExp.h> + +namespace automaton { + +namespace convert { + +class ToRegExp : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static regexp::RegExp convert(const automaton::Automaton& automaton); + +private: + void Visit(void*, const EpsilonNFA& automaton) const; + void Visit(void*, const MultiInitialStateNFA& automaton) const; + void Visit(void*, const NFA& automaton) const; + void Visit(void*, const DFA& automaton) const; + void Visit(void*, const ExtendedNFA& automaton) const; + void Visit(void*, const CompactNFA& automaton) const; + void Visit(void*, const DPDA& automaton) const; + void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownDPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; + void Visit(void*, const OneTapeDTM& automaton) const; + + static const ToRegExp TO_REGEXP; +}; + +} /* namespace convert */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_TO_REGEXP_H__ */ diff --git a/alib2algo/src/conversions/fa2re/Algebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp similarity index 79% rename from alib2algo/src/conversions/fa2re/Algebraic.cpp rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp index 959996376c9d64e233fc5fabadd70c5d6df70738..49711c8239066135fb061bad75f5ca1465b2b115 100644 --- a/alib2algo/src/conversions/fa2re/Algebraic.cpp +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp @@ -1,11 +1,11 @@ /* - * Algebraic.cpp + * ToRegExpAlgebraic.cpp * * Created on: 11. 2. 2014 * Author: Tomas Pecka */ -#include "Algebraic.h" +#include "ToRegExpAlgebraic.h" #include <alphabet/Symbol.h> #include <automaton/FSM/DFA.h> @@ -16,20 +16,19 @@ #include "../../equations/RightRegularEquationSolver.h" -namespace conversions -{ +namespace automaton { -namespace fa2re { +namespace convert { -regexp::RegExp Algebraic::convert(const automaton::Automaton& automaton) { +regexp::RegExp ToRegExpAlgebraic::convert(const automaton::Automaton& automaton) { regexp::RegExp* out = NULL; - automaton.getData().Accept((void*) &out, Algebraic::ALGEBRAIC); + automaton.getData().Accept((void*) &out, ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC); regexp::RegExp res = std::move(*out); delete out; return res; } -regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) { +regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::EpsilonNFA & automaton ) { equations::RightRegularEquationSolver solver; // initialize equations @@ -56,7 +55,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) ); } -regexp::UnboundedRegExp Algebraic::convert( const automaton::MultiInitialStateNFA & automaton ) { +regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitialStateNFA & automaton ) { equations::RightRegularEquationSolver solver; // initialize equations @@ -85,7 +84,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::MultiInitialStateNF return regexp::UnboundedRegExp { alternation }; } -regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) { +regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA & automaton ) { equations::RightRegularEquationSolver solver; // initialize equations @@ -106,7 +105,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) { return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) ); } -regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { +regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA & automaton ) { equations::RightRegularEquationSolver solver; // initialize equations @@ -126,36 +125,36 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { } -void Algebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const { +void ToRegExpAlgebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(this->convert(automaton)); } -void Algebraic::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { +void ToRegExpAlgebraic::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(this->convert(automaton)); } -void Algebraic::Visit(void* data, const automaton::NFA& automaton) const { +void ToRegExpAlgebraic::Visit(void* data, const automaton::NFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(this->convert(automaton)); } -void Algebraic::Visit(void* data, const automaton::DFA& automaton) const { +void ToRegExpAlgebraic::Visit(void* data, const automaton::DFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(this->convert(automaton)); } -void Algebraic::Visit(void*, const automaton::ExtendedNFA& ) const { +void ToRegExpAlgebraic::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void Algebraic::Visit(void*, const automaton::CompactNFA& ) const { +void ToRegExpAlgebraic::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const Algebraic Algebraic::ALGEBRAIC; +const ToRegExpAlgebraic ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC; -} /* namespace fa2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/conversions/fa2re/Algebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h similarity index 78% rename from alib2algo/src/conversions/fa2re/Algebraic.h rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.h index a03bc8a78775eaddc5da14f9a8176a9c2f4c46ad..54d1f89f7bf7c424d2b0d1033c7dc49c4b6b408b 100644 --- a/alib2algo/src/conversions/fa2re/Algebraic.h +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h @@ -1,12 +1,12 @@ /* - * Algebraic.h + * ToRegExpAlgebraic.h * * Created on: 11. 2. 2014 * Author: Tomas Pecka */ -#ifndef FA2RE_ALGEBRAIC_H_ -#define FA2RE_ALGEBRAIC_H_ +#ifndef AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_ +#define AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_ #include <deque> #include <map> @@ -16,11 +16,9 @@ #include <regexp/unbounded/UnboundedRegExpElements.h> #include <automaton/Automaton.h> -namespace conversions -{ +namespace automaton { -namespace fa2re -{ +namespace convert { // http://cs.stackexchange.com/questions/2016/how-to-convert-finite-automata-to-regular-expressions // https://github.com/ferno/greenery/blob/bcc0a136335edbe94cd7725fc6e8cce0268d850c/fsm.py @@ -29,8 +27,7 @@ namespace fa2re * Converts FA to RE using Brzozowski's algebraic method using right regular equations. * Source : Melichar 2.122 */ -class Algebraic : public automaton::VisitableConstFSMBase -{ +class ToRegExpAlgebraic : public automaton::VisitableConstFSMBase { public: /** * Performs conversion. @@ -51,11 +48,11 @@ private: void Visit(void*, const automaton::ExtendedNFA&) const; void Visit(void*, const automaton::CompactNFA&) const; - static const Algebraic ALGEBRAIC; + static const ToRegExpAlgebraic TO_REG_EXP_ALGEBRAIC; }; -} /* namespace fa2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* FA2RE_ALGEBRAIC_H_ */ +#endif /* AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_ */ diff --git a/alib2algo/src/conversions/fa2re/StateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp similarity index 69% rename from alib2algo/src/conversions/fa2re/StateElimination.cpp rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp index 1c22f40119392b4cf26a2b8ad967676b4ed3d023..88bdb12a9beb6e42701ec060efaa225a08757542 100644 --- a/alib2algo/src/conversions/fa2re/StateElimination.cpp +++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp @@ -1,37 +1,35 @@ /* - * StateEliminationUnbounded.cpp + * ToRegExpStateElimination.cpp * * Created on: 9. 2. 2014 * Author: Tomas Pecka */ -#include "StateElimination.h" +#include "ToRegExpStateElimination.h" #include <regexp/unbounded/UnboundedRegExp.h> #include <exception/AlibException.h> -#include "../../regexp/RegExpOptimize.h" -#include "../../regexp/RegExpAlternate.h" -#include "../../regexp/RegExpConcatenate.h" -#include "../../regexp/RegExpIterate.h" +#include "../../regexp/simplify/RegExpOptimize.h" +#include "../../regexp/transform/RegExpAlternate.h" +#include "../../regexp/transform/RegExpConcatenate.h" +#include "../../regexp/transform/RegExpIterate.h" -namespace conversions -{ +namespace automaton { -namespace fa2re -{ +namespace convert { -regexp::RegExp StateElimination::convert(const automaton::Automaton& automaton) +regexp::RegExp ToRegExpStateElimination::convert(const automaton::Automaton& automaton) { regexp::RegExp* out = NULL; - automaton.getData().Accept((void*) &out, StateElimination::STATE_ELIMINATION); + automaton.getData().Accept((void*) &out, ToRegExpStateElimination::TO_REG_EXP_STATE_ELIMINATION); regexp::RegExp res = std::move(*out); delete out; return res; } template<class T> -regexp::RegExp StateElimination::convert(const T& automaton) +regexp::RegExp ToRegExpStateElimination::convert(const T& automaton) { if(automaton.getFinalStates().size() == 0) return regexp::RegExp(regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty())); @@ -50,15 +48,13 @@ regexp::RegExp StateElimination::convert(const T& automaton) extendedAutomaton = eliminateState(extendedAutomaton, state); // step 4 - regexp::RegExpOptimize opt; - - return regexp::RegExpOptimize::optimize(regexp::RegExpConcatenate::concatenate( + return regexp::simplify::RegExpOptimize::optimize(regexp::RegExpConcatenate::concatenate( transition(extendedAutomaton, extendedAutomaton.getInitialState(), *extendedAutomaton.getFinalStates().begin()), regexp::RegExpIterate::iterate(transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin())))); } -automaton::ExtendedNFA StateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& q) +automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& q) { automaton::ExtendedNFA newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA) newAutomaton.setStates(extendedAutomaton.getStates()); @@ -66,8 +62,6 @@ automaton::ExtendedNFA StateElimination::eliminateState(const automaton::Extende newAutomaton.setInputSymbols(extendedAutomaton.getInputAlphabet()); newAutomaton.setFinalStates(extendedAutomaton.getFinalStates()); - regexp::RegExpOptimize opt; - for(const auto& p: newAutomaton.getStates()) { for(const auto& r : newAutomaton.getStates()) @@ -78,26 +72,25 @@ automaton::ExtendedNFA StateElimination::eliminateState(const automaton::Extende regexp::RegExp alt = regexp::RegExpAlternate::alternate(concat, transition(extendedAutomaton, p, r)); - newAutomaton.addTransition(p, regexp::RegExpOptimize::optimize(alt), r); + newAutomaton.addTransition(p, regexp::simplify::RegExpOptimize::optimize(alt), r); } } return newAutomaton; } -const regexp::RegExp StateElimination::transition(const automaton::ExtendedNFA& automaton, const automaton::State& from, const automaton::State& to) +const regexp::RegExp ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const automaton::State& from, const automaton::State& to) { - regexp::RegExpOptimize opt; regexp::RegExp ret(regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty { })); for(const auto& transition: automaton.getTransitionsFromState(from)) if(transition.second.count(to) > 0) ret = regexp::RegExpAlternate::alternate(ret, transition.first.second); - return regexp::RegExpOptimize::optimize(ret); + return regexp::simplify::RegExpOptimize::optimize(ret); } -void StateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) +void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) { const automaton::State& initState = automaton.getInitialState(); if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 ) @@ -131,44 +124,44 @@ void StateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) } } -void StateElimination::Visit(void* data, const automaton::EpsilonNFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::EpsilonNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -void StateElimination::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -void StateElimination::Visit(void* data, const automaton::NFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::NFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -void StateElimination::Visit(void* data, const automaton::DFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::DFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -void StateElimination::Visit(void* data, const automaton::ExtendedNFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::ExtendedNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -void StateElimination::Visit(void* data, const automaton::CompactNFA& automaton) const +void ToRegExpStateElimination::Visit(void* data, const automaton::CompactNFA& automaton) const { regexp::RegExp* & out = *((regexp::RegExp**) data); out = new regexp::RegExp(convert(automaton)); } -const StateElimination StateElimination::STATE_ELIMINATION; +const ToRegExpStateElimination ToRegExpStateElimination::TO_REG_EXP_STATE_ELIMINATION; -} /* namespace fa2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/conversions/fa2re/StateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h similarity index 79% rename from alib2algo/src/conversions/fa2re/StateElimination.h rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.h index ab54785825b8d9aaefa96fb8cceab9030eacb7cb..a70f35786f360798690a08044790f78f12cbb04a 100644 --- a/alib2algo/src/conversions/fa2re/StateElimination.h +++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h @@ -1,12 +1,12 @@ /* - * StateElimination.h + * ToRegExpStateElimination.h * * Created on: 9. 2. 2014 * Author: Tomas Pecka */ -#ifndef STATEELIMINATION_H_ -#define STATEELIMINATION_H_ +#ifndef TO_REG_EXP_STATE_ELIMINATION_H_ +#define TO_REG_EXP_STATE_ELIMINATION_H_ #include <regexp/RegExp.h> #include <regexp/unbounded/UnboundedRegExpElements.h> @@ -18,18 +18,15 @@ #include <automaton/FSM/EpsilonNFA.h> #include <automaton/FSM/ExtendedNFA.h> -namespace conversions -{ +namespace automaton { -namespace fa2re -{ +namespace convert { /** * Converts FSM to RE using State Elimination algorithm. * Source: Melichar 2.118 */ -class StateElimination : public automaton::VisitableConstFSMBase -{ +class ToRegExpStateElimination : public automaton::VisitableConstFSMBase { public: /** * Performs conversion. @@ -55,11 +52,11 @@ private: static automaton::ExtendedNFA eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& state); - static const StateElimination STATE_ELIMINATION; + static const ToRegExpStateElimination TO_REG_EXP_STATE_ELIMINATION; }; -} /* namespace fa2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* STATEELIMINATION_H_ */ +#endif /* TO_REG_EXP_STATE_ELIMINATION_H_ */ diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a9357d29f87e0189d2164e713d9e176648edc8b --- /dev/null +++ b/alib2algo/src/automaton/determinize/Determinize.cpp @@ -0,0 +1,101 @@ +/* + * Determinize.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Vesely + */ + +#include "Determinize.h" + +namespace automaton { + +namespace determinize { + +automaton::Automaton Determinize::determinize(const automaton::Automaton& automaton) { + automaton::Automaton* out = NULL; + automaton.getData().Accept((void*) &out, Determinize::DETERMINIZE); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +void Determinize::Visit(void*, const automaton::EpsilonNFA&) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void Determinize::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void* data, const automaton::NFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void*, const automaton::DFA&) const { + throw exception::AlibException("Unsupported automaton type DFA"); +} + +void Determinize::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void Determinize::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void Determinize::Visit(void*, const automaton::DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void Determinize::Visit(void*, const automaton::SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void Determinize::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void Determinize::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void Determinize::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void*, const automaton::NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void Determinize::Visit(void*, const automaton::SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void Determinize::Visit(void*, const automaton::OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const Determinize Determinize::DETERMINIZE; + +} /* namespace determinize */ + +} /* namespace automaton */ + +#include "DeterminizeNFAPart.cxx" +#include "DeterminizeIDPDAPart.cxx" +#include "DeterminizeVPAPart.cxx" +#include "DeterminizeRHDPDAPart.cxx" + diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.h b/alib2algo/src/automaton/determinize/Determinize.h similarity index 73% rename from alib2algo/src/determinize/nfa/NFADeterminizer.h rename to alib2algo/src/automaton/determinize/Determinize.h index 87f05f9b3725d594427c5dc3ee6edc1a6424aed7..2fc78ff1e37ac55c8529d0b28d9f485804398392 100644 --- a/alib2algo/src/determinize/nfa/NFADeterminizer.h +++ b/alib2algo/src/automaton/determinize/Determinize.h @@ -5,25 +5,28 @@ * Author: Jan Vesely */ -#ifndef NFA_DETERMINIZER_H_ -#define NFA_DETERMINIZER_H_ +#ifndef DETERMINIZE_H_ +#define DETERMINIZE_H_ #include <set> #include <automaton/common/State.h> #include <automaton/Automaton.h> -#include <automaton/FSM/NFA.h> -#include <automaton/FSM/MultiInitialStateNFA.h> #include <automaton/FSM/DFA.h> +#include <automaton/PDA/DPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> #include <exception/AlibException.h> +namespace automaton { + namespace determinize { /** * Class for running determinization algorithm on fsm. */ -class NFADeterminizer : public automaton::VisitableAutomatonBase::const_visitor_type { +class Determinize : public automaton::VisitableAutomatonBase::const_visitor_type { private: void Visit(void*, const automaton::EpsilonNFA& automaton) const; void Visit(void*, const automaton::MultiInitialStateNFA& automaton) const; @@ -42,7 +45,7 @@ private: void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; - static const NFADeterminizer NFA_DETERMINIZER; + static const Determinize DETERMINIZE; public: @@ -55,8 +58,13 @@ public: static automaton::DFA determinize(const automaton::NFA& nfa); static automaton::DFA determinize(const automaton::MultiInitialStateNFA& nfa); + static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic); + static automaton::DPDA determinize(const automaton::InputDrivenNPDA& nfa); + static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic); }; } /* namespace determinize */ -#endif /* NFA_DETERMINIZER_H_ */ +} /* namespace automaton */ + +#endif /* DETERMINIZE_H_ */ diff --git a/alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx similarity index 87% rename from alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp rename to alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx index 36cd28c3029c6efc3d8550ac853b3f62a01885f6..1f85414a8d3e65b9d2feb088eff4acb16689c277 100644 --- a/alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp +++ b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx @@ -5,16 +5,17 @@ * Author: Jan Vesely */ -#include "IDPDADeterminizer.h" -#include "../common/NFACommon.h" +#include "common/NFACommon.h" +#include <automaton/PDA/InputDrivenNPDA.h> #include <deque> #include <algorithm> -namespace determinize { +namespace automaton { +namespace determinize { -automaton::DPDA IDPDADeterminizer::determinize(const automaton::InputDrivenNPDA& nfa) { +automaton::DPDA Determinize::determinize(const automaton::InputDrivenNPDA& nfa) { // 1, 4 automaton::State initialState(createDFAState(nfa.getInitialStates())); automaton::DPDA res(initialState, nfa.getInitialSymbol()); @@ -63,4 +64,6 @@ automaton::DPDA IDPDADeterminizer::determinize(const automaton::InputDrivenNPDA& return res; } -} +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e156c3c8f16f54055897c6fbb1618e0691e9e5d6 --- /dev/null +++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx @@ -0,0 +1,115 @@ +/* + * NFADeterminizer.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Vesely + */ + +#include "common/NFACommon.h" + +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/MultiInitialStateNFA.h> +#include <deque> +#include <algorithm> + +namespace automaton { + +namespace determinize { + +automaton::DFA Determinize::determinize(const automaton::MultiInitialStateNFA& nfa) { + // 1, 4 + automaton::State initialState(createDFAState(nfa.getInitialStates())); + automaton::DFA res(initialState); + res.setInputSymbols(nfa.getInputAlphabet()); + + // 2 + std::deque<automaton::State> todo; + todo.push_back(initialState); + + do { + // 3a, c + automaton::State state = todo.front(); + todo.pop_front(); + + // 3b + for (const auto& input : nfa.getInputAlphabet()) { + std::set<automaton::State> targetNFAStates; + for(const auto& nfaState : recreateNFAStates(state)) { + auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input)); + if(iter != nfa.getTransitions().end()) { + targetNFAStates.insert(iter->second.begin(), iter->second.end()); + } + } + automaton::State dfaState = createDFAState(targetNFAStates); + + // 4 + bool existed = !res.addState(dfaState); + + // 3b + res.addTransition(state, input, dfaState); + + if(!existed) todo.push_back(dfaState); + } + } while(!todo.empty()); + + // 5 + for (const auto& dfaState : res.getStates()) { + std::set<automaton::State> nfaStates = recreateNFAStates(dfaState); + if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) { + res.addFinalState(dfaState); + } + } + + return res; +} + +automaton::DFA Determinize::determinize(const automaton::NFA& nfa) { + // 1, 4 + automaton::State initialState(createDFAState({nfa.getInitialState()})); + automaton::DFA res(initialState); + res.setInputSymbols(nfa.getInputAlphabet()); + + // 2 + std::deque<automaton::State> todo; + todo.push_back(initialState); + + do { + // 3a, c + automaton::State state = todo.front(); + todo.pop_front(); + + // 3b + for (const auto& input : nfa.getInputAlphabet()) { + std::set<automaton::State> targetNFAStates; + for(const auto& nfaState : recreateNFAStates(state)) { + auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input)); + if(iter != nfa.getTransitions().end()) { + targetNFAStates.insert(iter->second.begin(), iter->second.end()); + } + } + automaton::State dfaState = createDFAState(targetNFAStates); + + // 4 + bool existed = !res.addState(dfaState); + + // 3b + res.addTransition(state, input, dfaState); + + if(!existed) todo.push_back(dfaState); + } + } while(!todo.empty()); + + // 5 + for (const auto& dfaState : res.getStates()) { + std::set<automaton::State> nfaStates = recreateNFAStates(dfaState); + if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) { + res.addFinalState(dfaState); + } + } + + return res; +} + +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx similarity index 96% rename from alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp rename to alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx index 9c01e6c99210bdf890807acd1edeeb33804aa5d3..321b6e544020df05bd4410ac69688ce5022e573b 100644 --- a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp +++ b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx @@ -1,6 +1,13 @@ -#include "HDPDADeterminizer.h" -#include "../common/RHDPDACommon.h" +/* + * NFADeterminizer.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Travnicek + */ +#include "common/RHDPDACommon.h" + +#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> #include "automaton/common/State.h" #include "alphabet/Symbol.h" #include "alphabet/LabeledSymbol.h" @@ -9,6 +16,8 @@ #include <std/set.hpp> #include <iostream> +namespace automaton { + namespace determinize { void addRetTransition(const automaton::State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& dvpdaSymbol, const automaton::State& to, automaton::RealTimeHeightDeterministicDPDA& deterministic) { @@ -185,7 +194,7 @@ std::tuple<std::set<std::variant<string::Epsilon, alphabet::Symbol>>, std::set<s return std::make_tuple(local, call, ret); } -automaton::RealTimeHeightDeterministicDPDA HDPDADeterminizer::determinize(const automaton::RealTimeHeightDeterministicNPDA& n) { +automaton::RealTimeHeightDeterministicDPDA Determinize::determinize(const automaton::RealTimeHeightDeterministicNPDA& n) { label::Label initialLabel = packToStateLabel(createIdentity(retrieveLabels(n.getInitialStates()))); automaton::RealTimeHeightDeterministicDPDA d(automaton::State(initialLabel), n.getBottomOfTheStackSymbol()); @@ -239,4 +248,6 @@ automaton::RealTimeHeightDeterministicDPDA HDPDADeterminizer::determinize(const return d; } -} +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx similarity index 95% rename from alib2algo/src/determinize/vpa/VPADeterminizer.cpp rename to alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx index 136cf49c2c8a96427fbc5dd6be3b9bde7a2ef656..1a1e7ebca54a3fa1db5e6d6063d2a6d1bedcf4fc 100644 --- a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp +++ b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx @@ -1,6 +1,13 @@ -#include "VPADeterminizer.h" -#include "../common/RHDPDACommon.h" +/* + * NFADeterminizer.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Travnicek + */ +#include "common/RHDPDACommon.h" + +#include <automaton/PDA/VisiblyPushdownNPDA.h> #include "automaton/common/State.h" #include "alphabet/Symbol.h" #include "alphabet/LabeledSymbol.h" @@ -8,6 +15,8 @@ #include <std/set.hpp> #include <iostream> +namespace automaton { + namespace determinize { void addRetTransition(const automaton::State& from, const alphabet::Symbol& input, const alphabet::Symbol& dvpdaSymbol, const automaton::State& to, automaton::VisiblyPushdownDPDA& deterministic) { @@ -150,7 +159,7 @@ void local(const automaton::State& state, const alphabet::Symbol& input, const a addLocalTransition(state, input, automaton::State(packToStateLabel(std::move(S1))), deterministic); } -automaton::VisiblyPushdownDPDA VPADeterminizer::determinize(const automaton::VisiblyPushdownNPDA& n) { +automaton::VisiblyPushdownDPDA Determinize::determinize(const automaton::VisiblyPushdownNPDA& n) { label::Label initialLabel = packToStateLabel(createIdentity(retrieveLabels(n.getInitialStates()))); automaton::VisiblyPushdownDPDA d(automaton::State(initialLabel), n.getBottomOfTheStackSymbol()); @@ -194,4 +203,6 @@ automaton::VisiblyPushdownDPDA VPADeterminizer::determinize(const automaton::Vis return d; } -} +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/determinize/common/NFACommon.cpp b/alib2algo/src/automaton/determinize/common/NFACommon.cpp similarity index 90% rename from alib2algo/src/determinize/common/NFACommon.cpp rename to alib2algo/src/automaton/determinize/common/NFACommon.cpp index 7a99e583251737d89f36aae9e055611135f8c11b..f86c2eff6754a6ed1b2937b764853746135955a3 100644 --- a/alib2algo/src/determinize/common/NFACommon.cpp +++ b/alib2algo/src/automaton/determinize/common/NFACommon.cpp @@ -11,6 +11,8 @@ #include <deque> #include <algorithm> +namespace automaton { + namespace determinize { automaton::State createDFAState(const std::set<automaton::State>& nfaStates) { @@ -29,4 +31,6 @@ std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState) { return states; } -} +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/determinize/common/NFACommon.h b/alib2algo/src/automaton/determinize/common/NFACommon.h similarity index 95% rename from alib2algo/src/determinize/common/NFACommon.h rename to alib2algo/src/automaton/determinize/common/NFACommon.h index d68e98f97911e6900768468fe6a5d82445f786fd..2265efdf84cab10999f5441fdeba3781d5a471db 100644 --- a/alib2algo/src/determinize/common/NFACommon.h +++ b/alib2algo/src/automaton/determinize/common/NFACommon.h @@ -11,6 +11,8 @@ #include <automaton/common/State.h> #include <set> +namespace automaton { + namespace determinize { /** @@ -34,4 +36,6 @@ std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState); } /* namespace determinize */ +} /* namespace automaton */ + #endif /* NFA_COMMON_H_ */ diff --git a/alib2algo/src/determinize/common/RHDPDACommon.cpp b/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp similarity index 99% rename from alib2algo/src/determinize/common/RHDPDACommon.cpp rename to alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp index d309b75f55b89f66a83bba54d682f11ae41f90c9..e8c29d07032e22f5e19aa6411c25b4ca85ed7e3b 100644 --- a/alib2algo/src/determinize/common/RHDPDACommon.cpp +++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp @@ -10,6 +10,8 @@ #include "automaton/PDA/RealTimeHeightDeterministicDPDA.h" #include "automaton/PDA/RealTimeHeightDeterministicNPDA.h" +namespace automaton { + namespace determinize { label::Label packToStateLabel(std::set<std::pair<label::Label, label::Label>>&& data) { @@ -221,4 +223,6 @@ std::set<label::Label> retrieveLabels(const std::set<automaton::State>& states) return labels; } +} /* namespace automaton */ + } /* namespace determinize */ diff --git a/alib2algo/src/determinize/common/RHDPDACommon.h b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h similarity index 97% rename from alib2algo/src/determinize/common/RHDPDACommon.h rename to alib2algo/src/automaton/determinize/common/RHDPDACommon.h index 26fff9071ec8806e4ad8340cb4b3abbdfac6fb3e..787037bd81b438b6fb3f7557db9d8404b482c95e 100644 --- a/alib2algo/src/determinize/common/RHDPDACommon.h +++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h @@ -9,6 +9,8 @@ #include <set> #include <map> +namespace automaton { + namespace determinize { label::Label packToStateLabel(std::set<std::pair<label::Label, label::Label>>&& data); @@ -40,4 +42,6 @@ std::set<label::Label> retrieveLabels(const std::set<automaton::State>& states); } /* namespace determinize */ +} /* namespace automaton */ + #endif /* RHDPDA_VPA_COMMON_H_ */ diff --git a/alib2algo/src/generator/RandomAutomatonFactory.cpp b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp similarity index 97% rename from alib2algo/src/generator/RandomAutomatonFactory.cpp rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp index 3bed804ba9ce1cdbb3b91a41367baf1b0d24a656..6aacce65f39fc38f350fe42da960413777057e1e 100644 --- a/alib2algo/src/generator/RandomAutomatonFactory.cpp +++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp @@ -10,7 +10,9 @@ #include <algorithm> -namespace generator { +namespace automaton { + +namespace generate { automaton::NFA RandomAutomatonFactory::generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density ) { std::deque<alphabet::Symbol> alphabet2; @@ -150,4 +152,6 @@ automaton::NFA RandomAutomatonFactory::LeslieConnectedNFA( size_t n, const std:: return automaton; } -} +} /* namespace generate */ + +} /* namespace automaton */ diff --git a/alib2algo/src/generator/RandomAutomatonFactory.h b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h similarity index 87% rename from alib2algo/src/generator/RandomAutomatonFactory.h rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.h index 3501e45b780c4fb39ddd2e26ce1d6220c50f8678..0f2881e34ac187fd9d26f16969dd93e2a6789d46 100644 --- a/alib2algo/src/generator/RandomAutomatonFactory.h +++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h @@ -14,7 +14,9 @@ #include <exception/AlibException.h> #include <automaton/FSM/NFA.h> -namespace generator { +namespace automaton { + +namespace generate { class RandomAutomatonFactory { public: @@ -25,6 +27,8 @@ private: static automaton::NFA LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density ); }; -} +} /* namespace generate */ + +} /* namespace automaton */ #endif /* RANDOM_AUTOMATON_FACTORY_H_ */ diff --git a/alib2algo/src/automaton/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp similarity index 96% rename from alib2algo/src/automaton/EpsilonClosure.cpp rename to alib2algo/src/automaton/properties/EpsilonClosure.cpp index 854df6f1c01af8008f155095ac3c1cef0e2cd6ee..b91b08d470cf3b64a12d9acc6b2334f9a435ef98 100644 --- a/alib2algo/src/automaton/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp @@ -19,10 +19,12 @@ #include <map> #include <queue> -#include "../regexp/RegExpEpsilon.h" +#include "../../regexp/properties/RegExpEpsilon.h" namespace automaton { +namespace properties { + std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::EpsilonNFA & fsm, const automaton::State & q ) { if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton"); @@ -94,7 +96,7 @@ std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::Exte closure.insert( p ); for( const auto & transition : fsm.getTransitions( ) ) - if( transition.first.first == p && regexp::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) ) + if( transition.first.first == p && regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) ) for (const auto & to : transition.second ) if( visited [ to ] == false ) queue.push( to ); @@ -209,5 +211,7 @@ void EpsilonClosure::Visit(void*, const OneTapeDTM&) const { const EpsilonClosure EpsilonClosure::EPSILON_CLOSURE; -} +} /* namespace properties */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h similarity index 96% rename from alib2algo/src/automaton/EpsilonClosure.h rename to alib2algo/src/automaton/properties/EpsilonClosure.h index 2d98d57a6b7389067ec88c7fb1c0b632779033c3..eb768f772a770a47cb9a4547c72255c476ae121c 100644 --- a/alib2algo/src/automaton/EpsilonClosure.h +++ b/alib2algo/src/automaton/properties/EpsilonClosure.h @@ -17,6 +17,8 @@ namespace automaton { +namespace properties { + class EpsilonClosure : public VisitableAutomatonBase::const_visitor_type { public: static std::set<automaton::State> epsilonClosure( const automaton::Automaton & automaton, const automaton::State & state ); @@ -52,6 +54,8 @@ private: static const EpsilonClosure EPSILON_CLOSURE; }; -} +} /* namespace properties */ + +} /* namespace automaton */ #endif /* EPSILON_CLOSURE_H_ */ diff --git a/alib2algo/src/automaton/UnreachableStates.cpp b/alib2algo/src/automaton/properties/UnreachableStates.cpp similarity index 98% rename from alib2algo/src/automaton/UnreachableStates.cpp rename to alib2algo/src/automaton/properties/UnreachableStates.cpp index 9e868c8fcd624b0e5ee543779fa56738ddd922c2..fd730f3edc02d1a39921aa28d7dbad8737db6012 100644 --- a/alib2algo/src/automaton/UnreachableStates.cpp +++ b/alib2algo/src/automaton/properties/UnreachableStates.cpp @@ -20,6 +20,8 @@ namespace automaton { +namespace properties { + std::set<automaton::State> UnreachableStates::unreachableStates(const Automaton& automaton) { std::set<automaton::State> out; automaton.getData().Accept((void*) &out, UnreachableStates::UNREACHABLE_STATES); @@ -181,5 +183,7 @@ void UnreachableStates::Visit(void*, const OneTapeDTM&) const { const UnreachableStates UnreachableStates::UNREACHABLE_STATES; -} +} /* namespace properties */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/UnreachableStates.h b/alib2algo/src/automaton/properties/UnreachableStates.h similarity index 95% rename from alib2algo/src/automaton/UnreachableStates.h rename to alib2algo/src/automaton/properties/UnreachableStates.h index e18f17aa9d6343a255cc82cbc0a98e54d7264aa4..d50644c4b792f54b71d30572f0cfb82dceb1cdd6 100644 --- a/alib2algo/src/automaton/UnreachableStates.h +++ b/alib2algo/src/automaton/properties/UnreachableStates.h @@ -17,6 +17,8 @@ namespace automaton { +namespace properties { + class UnreachableStates : public VisitableAutomatonBase::const_visitor_type { public: static std::set<automaton::State> unreachableStates( const automaton::Automaton & automaton ); @@ -48,6 +50,8 @@ private: static const UnreachableStates UNREACHABLE_STATES; }; -} +} /* namespace properties */ + +} /* namespace automaton */ #endif /* UNREACHABLE_STATES_H_ */ diff --git a/alib2algo/src/automaton/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp similarity index 98% rename from alib2algo/src/automaton/UsefullStates.cpp rename to alib2algo/src/automaton/properties/UsefullStates.cpp index 68e4837dcad9afc9d4d67a98132ce0a9b076f7c9..83a53781ae67b769a84e42fa7b9b14bc8c294994 100644 --- a/alib2algo/src/automaton/UsefullStates.cpp +++ b/alib2algo/src/automaton/properties/UsefullStates.cpp @@ -20,6 +20,8 @@ namespace automaton { +namespace properties { + std::set<automaton::State> UsefullStates::usefullStates(const Automaton& automaton) { std::set<automaton::State> out; automaton.getData().Accept((void*) &out, UsefullStates::USEFULL_STATES); @@ -151,5 +153,7 @@ void UsefullStates::Visit(void*, const OneTapeDTM&) const { const UsefullStates UsefullStates::USEFULL_STATES; -} +} /* namespace properties */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/UsefullStates.h b/alib2algo/src/automaton/properties/UsefullStates.h similarity index 95% rename from alib2algo/src/automaton/UsefullStates.h rename to alib2algo/src/automaton/properties/UsefullStates.h index db9a641cb2ca1c0ec1f886d0a1d21570b5597bfa..81a11580298976eeaa14056bce2b453a1dfa1fba 100644 --- a/alib2algo/src/automaton/UsefullStates.h +++ b/alib2algo/src/automaton/properties/UsefullStates.h @@ -17,6 +17,8 @@ namespace automaton { +namespace properties { + class UsefullStates : public VisitableAutomatonBase::const_visitor_type { public: static std::set<automaton::State> usefullStates( const automaton::Automaton & automaton ); @@ -48,6 +50,8 @@ private: static const UsefullStates USEFULL_STATES; }; -} +} /* namespace properties */ + +} /* namespace automaton */ #endif /* USEFULL_STATES_H_ */ diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/automaton/simplify/EpsilonRemover.cpp similarity index 56% rename from alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp rename to alib2algo/src/automaton/simplify/EpsilonRemover.cpp index 76153a08d7f6daf613676991d7074af7a9dce821..7435740493845871c3028ad4c788b368305d52ed 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp +++ b/alib2algo/src/automaton/simplify/EpsilonRemover.cpp @@ -1,32 +1,34 @@ /* - * FSMEpsilonRemover.cpp + * EpsilonRemover.cpp * * Created on: 16. 1. 2014 * Author: Tomas Pecka */ -#include "FSMEpsilonRemover.h" +#include "EpsilonRemover.h" -#include "../../automaton/EpsilonClosure.h" +#include "../properties/EpsilonClosure.h" -namespace epsilon { +namespace automaton { -automaton::DFA FSMEpsilonRemover::remove(const automaton::DFA& origFSM) +namespace simplify { + +automaton::DFA EpsilonRemover::remove(const automaton::DFA& origFSM) { return origFSM; } -automaton::MultiInitialStateNFA FSMEpsilonRemover::remove(const automaton::MultiInitialStateNFA& origFSM) +automaton::MultiInitialStateNFA EpsilonRemover::remove(const automaton::MultiInitialStateNFA& origFSM) { return origFSM; } -automaton::NFA FSMEpsilonRemover::remove(const automaton::NFA& origFSM) +automaton::NFA EpsilonRemover::remove(const automaton::NFA& origFSM) { return origFSM; } -automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { +automaton::NFA EpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { automaton::NFA fsm(origFSM.getInitialState()); for( const auto & state : origFSM.getStates() ) @@ -39,7 +41,7 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM * Step 1 from Melichar 2.41 */ for( const auto & from : origFSM.getStates( ) ) - for( const auto & fromClosure : automaton::EpsilonClosure::epsilonClosure( origFSM, from ) ) + for( const auto & fromClosure : automaton::properties::EpsilonClosure::epsilonClosure( origFSM, from ) ) for( const auto & transition : origFSM.getTransitions( ) ) if (transition.first.first == fromClosure && transition.first.second.is<alphabet::Symbol>()) for( const auto & to : transition.second ) @@ -52,7 +54,7 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM for( const auto & q : fsm.getStates( ) ) { - const std::set<automaton::State> & cl = automaton::EpsilonClosure::epsilonClosure( origFSM, q ); + const std::set<automaton::State> & cl = automaton::properties::EpsilonClosure::epsilonClosure( origFSM, q ); const std::set<automaton::State> & F = origFSM.getFinalStates( ); std::set<automaton::State> intersect; @@ -67,82 +69,84 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM return fsm; } -automaton::Automaton FSMEpsilonRemover::remove(const automaton::Automaton& automaton) { +automaton::Automaton EpsilonRemover::remove(const automaton::Automaton& automaton) { automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, FSMEpsilonRemover::FSM_EPSILON_REMOVER); + automaton.getData().Accept((void*) &out, EpsilonRemover::EPSILON_REMOVER); automaton::Automaton res = std::move(*out); delete out; return res; } -void FSMEpsilonRemover::Visit(void* data, const automaton::EpsilonNFA& automaton) const { +void EpsilonRemover::Visit(void* data, const automaton::EpsilonNFA& automaton) const { automaton::Automaton* & out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->remove(automaton)); } -void FSMEpsilonRemover::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { +void EpsilonRemover::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { automaton::Automaton* & out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->remove(automaton)); } -void FSMEpsilonRemover::Visit(void* data, const automaton::NFA& automaton) const { +void EpsilonRemover::Visit(void* data, const automaton::NFA& automaton) const { automaton::Automaton* & out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->remove(automaton)); } -void FSMEpsilonRemover::Visit(void* data, const automaton::DFA& automaton) const { +void EpsilonRemover::Visit(void* data, const automaton::DFA& automaton) const { automaton::Automaton* & out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->remove(automaton)); } -void FSMEpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const { +void EpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const { +void EpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::DPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::InputDrivenNPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::InputDrivenNPDA&) const { throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::NPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const { +void EpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); } -void FSMEpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const { +void EpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } -const FSMEpsilonRemover FSMEpsilonRemover::FSM_EPSILON_REMOVER; +const EpsilonRemover EpsilonRemover::EPSILON_REMOVER; + +} /* namespace simplify */ -} /* namespace epsilon */ +} /* namespace automaton */ diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h b/alib2algo/src/automaton/simplify/EpsilonRemover.h similarity index 84% rename from alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h rename to alib2algo/src/automaton/simplify/EpsilonRemover.h index 380deb2c814487e2476088e71d774aed3fdec8cd..38aa69f2e356ef0011ae618a8ffaa621a250b325 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h +++ b/alib2algo/src/automaton/simplify/EpsilonRemover.h @@ -1,12 +1,12 @@ /* - * FSMEpsilonRemover.h + * EpsilonRemover.h * * Created on: 16. 1. 2014 * Author: Tomas Pecka */ -#ifndef FMS_EPSILON_REMOVER_H_ -#define FMS_EPSILON_REMOVER_H_ +#ifndef EPSILON_REMOVER_H_ +#define EPSILON_REMOVER_H_ #include <map> #include <algorithm> @@ -19,9 +19,11 @@ #include <automaton/FSM/DFA.h> #include <exception/AlibException.h> -namespace epsilon { +namespace automaton { -class FSMEpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type { +namespace simplify { + +class EpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type { public: static automaton::Automaton remove( const automaton::Automaton & automaton ); @@ -51,9 +53,11 @@ private: void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; - static const FSMEpsilonRemover FSM_EPSILON_REMOVER; + static const EpsilonRemover EPSILON_REMOVER; }; -} /* namespace epsilon */ +} /* namespace simplify */ + +} /* namespace automaton */ -#endif /* FMS_EPSILON_REMOVER_H_ */ +#endif /* EPSILON_REMOVER_H_ */ diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp similarity index 82% rename from alib2algo/src/minimize/dfa/MinimizeDFA.cpp rename to alib2algo/src/automaton/simplify/Minimize.cpp index 4f60e53c71c74fafd0b9a1fe8d323e21b0bd0d17..548354a3d65b95256027b3cf0e37ed4ba0e8d084 100644 --- a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp +++ b/alib2algo/src/automaton/simplify/Minimize.cpp @@ -1,11 +1,11 @@ /* - * MinimizeDFA.cpp + * Minimize.cpp * * Created on: Dec 9, 2013 * Author: honza */ -#include "MinimizeDFA.h" +#include "Minimize.h" #include <map> #include <set> @@ -18,17 +18,19 @@ #include <automaton/Automaton.h> -namespace minimize { +namespace automaton { -automaton::Automaton MinimizeDFA::minimize(const automaton::Automaton& automaton) { +namespace simplify { + +automaton::Automaton Minimize::minimize(const automaton::Automaton& automaton) { automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, MinimizeDFA::MINIMIZE_DFA); + automaton.getData().Accept((void*) &out, Minimize::MINIMIZE); automaton::Automaton res = std::move(*out); delete out; return res; } -automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) { +automaton::DFA Minimize::minimize(const automaton::DFA& dfa) { if(dfa.getFinalStates().size() == 0) { automaton::DFA result(automaton::State(0)); result.setInputSymbols(dfa.getInputAlphabet()); @@ -140,71 +142,73 @@ automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) { return result; } -void MinimizeDFA::Visit(void*, const automaton::EpsilonNFA&) const { +void Minimize::Visit(void*, const automaton::EpsilonNFA&) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void MinimizeDFA::Visit(void* data, const automaton::DFA& automaton) const { +void Minimize::Visit(void* data, const automaton::DFA& automaton) const { automaton::Automaton* & out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->minimize(automaton)); } -void MinimizeDFA::Visit(void*, const automaton::MultiInitialStateNFA&) const { +void Minimize::Visit(void*, const automaton::MultiInitialStateNFA&) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void MinimizeDFA::Visit(void*, const automaton::NFA&) const { +void Minimize::Visit(void*, const automaton::NFA&) const { throw exception::AlibException("Unsupported automaton type DFA"); } -void MinimizeDFA::Visit(void*, const automaton::ExtendedNFA& ) const { +void Minimize::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void MinimizeDFA::Visit(void*, const automaton::CompactNFA& ) const { +void Minimize::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -void MinimizeDFA::Visit(void*, const automaton::DPDA&) const { +void Minimize::Visit(void*, const automaton::DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } -void MinimizeDFA::Visit(void*, const automaton::SinglePopDPDA&) const { +void Minimize::Visit(void*, const automaton::SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); } -void MinimizeDFA::Visit(void*, const automaton::InputDrivenNPDA&) const { +void Minimize::Visit(void*, const automaton::InputDrivenNPDA&) const { throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); } -void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { +void Minimize::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); } -void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { +void Minimize::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); } -void MinimizeDFA::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { +void Minimize::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); } -void MinimizeDFA::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const { +void Minimize::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); } -void MinimizeDFA::Visit(void*, const automaton::NPDA&) const { +void Minimize::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); } -void MinimizeDFA::Visit(void*, const automaton::SinglePopNPDA&) const { +void Minimize::Visit(void*, const automaton::SinglePopNPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); } -void MinimizeDFA::Visit(void*, const automaton::OneTapeDTM&) const { +void Minimize::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } -const MinimizeDFA MinimizeDFA::MINIMIZE_DFA; +const Minimize Minimize::MINIMIZE; + +} /* namespace simplify */ -} /* namespace minimize */ +} /* namespace automaton */ diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.h b/alib2algo/src/automaton/simplify/Minimize.h similarity index 84% rename from alib2algo/src/minimize/dfa/MinimizeDFA.h rename to alib2algo/src/automaton/simplify/Minimize.h index 01e2d9d8033ac3083c0b73fcbbf29333874bec82..cc16d9f6200d94fcae80febf1c920f11afe201ab 100644 --- a/alib2algo/src/minimize/dfa/MinimizeDFA.h +++ b/alib2algo/src/automaton/simplify/Minimize.h @@ -5,15 +5,17 @@ * Author: Jan Travnicek */ -#ifndef MINIMIZE_DFA_H_ -#define MINIMIZE_DFA_H_ +#ifndef MINIMIZE_H_ +#define MINIMIZE_H_ #include <automaton/Automaton.h> #include <automaton/FSM/DFA.h> -namespace minimize { +namespace automaton { -class MinimizeDFA : public automaton::VisitableAutomatonBase::const_visitor_type { +namespace simplify { + +class Minimize : public automaton::VisitableAutomatonBase::const_visitor_type { public: /** * @param dfa automaton to minimize @@ -40,9 +42,11 @@ protected: void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; - static const MinimizeDFA MINIMIZE_DFA; + static const Minimize MINIMIZE; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ -#endif /* MINIMIZE_DFA_H_ */ +#endif /* MINIMIZE_H_ */ diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.cpp b/alib2algo/src/automaton/simplify/Normalize.cpp similarity index 90% rename from alib2algo/src/normalize/dfa/NormalizeDFA.cpp rename to alib2algo/src/automaton/simplify/Normalize.cpp index d7b11ef6a5e55f2a45c0beb3d751d7ec70e02b62..1780efd4503954c258aee59cd8b885a7fc39b574 100644 --- a/alib2algo/src/normalize/dfa/NormalizeDFA.cpp +++ b/alib2algo/src/automaton/simplify/Normalize.cpp @@ -1,10 +1,11 @@ /* - * NormalizeDFA.cpp + * Normalize.cpp * * Created on: Dec 9, 2013 - * Author: JanTravnicek */ + * Author: Jan Travnicek + */ -#include "NormalizeDFA.h" +#include "Normalize.h" #include <map> #include <deque> @@ -19,9 +20,11 @@ #include "automaton/Automaton.h" -namespace normalize { +namespace automaton { -automaton::DFA NormalizeDFA::normalize(automaton::DFA& fsm) { +namespace simplify { + +automaton::DFA Normalize::normalize(automaton::DFA& fsm) { int counter = 0; std::map<automaton::State, int > normalizationData; std::deque<automaton::State > processingData; @@ -67,4 +70,6 @@ automaton::DFA NormalizeDFA::normalize(automaton::DFA& fsm) { return result; } -} +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/simplify/Normalize.h b/alib2algo/src/automaton/simplify/Normalize.h new file mode 100644 index 0000000000000000000000000000000000000000..48a6df5a2ee60880daf391cc33fa86ed069ac8ef --- /dev/null +++ b/alib2algo/src/automaton/simplify/Normalize.h @@ -0,0 +1,27 @@ +/* + * Normalize.h + * + * Created on: Dec 9, 2013 + * Author: Jan Travnicek + */ + +#ifndef NORMALIZE_H_ +#define NORMALIZE_H_ + +#include "automaton/FSM/DFA.h" + +namespace automaton { + +namespace simplify { + +class Normalize { +public: + static automaton::DFA normalize(automaton::DFA& dfa); + +}; + +} /* namespace simplify */ + +} /* namespace automaton */ + +#endif /* NORMALIZE_H_ */ diff --git a/alib2algo/src/automaton/FSMSingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp similarity index 60% rename from alib2algo/src/automaton/FSMSingleInitialState.cpp rename to alib2algo/src/automaton/simplify/SingleInitialState.cpp index b76387d69771b78b60e6732746c8bb3587add580..372b09d47ba5383a649c5852c0edd66e5bc947e6 100644 --- a/alib2algo/src/automaton/FSMSingleInitialState.cpp +++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp @@ -1,11 +1,11 @@ /* - * FSMSingleInitialState.cpp + * SingleInitialState.cpp * * Created on: 20. 9. 2014 * Author: Tomas Pecka */ -#include "FSMSingleInitialState.h" +#include "SingleInitialState.h" #include <algorithm> #include <set> @@ -20,15 +20,17 @@ namespace automaton { -automaton::Automaton FSMSingleInitialState::convert(const Automaton& automaton) { +namespace simplify { + +automaton::Automaton SingleInitialState::convert(const Automaton& automaton) { automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, FSMSingleInitialState::FSM_SINGLE_INITIAL_STATE); + automaton.getData().Accept((void*) &out, SingleInitialState::SINGLE_INITIAL_STATE); automaton::Automaton res = std::move(*out); delete out; return res; } -automaton::NFA FSMSingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) { +automaton::NFA SingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) { // step 3 automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), automaton.getStates()); automaton::NFA res(q0); @@ -61,97 +63,98 @@ automaton::NFA FSMSingleInitialState::convert(const automaton::MultiInitialState return res; } -automaton::DFA FSMSingleInitialState::convert(const automaton::DFA& automaton) { +automaton::DFA SingleInitialState::convert(const automaton::DFA& automaton) { return automaton; } -automaton::EpsilonNFA FSMSingleInitialState::convert(const automaton::EpsilonNFA& automaton) { +automaton::EpsilonNFA SingleInitialState::convert(const automaton::EpsilonNFA& automaton) { return automaton; } -automaton::NFA FSMSingleInitialState::convert(const automaton::NFA& automaton) { +automaton::NFA SingleInitialState::convert(const automaton::NFA& automaton) { return automaton; } -automaton::CompactNFA FSMSingleInitialState::convert(const automaton::CompactNFA& automaton) { +automaton::CompactNFA SingleInitialState::convert(const automaton::CompactNFA& automaton) { return automaton; } -automaton::ExtendedNFA FSMSingleInitialState::convert(const automaton::ExtendedNFA& automaton) { +automaton::ExtendedNFA SingleInitialState::convert(const automaton::ExtendedNFA& automaton) { return automaton; } -void FSMSingleInitialState::Visit(void* data, const EpsilonNFA& automaton) const { +void SingleInitialState::Visit(void* data, const EpsilonNFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void* data, const MultiInitialStateNFA& automaton) const { +void SingleInitialState::Visit(void* data, const MultiInitialStateNFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void* data, const NFA& automaton) const { +void SingleInitialState::Visit(void* data, const NFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void* data, const DFA& automaton) const { +void SingleInitialState::Visit(void* data, const DFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void* data, const ExtendedNFA& automaton) const { +void SingleInitialState::Visit(void* data, const ExtendedNFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void* data, const CompactNFA& automaton) const { +void SingleInitialState::Visit(void* data, const CompactNFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->convert(automaton)); } -void FSMSingleInitialState::Visit(void*, const DPDA&) const { +void SingleInitialState::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } -void FSMSingleInitialState::Visit(void*, const SinglePopDPDA&) const { +void SingleInitialState::Visit(void*, const SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); } -void FSMSingleInitialState::Visit(void*, const InputDrivenNPDA&) const { +void SingleInitialState::Visit(void*, const InputDrivenNPDA&) const { throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); } -void FSMSingleInitialState::Visit(void*, const VisiblyPushdownDPDA&) const { +void SingleInitialState::Visit(void*, const VisiblyPushdownDPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); } -void FSMSingleInitialState::Visit(void*, const VisiblyPushdownNPDA&) const { +void SingleInitialState::Visit(void*, const VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); } -void FSMSingleInitialState::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { +void SingleInitialState::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); } -void FSMSingleInitialState::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { +void SingleInitialState::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); } -void FSMSingleInitialState::Visit(void*, const NPDA&) const { +void SingleInitialState::Visit(void*, const NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); } -void FSMSingleInitialState::Visit(void*, const SinglePopNPDA&) const { +void SingleInitialState::Visit(void*, const SinglePopNPDA&) const { throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); } -void FSMSingleInitialState::Visit(void*, const OneTapeDTM&) const { +void SingleInitialState::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } -const FSMSingleInitialState FSMSingleInitialState::FSM_SINGLE_INITIAL_STATE; +const SingleInitialState SingleInitialState::SINGLE_INITIAL_STATE; -} +} /* namespace simplify */ +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/FSMSingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h similarity index 84% rename from alib2algo/src/automaton/FSMSingleInitialState.h rename to alib2algo/src/automaton/simplify/SingleInitialState.h index ef69e4f093f3f0cd291728876fa7931b0bbc7255..e5b1f6085c2530196514dfc7b907429540eccedf 100644 --- a/alib2algo/src/automaton/FSMSingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -1,23 +1,25 @@ /* - * FSMSingleInitialState.h + * SingleInitialState.h * * Created on: 20. 9. 2014 * Author: Tomas Pecka */ -#ifndef FSM_SINGLE_INITIAL_STATE_H -#define FSM_SINGLE_INITIAL_STATE_H +#ifndef _SINGLE_INITIAL_STATE_H_ +#define _SINGLE_INITIAL_STATE_H_ #include <automaton/Automaton.h> #include <automaton/common/State.h> namespace automaton { +namespace simplify { + /** * Makes finite automaton's transition function convert. * Source: Melichar: Algorithm 2.22 */ -class FSMSingleInitialState : public VisitableAutomatonBase::const_visitor_type { +class SingleInitialState : public VisitableAutomatonBase::const_visitor_type { public: /** * Computes epsilon closure of a state in epsilon nonfree automaton @@ -50,9 +52,11 @@ private: void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; - static const FSMSingleInitialState FSM_SINGLE_INITIAL_STATE; + static const SingleInitialState SINGLE_INITIAL_STATE; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ -#endif /* FSM_SINGLE_INITIAL_STATE_H_ */ +#endif /* _SINGLE_INITIAL_STATE_H_ */ diff --git a/alib2algo/src/automaton/FSMTotal.cpp b/alib2algo/src/automaton/simplify/Total.cpp similarity index 71% rename from alib2algo/src/automaton/FSMTotal.cpp rename to alib2algo/src/automaton/simplify/Total.cpp index 74cc8ce3aee704291e7a4d1b70f3628cb3b69146..970caa05c824fddf926c731b96b437794e3b4c41 100644 --- a/alib2algo/src/automaton/FSMTotal.cpp +++ b/alib2algo/src/automaton/simplify/Total.cpp @@ -1,11 +1,11 @@ /* - * FSMTotal.cpp + * Total.cpp * * Created on: 20. 9. 2014 * Author: Tomas Pecka */ -#include "FSMTotal.h" +#include "Total.h" #include <exception/AlibException.h> @@ -14,15 +14,17 @@ namespace automaton { -automaton::Automaton FSMTotal::total(const Automaton& automaton) { +namespace simplify { + +automaton::Automaton Total::total(const Automaton& automaton) { automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, FSMTotal::FSM_TOTAL); + automaton.getData().Accept((void*) &out, Total::TOTAL); automaton::Automaton res = std::move(*out); delete out; return res; } -automaton::NFA FSMTotal::total(const automaton::NFA& automaton) { +automaton::NFA Total::total(const automaton::NFA& automaton) { if(! automaton.isDeterministic()) { throw exception::AlibException("Automaton must be deterministic to make its transition function total"); } @@ -42,7 +44,7 @@ automaton::NFA FSMTotal::total(const automaton::NFA& automaton) { return res; } -automaton::DFA FSMTotal::total(const automaton::DFA& automaton) { +automaton::DFA Total::total(const automaton::DFA& automaton) { automaton::DFA res(automaton); automaton::State nullState = automaton::createUniqueState(automaton::State("q0"), automaton.getStates()); res.addState(nullState); @@ -58,33 +60,35 @@ automaton::DFA FSMTotal::total(const automaton::DFA& automaton) { return res; } -void FSMTotal::Visit(void*, const EpsilonNFA&) const { +void Total::Visit(void*, const EpsilonNFA&) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void FSMTotal::Visit(void*, const MultiInitialStateNFA&) const { +void Total::Visit(void*, const MultiInitialStateNFA&) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void FSMTotal::Visit(void* data, const NFA& automaton) const { +void Total::Visit(void* data, const NFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->total(automaton)); } -void FSMTotal::Visit(void* data, const DFA& automaton) const { +void Total::Visit(void* data, const DFA& automaton) const { automaton::Automaton*& out = *((automaton::Automaton**) data); out = new automaton::Automaton(this->total(automaton)); } -void FSMTotal::Visit(void*, const ExtendedNFA&) const { +void Total::Visit(void*, const ExtendedNFA&) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FSMTotal::Visit(void*, const CompactNFA&) const { +void Total::Visit(void*, const CompactNFA&) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const FSMTotal FSMTotal::FSM_TOTAL; +const Total Total::TOTAL; -} +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/FSMTotal.h b/alib2algo/src/automaton/simplify/Total.h similarity index 81% rename from alib2algo/src/automaton/FSMTotal.h rename to alib2algo/src/automaton/simplify/Total.h index 604ddb74823dcd4111b0a11c652a7a946b1dec16..9730b0b96e28ad005665707d71f2d285695f75e1 100644 --- a/alib2algo/src/automaton/FSMTotal.h +++ b/alib2algo/src/automaton/simplify/Total.h @@ -1,12 +1,12 @@ /* - * FSMTotal.h + * Total.h * * Created on: 20. 9. 2014 * Author: Tomas Pecka */ -#ifndef FSM_TOTAL_H_ -#define FSM_TOTAL_H_ +#ifndef TOTAL_H_ +#define TOTAL_H_ #include <algorithm> #include <deque> @@ -17,11 +17,13 @@ namespace automaton { +namespace simplify { + /** * Makes finite automaton's transition function total. * Source: Melichar: Algorithm 2.22 */ -class FSMTotal : public VisitableConstFSMBase { +class Total : public VisitableConstFSMBase { public: /** * Computes epsilon closure of a state in epsilon nonfree automaton @@ -39,9 +41,11 @@ private: void Visit(void*, const ExtendedNFA& automaton) const; void Visit(void*, const CompactNFA& automaton) const; - static const FSMTotal FSM_TOTAL; + static const Total TOTAL; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ -#endif /* FSM_TOTAL_H_ */ +#endif /* TOTAL_H_ */ diff --git a/alib2algo/src/trim/automaton/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp similarity index 97% rename from alib2algo/src/trim/automaton/Trim.cpp rename to alib2algo/src/automaton/simplify/Trim.cpp index e2bbcd20a1289041f725267615c488b8a15012ab..416378528dcca262c97a848fc653c92cb5a36f05 100644 --- a/alib2algo/src/trim/automaton/Trim.cpp +++ b/alib2algo/src/automaton/simplify/Trim.cpp @@ -16,13 +16,12 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> -#include "../../automaton/UsefullStates.h" -#include "../../automaton/UnreachableStates.h" - #include "automaton/common/State.h" #include "automaton/Automaton.h" -namespace trim { +namespace automaton { + +namespace simplify { template<class T> T Trim::trim( const T & fsm ) { @@ -116,5 +115,7 @@ void Trim::Visit(void*, const automaton::OneTapeDTM&) const { const Trim Trim::TRIM; -} +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/trim/automaton/Trim.h b/alib2algo/src/automaton/simplify/Trim.h similarity index 89% rename from alib2algo/src/trim/automaton/Trim.h rename to alib2algo/src/automaton/simplify/Trim.h index 1c88bae446df6df1846654b4d4d4894f6dea2c49..e5c085bd268d6640af6b9157515a836579fa5e64 100644 --- a/alib2algo/src/trim/automaton/Trim.h +++ b/alib2algo/src/automaton/simplify/Trim.h @@ -5,15 +5,17 @@ * Author: Tomas Pecka */ -#ifndef TRIM_H_ -#define TRIM_H_ +#ifndef AUTOMATON_TRIM_H_ +#define AUTOMAONT_TRIM_H_ #include <algorithm> #include <deque> #include <set> #include <automaton/Automaton.h> -namespace trim { +namespace automaton { + +namespace simplify { class Trim : public automaton::VisitableAutomatonBase::const_visitor_type { public: @@ -46,6 +48,8 @@ private: static const Trim TRIM; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ -#endif /* TRIM_H_ */ +#endif /* AUTOMATON_TRIM_H_ */ diff --git a/alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp similarity index 93% rename from alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp rename to alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp index 370a121f5b9827a7862b91ba5c1bfff70faf57bd..cfab0b7c602f88b987b818f08f6759553b1f6776 100644 --- a/alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp @@ -15,17 +15,19 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> -#include "../../automaton/UnreachableStates.h" +#include "../properties/UnreachableStates.h" #include "automaton/common/State.h" #include "automaton/Automaton.h" -namespace trim { +namespace automaton { + +namespace simplify { template<class T> T UnreachableStatesRemover::remove( const T & fsm ) { // 1a - std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm ); + std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm ); // 2 T M(fsm.getInitialState()); @@ -57,7 +59,7 @@ template automaton::ExtendedNFA UnreachableStatesRemover::remove( const automato template<> automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) { // 1a - std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm ); + std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm ); // 2 automaton::DFA M(fsm.getInitialState() ); @@ -83,7 +85,7 @@ automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) { template<> automaton::MultiInitialStateNFA UnreachableStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) { // 1a - std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm ); + std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm ); // 2 automaton::MultiInitialStateNFA M; @@ -189,5 +191,6 @@ void UnreachableStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const const UnreachableStatesRemover UnreachableStatesRemover::UNREACHABLE_STATES_REMOVER; -} +} /* namespace simplify */ +} /* namespace automaton */ diff --git a/alib2algo/src/trim/automaton/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h similarity index 94% rename from alib2algo/src/trim/automaton/UnreachableStatesRemover.h rename to alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index 2c3143d3a997423395937647d411f454813a728f..1422d99aa9e3d8c8555f0c8af678bc0bb0b291d9 100644 --- a/alib2algo/src/trim/automaton/UnreachableStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h @@ -13,7 +13,9 @@ #include <set> #include <automaton/Automaton.h> -namespace trim { +namespace automaton { + +namespace simplify { class UnreachableStatesRemover : public automaton::VisitableAutomatonBase::const_visitor_type { public: @@ -46,6 +48,8 @@ private: static const UnreachableStatesRemover UNREACHABLE_STATES_REMOVER; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ #endif /* UNREACHABLE_STATES_REMOVER_H_ */ diff --git a/alib2algo/src/trim/automaton/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp similarity index 93% rename from alib2algo/src/trim/automaton/UselessStatesRemover.cpp rename to alib2algo/src/automaton/simplify/UselessStatesRemover.cpp index d4b55f85270d27e7af434668627b1140e8c01c34..540d6723dfd8691e1f06e1fbc726f68783f2a017 100644 --- a/alib2algo/src/trim/automaton/UselessStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp @@ -15,17 +15,19 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> -#include "../../automaton/UsefullStates.h" +#include "../properties/UsefullStates.h" #include "automaton/common/State.h" #include "automaton/Automaton.h" -namespace trim { +namespace automaton { + +namespace simplify { template<class T> T UselessStatesRemover::remove( const T & fsm ) { // 1. - std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm ); + std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm ); // 2. T M(fsm.getInitialState()); @@ -59,7 +61,7 @@ template automaton::ExtendedNFA UselessStatesRemover::remove( const automaton::E template<> automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) { // 1. - std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm ); + std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm ); // 2. automaton::DFA M ( fsm.getInitialState () ); @@ -87,7 +89,7 @@ automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) { template<> automaton::MultiInitialStateNFA UselessStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) { // 1. - std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm ); + std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm ); // 2. automaton::MultiInitialStateNFA M; @@ -198,5 +200,6 @@ void UselessStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const { const UselessStatesRemover UselessStatesRemover::USELESS_STATES_REMOVER; -} +} /* namespace simplify */ +} /* namespace automaton */ diff --git a/alib2algo/src/trim/automaton/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h similarity index 94% rename from alib2algo/src/trim/automaton/UselessStatesRemover.h rename to alib2algo/src/automaton/simplify/UselessStatesRemover.h index 30df905885469fa05ed96de576316c1ea2c66307..dbf462579d108bb3d0eb3e0924c6d1f9a51b2e66 100644 --- a/alib2algo/src/trim/automaton/UselessStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h @@ -13,7 +13,9 @@ #include <set> #include <automaton/Automaton.h> -namespace trim { +namespace automaton { + +namespace simplify { class UselessStatesRemover : public automaton::VisitableAutomatonBase::const_visitor_type { public: @@ -46,6 +48,8 @@ private: static const UselessStatesRemover USELESS_STATES_REMOVER; }; -} +} /* namespace simplify */ + +} /* namespace automaton */ #endif /* USELESS_STATES_REMOVER_H_ */ diff --git a/alib2algo/src/automaton/PDAToRHPDA.cpp b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp similarity index 100% rename from alib2algo/src/automaton/PDAToRHPDA.cpp rename to alib2algo/src/automaton/transform/PDAToRHPDA.cpp diff --git a/alib2algo/src/automaton/PDAToRHPDA.h b/alib2algo/src/automaton/transform/PDAToRHPDA.h similarity index 100% rename from alib2algo/src/automaton/PDAToRHPDA.h rename to alib2algo/src/automaton/transform/PDAToRHPDA.h diff --git a/alib2algo/src/automaton/RHPDAToPDA.cpp b/alib2algo/src/automaton/transform/RHPDAToPDA.cpp similarity index 100% rename from alib2algo/src/automaton/RHPDAToPDA.cpp rename to alib2algo/src/automaton/transform/RHPDAToPDA.cpp diff --git a/alib2algo/src/automaton/RHPDAToPDA.h b/alib2algo/src/automaton/transform/RHPDAToPDA.h similarity index 100% rename from alib2algo/src/automaton/RHPDAToPDA.h rename to alib2algo/src/automaton/transform/RHPDAToPDA.h diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.h b/alib2algo/src/conversions/re2fa/GlushkovNFA.h deleted file mode 100644 index 1cb1c806b7aa9859135c1a9841ee8b22664fb6fe..0000000000000000000000000000000000000000 --- a/alib2algo/src/conversions/re2fa/GlushkovNFA.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * GlushkovNFA.h - * - * Created on: 11. 1. 2014 - * Author: Tomas Pecka - */ - -#ifndef FA2RE_GLUSHKOVNFA_H_ -#define FA2RE_GLUSHKOVNFA_H_ - -#include <map> - -#include <automaton/FSM/NFA.h> -#include <regexp/RegExp.h> -#include <regexp/formal/FormalRegExp.h> -#include <regexp/unbounded/UnboundedRegExp.h> - -namespace conversions { - -namespace re2fa { - -/** - * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm. - * Source: Melichar 2.107 - */ -class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type -{ -public: - /** - * Performs conversion. - * @param re Original regular expression. - * @return NFA equivalent to original regular expression. - */ - static automaton::NFA convert(const regexp::RegExp& re); - - static automaton::NFA convert(const regexp::UnboundedRegExp& re); - static automaton::NFA convert(const regexp::FormalRegExp& re); - -private: - void Visit(void*, const regexp::FormalRegExp& regexp) const; - void Visit(void*, const regexp::UnboundedRegExp& regexp) const; - - static const GlushkovNFA GLUSHKOV_NFA; -}; - -} /* namespace re2fa */ - -} /* namespace conversions */ - -#endif /* FA2RE_GLUSHKOV_H_ */ diff --git a/alib2algo/src/conversions/rg2fa/RGtoFA.cpp b/alib2algo/src/conversions/rg2fa/RGtoFA.cpp deleted file mode 100644 index d18ffdada6efff06b9ad9acbe39cf27fbb07ca60..0000000000000000000000000000000000000000 --- a/alib2algo/src/conversions/rg2fa/RGtoFA.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * RGtoFA.cpp - * - * Created on: 1. 11. 2013 - * Author: Tomas Pecka - */ -#include "RGtoFA.h" - -#include <alphabet/LabeledSymbol.h> -#include <exception/AlibException.h> - -namespace conversions -{ - -namespace rg2fa -{ - -automaton::Automaton RGtoFA::convert(const grammar::Grammar& grammar) -{ - automaton::Automaton* out = NULL; - grammar.getData().Accept((void*) &out, RGtoFA::RG_TO_FA_CONVERSION); - automaton::Automaton res = std::move(*out); - delete out; - return res; -} - -automaton::NFA RGtoFA::convert(const grammar::LeftRG& grammar) -{ - std::map<alphabet::Symbol, automaton::State> stateMap; - std::set<automaton::State> states; - - // step 2 - for(const auto& symbol : grammar.getNonterminalAlphabet()) - { - automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); - states.insert(state); - stateMap.insert(std::make_pair(symbol, state)); - } - - // step 1, 4 - const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); - states.insert(q0); - automaton::NFA automaton(q0); - automaton.setInputSymbols(grammar.getTerminalAlphabet()); - automaton.setStates(states); - - // step 3 - for(const auto& rule : grammar.getRules()) - { - const alphabet::Symbol& lhs = rule.first; - for(const auto& ruleRHS : rule.second) - { - if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B - { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second); - } - else // if B->a => \delta(StartState,a)=B - { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - automaton.addTransition(q0, rhs, stateMap.find(lhs)->second); - } - } - } - - // step 5 - automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second); - if(grammar.getGeneratesEpsilon()) - automaton.addFinalState(q0); - - return automaton; -} - -automaton::NFA RGtoFA::convert(const grammar::RightRG& grammar) -{ - std::map<alphabet::Symbol, automaton::State> stateMap; - std::set<automaton::State> states; - - // step2 - for(const auto& symbol : grammar.getNonterminalAlphabet()) - { - automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); - states.insert(state); - stateMap.insert(std::make_pair(symbol, state)); - } - - // step 1, 4 - const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states); - states.insert(AState); - automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second); - automaton.setStates(states); - - automaton.setInputSymbols(grammar.getTerminalAlphabet()); - - // step 3 - for(const auto& rule : grammar.getRules()) - { - const alphabet::Symbol& lhs = rule.first; - for(const auto& ruleRHS : rule.second) - { - if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C - { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second); - } - else // if B->a => \delta(B,a)=AState - { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - automaton.addTransition(stateMap.find(lhs)->second, rhs, AState); - } - } - } - - // step 5 - automaton.addFinalState(AState); - if(grammar.getGeneratesEpsilon()) - automaton.addFinalState(automaton.getInitialState()); - - return automaton; -} - -void RGtoFA::Visit(void* userData, const grammar::RightRG& grammar) const -{ - automaton::Automaton* & out = *((automaton::Automaton**) userData); - out = new automaton::Automaton(this->convert(grammar)); -} - -void RGtoFA::Visit(void* userData, const grammar::LeftRG& grammar) const -{ - automaton::Automaton* & out = *((automaton::Automaton**) userData); - out = new automaton::Automaton(this->convert(grammar)); -} - -void RGtoFA::Visit(void*, const grammar::RightLG&) const -{ - throw exception::AlibException("Unsupported grammar type RightLG"); -} - -void RGtoFA::Visit(void*, const grammar::LeftLG&) const -{ - throw exception::AlibException("Unsupported grammar type LeftLG"); -} - -const RGtoFA RGtoFA::RG_TO_FA_CONVERSION; - -} /* namespace rg2fa */ - -} /* namespace conversions */ diff --git a/alib2algo/src/conversions/rg2fa/RGtoFA.h b/alib2algo/src/conversions/rg2fa/RGtoFA.h deleted file mode 100644 index d88359532b2862ca676e46e988f4aa43e9dab1dc..0000000000000000000000000000000000000000 --- a/alib2algo/src/conversions/rg2fa/RGtoFA.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * RGtoFA.h - * - * Created on: 1. 11. 2013 - * Author: Tomas Pecka - */ - -#ifndef __RGTOFA_H__ -#define __RGTOFA_H__ - -#include <grammar/Grammar.h> -#include <grammar/Regular/LeftRG.h> -#include <grammar/Regular/RightRG.h> - -#include <automaton/Automaton.h> -#include <automaton/FSM/NFA.h> - -namespace conversions -{ - -namespace rg2fa -{ - -/** - * Converts regular grammar to nondeterministic finite automaton. - * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA). - */ -class RGtoFA : public grammar::VisitableConstRGBase -{ -public: - /** - * Performs conversion. - * @param grammar Regular grammar to convert. - * @return FSM equivalent to source grammar. - */ - static automaton::Automaton convert(const grammar::Grammar& grammar); - - static automaton::NFA convert(const grammar::LeftRG& grammar); - static automaton::NFA convert(const grammar::RightRG& grammar); - -private: - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::LeftLG& grammar) const; - - static const RGtoFA RG_TO_FA_CONVERSION; -}; - -} /* namespace rg2fa */ - -} /* namespace conversions */ - -#endif /* __RGTOFA_H__ */ diff --git a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h b/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h deleted file mode 100644 index 2d867dcdd04578899e268dbda81b5afe9013f7ca..0000000000000000000000000000000000000000 --- a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HDPDA_DETERMINIZER_H_ -#define HDPDA_DETERMINIZER_H_ - -#include "automaton/PDA/RealTimeHeightDeterministicNPDA.h" -#include "automaton/PDA/RealTimeHeightDeterministicDPDA.h" - -namespace determinize { - -/** - * Class for running basic determinization algorithm on vpa. - */ -class HDPDADeterminizer { -public: - /** - * Runs determinization algorithm on nondeterministic vpa given in constructor. - * - * @return deterministic visibly pushdown automaton - */ - static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic); - -}; - -} /* namespace determinize */ - -#endif /* HDPDA_DETERMINIZER_h_ */ diff --git a/alib2algo/src/determinize/idpda/IDPDADeterminizer.h b/alib2algo/src/determinize/idpda/IDPDADeterminizer.h deleted file mode 100644 index 4009c23dd29245ccac294b86ce5a6f916f012789..0000000000000000000000000000000000000000 --- a/alib2algo/src/determinize/idpda/IDPDADeterminizer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * IDPDADeterminizer.h - * - * Created on: 16. 1. 2014 - * Author: Jan Vesely - */ - -#ifndef IDPDA_DETERMINIZER_H_ -#define IDPDA_DETERMINIZER_H_ - -#include <set> - -#include "automaton/common/State.h" -#include "automaton/PDA/InputDrivenNPDA.h" -#include "automaton/PDA/DPDA.h" - -namespace determinize { - -/** - * Class for running determinization algorithm on fsm. - */ -class IDPDADeterminizer { -public: - - /** - * @param nfsm nondeterministic final-state machine given for determinization - * Runs determinization algorithm on nondeterministic fsm given in constructor. - */ - static automaton::DPDA determinize(const automaton::InputDrivenNPDA& nfa); - -}; - -} /* namespace determinize */ - -#endif /* IDPDA_DETERMINIZER_H_ */ diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp deleted file mode 100644 index 3e0925ea731914873154ec7e967d09c88a99f501..0000000000000000000000000000000000000000 --- a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * NFADeterminizer.cpp - * - * Created on: 16. 1. 2014 - * Author: Jan Vesely - */ - -#include "NFADeterminizer.h" -#include "../common/NFACommon.h" - -#include <deque> -#include <algorithm> - -namespace determinize { - -automaton::Automaton NFADeterminizer::determinize(const automaton::Automaton& automaton) { - automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, NFADeterminizer::NFA_DETERMINIZER); - automaton::Automaton res = std::move(*out); - delete out; - return res; -} - -automaton::DFA NFADeterminizer::determinize(const automaton::MultiInitialStateNFA& nfa) { - // 1, 4 - automaton::State initialState(createDFAState(nfa.getInitialStates())); - automaton::DFA res(initialState); - res.setInputSymbols(nfa.getInputAlphabet()); - - // 2 - std::deque<automaton::State> todo; - todo.push_back(initialState); - - do { - // 3a, c - automaton::State state = todo.front(); - todo.pop_front(); - - // 3b - for (const auto& input : nfa.getInputAlphabet()) { - std::set<automaton::State> targetNFAStates; - for(const auto& nfaState : recreateNFAStates(state)) { - auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input)); - if(iter != nfa.getTransitions().end()) { - targetNFAStates.insert(iter->second.begin(), iter->second.end()); - } - } - automaton::State dfaState = createDFAState(targetNFAStates); - - // 4 - bool existed = !res.addState(dfaState); - - // 3b - res.addTransition(state, input, dfaState); - - if(!existed) todo.push_back(dfaState); - } - } while(!todo.empty()); - - // 5 - for (const auto& dfaState : res.getStates()) { - std::set<automaton::State> nfaStates = recreateNFAStates(dfaState); - if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) { - res.addFinalState(dfaState); - } - } - - return res; -} - -automaton::DFA NFADeterminizer::determinize(const automaton::NFA& nfa) { - // 1, 4 - automaton::State initialState(createDFAState({nfa.getInitialState()})); - automaton::DFA res(initialState); - res.setInputSymbols(nfa.getInputAlphabet()); - - // 2 - std::deque<automaton::State> todo; - todo.push_back(initialState); - - do { - // 3a, c - automaton::State state = todo.front(); - todo.pop_front(); - - // 3b - for (const auto& input : nfa.getInputAlphabet()) { - std::set<automaton::State> targetNFAStates; - for(const auto& nfaState : recreateNFAStates(state)) { - auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input)); - if(iter != nfa.getTransitions().end()) { - targetNFAStates.insert(iter->second.begin(), iter->second.end()); - } - } - automaton::State dfaState = createDFAState(targetNFAStates); - - // 4 - bool existed = !res.addState(dfaState); - - // 3b - res.addTransition(state, input, dfaState); - - if(!existed) todo.push_back(dfaState); - } - } while(!todo.empty()); - - // 5 - for (const auto& dfaState : res.getStates()) { - std::set<automaton::State> nfaStates = recreateNFAStates(dfaState); - if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) { - res.addFinalState(dfaState); - } - } - - return res; -} - -void NFADeterminizer::Visit(void*, const automaton::EpsilonNFA&) const { - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void NFADeterminizer::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { - automaton::Automaton* & out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->determinize(automaton)); -} - -void NFADeterminizer::Visit(void* data, const automaton::NFA& automaton) const { - automaton::Automaton* & out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->determinize(automaton)); -} - -void NFADeterminizer::Visit(void*, const automaton::DFA&) const { - throw exception::AlibException("Unsupported automaton type DFA"); -} - -void NFADeterminizer::Visit(void*, const automaton::ExtendedNFA& ) const { - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void NFADeterminizer::Visit(void*, const automaton::CompactNFA& ) const { - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void NFADeterminizer::Visit(void*, const automaton::DPDA&) const { - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::SinglePopDPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::InputDrivenNPDA&) const { - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownDPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const { - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const { - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::NPDA&) const { - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::SinglePopNPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void NFADeterminizer::Visit(void*, const automaton::OneTapeDTM&) const { - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -const NFADeterminizer NFADeterminizer::NFA_DETERMINIZER; - -} diff --git a/alib2algo/src/determinize/vpa/VPADeterminizer.h b/alib2algo/src/determinize/vpa/VPADeterminizer.h deleted file mode 100644 index 129a90f2a3bda42bb9b35007fc8cbd4234286d04..0000000000000000000000000000000000000000 --- a/alib2algo/src/determinize/vpa/VPADeterminizer.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef VPADETERMINIZER_H_ -#define VPADETERMINIZER_H_ - -#include "automaton/PDA/VisiblyPushdownNPDA.h" -#include "automaton/PDA/VisiblyPushdownDPDA.h" - -namespace determinize { - -/** - * Class for running basic determinization algorithm on vpa. - */ -class VPADeterminizer { -public: - /** - * Runs determinization algorithm on nondeterministic vpa given in constructor. - * - * @return deterministic visibly pushdown automaton - */ - static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic); - -}; - -} /* namespace determinize */ - -#endif /* VPADETERMINIZER_H_ */ diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.cpp b/alib2algo/src/equations/LeftRegularEquationSolver.cpp index 72351deeaad2ad5cb333a0b44bc62a15e684877a..59f2d51ab21432ce778de40714c1df5eb92c62d2 100644 --- a/alib2algo/src/equations/LeftRegularEquationSolver.cpp +++ b/alib2algo/src/equations/LeftRegularEquationSolver.cpp @@ -8,13 +8,11 @@ #include "LeftRegularEquationSolver.h" #include "regexp/unbounded/UnboundedRegExpElements.h" -#include "../regexp/RegExpOptimize.h" +#include "../regexp/simplify/RegExpOptimize.h" namespace equations { regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { - regexp::RegExpOptimize opt; - for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) { const alphabet::Symbol& a = * itA; @@ -24,7 +22,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { * => A = 10*B + 20*C */ regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second)); - regexp::RegExpOptimize::optimize(loop); + regexp::simplify::RegExpOptimize::optimize(loop); // for all transitions from A apply Arden's Lemma for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) { @@ -35,7 +33,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { regexp::UnboundedRegExpAlternation alt; alt.appendElement(std::move(concat)); equationTransition.find(std::make_pair(a, b))->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second); + regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second); } regexp::UnboundedRegExpConcatenation concat; concat.appendElement(std::move(equationFinal.find(a)->second)); @@ -43,7 +41,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { regexp::UnboundedRegExpAlternation alt; alt.appendElement(std::move(concat)); equationFinal.find(a)->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationFinal.find(a)->second); + regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second); /* * eliminate A from rest of the equations using this pattern: @@ -62,7 +60,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second)); alt.appendElement(std::move(concat)); equationTransition.find(std::make_pair(b, c))->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second); + regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second); } regexp::UnboundedRegExpConcatenation concat; @@ -72,11 +70,11 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) { alt.appendElement(std::move(equationFinal.find(b)->second)); alt.appendElement(std::move(concat)); equationFinal.find(b)->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationFinal.find(b)->second); + regexp::simplify::RegExpOptimize::optimize(equationFinal.find(b)->second); } } - return regexp::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))); + return regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))); } } /* namespace equations */ diff --git a/alib2algo/src/equations/RightRegularEquationSolver.cpp b/alib2algo/src/equations/RightRegularEquationSolver.cpp index 08cf2fb03d8ba55b7f2eaff2c734be5856e11471..8403237f907543ea2699ae540206529335fcbf3e 100644 --- a/alib2algo/src/equations/RightRegularEquationSolver.cpp +++ b/alib2algo/src/equations/RightRegularEquationSolver.cpp @@ -8,13 +8,11 @@ #include "RightRegularEquationSolver.h" #include "regexp/unbounded/UnboundedRegExpElements.h" -#include "../regexp/RegExpOptimize.h" +#include "../regexp/simplify/RegExpOptimize.h" namespace equations { regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { - regexp::RegExpOptimize opt; - for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) { const alphabet::Symbol& a = * itA; @@ -24,7 +22,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { * => A = 0*1B + 0*2C */ regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second)); - regexp::RegExpOptimize::optimize(loop); + regexp::simplify::RegExpOptimize::optimize(loop); // for all transitions from A apply Arden's Lemma for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) { @@ -35,7 +33,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { regexp::UnboundedRegExpAlternation alt; alt.appendElement(std::move(concat)); equationTransition.find(std::make_pair(a, b))->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second); + regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second); } regexp::UnboundedRegExpConcatenation concat; concat.appendElement(std::move(loop)); @@ -43,7 +41,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { regexp::UnboundedRegExpAlternation alt; alt.appendElement(std::move(concat)); equationFinal.find(a)->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationFinal.find(a)->second); + regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second); /* * eliminate A from rest of the equations using this pattern: @@ -62,7 +60,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second)); alt.appendElement(std::move(concat)); equationTransition.find(std::make_pair(b, c))->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second); + regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second); } regexp::UnboundedRegExpConcatenation concat; @@ -72,11 +70,11 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) { alt.appendElement(std::move(equationFinal.find(b)->second)); alt.appendElement(std::move(concat)); equationFinal.find(b)->second = std::move(alt); - regexp::RegExpOptimize::optimize(equationFinal.find(b)->second); + regexp::simplify::RegExpOptimize::optimize(equationFinal.find(b)->second); } } - return regexp::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))); + return regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))); } } /* namespace equations */ diff --git a/alib2algo/src/grammar/GrammarPropertiesCFG.cpp b/alib2algo/src/grammar/GrammarPropertiesCFG.cpp deleted file mode 100644 index e72f1cb33e65ebe5bfd382b40bb131b2330fd955..0000000000000000000000000000000000000000 --- a/alib2algo/src/grammar/GrammarPropertiesCFG.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * GrammarPropertiesCFG.cpp - * - * Created on: 22. 3. 2014 - * Author: Tomas Pecka - */ - -#include "GrammarPropertiesCFG.h" - -#include <grammar/ContextFree/CFG.h> -#include <grammar/ContextFree/EpsilonFreeCFG.h> -#include <grammar/ContextFree/GNF.h> -#include <grammar/ContextFree/CNF.h> -#include <grammar/ContextFree/LG.h> -#include <grammar/Regular/LeftLG.h> -#include <grammar/Regular/LeftRG.h> -#include <grammar/Regular/RightLG.h> -#include <grammar/Regular/RightRG.h> - -#include <std/set.hpp> - -namespace grammar { - -template<class T> -std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const T & grammar ) { - // 1. - std::deque<std::set<alphabet::Symbol>> Ni; - Ni.push_back( std::set<alphabet::Symbol>( ) ); - - int i = 1; - - // 2. - while( true ) { - Ni.push_back( Ni.at( i - 1 ) ); - - for( const auto & rule : grammar.getRawRules( ) ) { - for( const auto & rhs : rule.second ) { - if( std::all_of( rhs.begin( ), rhs.end( ), [ i, Ni, grammar ]( const alphabet::Symbol & symbol ) -> bool { - return Ni.at( i - 1 ) . count( symbol ) || grammar.getTerminalAlphabet( ). count( symbol ); - } ) ) - Ni.at( i ).insert( rule.first ); - } - } - - if( Ni.at( i ) == Ni.at( i - 1 ) ) - break; - - i = i + 1; - } - - // 3. - return Ni.at( i ); -} - -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::CFG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::GNF & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::CNF & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LeftLG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LeftRG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::RightLG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::RightRG & grammar ); - -template<class T> -std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const T & grammar ) { - // 1 - std::deque<std::set<alphabet::Symbol>> Vi; - Vi.push_back( std::set<alphabet::Symbol>( ) ); - Vi.at( 0 ).insert( grammar.getInitialSymbol( ) ); - - int i = 1; - - // 2. - while( true ) { - Vi.push_back( Vi.at( i - 1 ) ); - - for( const auto & rule : grammar.getRawRules( ) ) { - if( Vi.at( i - 1 ).count( rule.first ) ) { - for( const auto & rhs : rule.second ) { - Vi.at( i ).insert( rhs.begin( ), rhs.end( ) ); - } - } - } - - - if( Vi.at( i ) == Vi.at( i - 1 ) ) - break; - - i = i + 1; - } - - // 3. - return Vi.at( i ); -} - -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::CFG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::GNF & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::CNF & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LeftLG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LeftRG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightLG & grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightRG & grammar ); - -template<class T> -std::set<alphabet::Symbol> GrammarPropertiesCFG::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); -} - -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CFG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::GNF& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CNF& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftLG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftRG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightLG& grammar ); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightRG& grammar ); - -template<class T> -std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal) { - if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) { - throw exception::AlibException("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); -} - -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal); - -} /* namespace grammar */ diff --git a/alib2algo/src/grammar/GrammarPropertiesCFG.h b/alib2algo/src/grammar/GrammarPropertiesCFG.h deleted file mode 100644 index 4cf05c9cce7e2373c36b3b66836f887c67904e4d..0000000000000000000000000000000000000000 --- a/alib2algo/src/grammar/GrammarPropertiesCFG.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * GrammarPropertiesCFG.h - * - * Created on: 22. 3. 2014 - * Author: Tomas Pecka - */ - -#ifndef GRAMMAR_PROPERTIES_CFG_H_ -#define GRAMMAR_PROPERTIES_CFG_H_ - -#include <algorithm> -#include <deque> -#include <set> - -#include <exception/AlibException.h> - -#include <alphabet/Symbol.h> - -namespace grammar { - -/** - * Implements algorithms from Melichar, chapter 3.3 - */ -class GrammarPropertiesCFG { -public: - /** - * Implements steps 1 through 3 in Melichar 3.6 - */ - template<class T> - static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar ); - - /** - * Implements - */ - template<class T> - static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar ); - - /** - * Retrieve all nullable nonterminals from grammar - * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps - * - * Source: Melichar, algorithm 2.4, step 1 - * - * @param grammar grammar - * @return set of nullable nonterminals from grammar - */ - template<class T> - static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar); - - /** - * Retrieves set N = {B : A->^* B} for given grammar and nonterminal - * - * Source: Melichar, algorithm 2.6, step 1 - * - * @param grammar grammar - * @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); -}; - -} /* namespace grammar */ - -#endif /* GRAMMAR_PROPERTIES_CFG_H_ */ diff --git a/alib2algo/src/grammar/convert/ToAutomaton.cpp b/alib2algo/src/grammar/convert/ToAutomaton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68a1e5ca4721c510c9928adbbd2f66827f8e6ce6 --- /dev/null +++ b/alib2algo/src/grammar/convert/ToAutomaton.cpp @@ -0,0 +1,182 @@ +/* + * ToAutomaton.cpp + * + * Created on: 1. 11. 2013 + * Author: Tomas Pecka + */ +#include "ToAutomaton.h" + +#include <alphabet/LabeledSymbol.h> +#include <exception/AlibException.h> + +namespace grammar { + +namespace convert { + +automaton::Automaton ToAutomaton::convert(const grammar::Grammar& grammar) +{ + automaton::Automaton* out = NULL; + grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar) +{ + std::map<alphabet::Symbol, automaton::State> stateMap; + std::set<automaton::State> states; + + // step 2 + for(const auto& symbol : grammar.getNonterminalAlphabet()) + { + automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); + states.insert(state); + stateMap.insert(std::make_pair(symbol, state)); + } + + // step 1, 4 + const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); + states.insert(q0); + automaton::NFA automaton(q0); + automaton.setInputSymbols(grammar.getTerminalAlphabet()); + automaton.setStates(states); + + // step 3 + for(const auto& rule : grammar.getRules()) + { + const alphabet::Symbol& lhs = rule.first; + for(const auto& ruleRHS : rule.second) + { + if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B + { + const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); + automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second); + } + else // if B->a => \delta(StartState,a)=B + { + const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); + automaton.addTransition(q0, rhs, stateMap.find(lhs)->second); + } + } + } + + // step 5 + automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second); + if(grammar.getGeneratesEpsilon()) + automaton.addFinalState(q0); + + return automaton; +} + +automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar) +{ + std::map<alphabet::Symbol, automaton::State> stateMap; + std::set<automaton::State> states; + + // step2 + for(const auto& symbol : grammar.getNonterminalAlphabet()) + { + automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); + states.insert(state); + stateMap.insert(std::make_pair(symbol, state)); + } + + // step 1, 4 + const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states); + states.insert(AState); + automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second); + automaton.setStates(states); + + automaton.setInputSymbols(grammar.getTerminalAlphabet()); + + // step 3 + for(const auto& rule : grammar.getRules()) + { + const alphabet::Symbol& lhs = rule.first; + for(const auto& ruleRHS : rule.second) + { + if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C + { + const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); + automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second); + } + else // if B->a => \delta(B,a)=AState + { + const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); + automaton.addTransition(stateMap.find(lhs)->second, rhs, AState); + } + } + } + + // step 5 + automaton.addFinalState(AState); + if(grammar.getGeneratesEpsilon()) + automaton.addFinalState(automaton.getInitialState()); + + return automaton; +} + +void ToAutomaton::Visit(void* userData, const grammar::RightRG& grammar) const +{ + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(grammar)); +} + +void ToAutomaton::Visit(void* userData, const grammar::LeftRG& grammar) const +{ + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(grammar)); +} + +void ToAutomaton::Visit(void*, const grammar::RightLG&) const +{ + throw exception::AlibException("Unsupported grammar type RightLG"); +} + +void ToAutomaton::Visit(void*, const grammar::LeftLG&) const +{ + throw exception::AlibException("Unsupported grammar type LeftLG"); +} + +void ToAutomaton::Visit(void*, const grammar::LG& ) const { + throw exception::AlibException("Unsupported grammar type LG"); +} + +void ToAutomaton::Visit(void*, const grammar::CFG& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToAutomaton::Visit(void*, const grammar::EpsilonFreeCFG& ) const { + throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG"); +} + +void ToAutomaton::Visit(void*, const grammar::CNF& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToAutomaton::Visit(void*, const grammar::GNF& ) const { + throw exception::AlibException("Unsupported grammar type GNF"); +} + +void ToAutomaton::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void ToAutomaton::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void ToAutomaton::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void ToAutomaton::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const ToAutomaton ToAutomaton::TO_AUTOMATON; + +} /* namespace convert */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/convert/ToAutomaton.h b/alib2algo/src/grammar/convert/ToAutomaton.h new file mode 100644 index 0000000000000000000000000000000000000000..aeea0edfbc22db86bffd7dabf90e228e9088455c --- /dev/null +++ b/alib2algo/src/grammar/convert/ToAutomaton.h @@ -0,0 +1,60 @@ +/* + * ToAutomaton.h + * + * Created on: 1. 11. 2013 + * Author: Tomas Pecka + */ + +#ifndef _GRAMMAR_TO_AUTOMATON_H_ +#define _GRAMMAR_TO_AUTOMATON_H_ + +#include <grammar/Grammar.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightRG.h> + +#include <automaton/Automaton.h> +#include <automaton/FSM/NFA.h> + +namespace grammar { + +namespace convert { + +/** + * Converts regular grammar to nondeterministic finite automaton. + * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA). + */ +class ToAutomaton : public grammar::VisitableGrammarBase::const_visitor_type { +public: + /** + * Performs conversion. + * @param grammar Regular grammar to convert. + * @return FSM equivalent to source grammar. + */ + static automaton::Automaton convert(const grammar::Grammar& grammar); + + static automaton::NFA convert(const grammar::LeftRG& grammar); + static automaton::NFA convert(const grammar::RightRG& grammar); + +private: + void Visit(void*, const grammar::RightRG& grammar) const; + void Visit(void*, const grammar::LeftRG& grammar) const; + void Visit(void*, const grammar::RightLG& grammar) const; + void Visit(void*, const grammar::LeftLG& 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 ToAutomaton TO_AUTOMATON; +}; + +} /* namespace convert */ + +} /* namespace grammar */ + +#endif /* _GRAMMAR_TO_AUTOMATON_H_ */ diff --git a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp similarity index 72% rename from alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp rename to alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp index 71bbf621fc4a4eed164601a6e0303c0b38db0645..e0eaa76cc0562710eb82fc113ee8680d30d336c3 100644 --- a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp +++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp @@ -1,30 +1,28 @@ /* - * RightToLeftRegularGrammar.cpp + * ToGrammarLeftRG.cpp * * Created on: 8. 3. 2014 * Author: Tomas Pecka */ -#include "RightToLeftRegularGrammar.h" +#include "ToGrammarLeftRG.h" #include <exception/AlibException.h> -namespace conversions -{ +namespace grammar { -namespace rg2rg -{ +namespace convert { -grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::Grammar& grammar) +grammar::LeftRG ToGrammarLeftRG::convert(const grammar::Grammar& grammar) { grammar::LeftRG* out = NULL; - grammar.getData().Accept((void*) &out, RightToLeftRegularGrammar::RIGHT_TO_LEFT_REGULAR_GRAMMAR); + grammar.getData().Accept((void*) &out, ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG); grammar::LeftRG res = std::move(*out); delete out; return res; } -grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& grammar) +grammar::LeftRG ToGrammarLeftRG::convert(const grammar::RightRG& grammar) { // 1. alphabet::Symbol s = alphabet::createUniqueSymbol( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); @@ -73,30 +71,30 @@ grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& gramm return lrg; } -void RightToLeftRegularGrammar::Visit(void* userData, const grammar::RightRG& grammar) const +void ToGrammarLeftRG::Visit(void* userData, const grammar::RightRG& grammar) const { grammar::LeftRG* & out = *((grammar::LeftRG**) userData); out = new grammar::LeftRG(this->convert(grammar)); } -void RightToLeftRegularGrammar::Visit(void*, const grammar::LeftRG&) const +void ToGrammarLeftRG::Visit(void*, const grammar::LeftRG&) const { throw exception::AlibException("Unsupported grammar type RightRG"); } -void RightToLeftRegularGrammar::Visit(void*, const grammar::RightLG&) const +void ToGrammarLeftRG::Visit(void*, const grammar::RightLG&) const { throw exception::AlibException("Unsupported grammar type RightLG"); } -void RightToLeftRegularGrammar::Visit(void*, const grammar::LeftLG&) const +void ToGrammarLeftRG::Visit(void*, const grammar::LeftLG&) const { throw exception::AlibException("Unsupported grammar type LeftLG"); } -const RightToLeftRegularGrammar RightToLeftRegularGrammar::RIGHT_TO_LEFT_REGULAR_GRAMMAR; +const ToGrammarLeftRG ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG; -} /* namespace rg2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace grammar */ diff --git a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h similarity index 67% rename from alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h rename to alib2algo/src/grammar/convert/ToGrammarLeftRG.h index a965dc3926751e910b2a6efe2749e59512b254fe..58648f091a7eb5a12177d5a430586a270cc6a96b 100644 --- a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h +++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h @@ -1,27 +1,25 @@ /* - * RightToLeftRegularGrammar.h + * ToGrammarLeftRG.h * * Created on: 8. 3. 2014 * Author: Tomas Pecka */ -#ifndef RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_ -#define RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_ +#ifndef TO_GRAMMAR_LEFT_RG_H_ +#define TO_GRAMMAR_LEFT_RG_H_ #include <grammar/Grammar.h> #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightRG.h> -namespace conversions -{ +namespace grammar { -namespace rg2rg -{ +namespace convert { /** * Converts right regular grammar to left regular grammar. */ -class RightToLeftRegularGrammar : public grammar::VisitableConstRGBase +class ToGrammarLeftRG : public grammar::VisitableConstRGBase { public: /** @@ -38,11 +36,11 @@ private: void Visit(void*, const grammar::RightLG& grammar) const; void Visit(void*, const grammar::LeftLG& grammar) const; - static const RightToLeftRegularGrammar RIGHT_TO_LEFT_REGULAR_GRAMMAR; + static const ToGrammarLeftRG TO_GRAMMAR_LEFT_RG; }; -} /* namespace rg2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace grammar */ -#endif /* RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_ */ +#endif /* TO_GRAMMAR_LEFT_RG_H_ */ diff --git a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp similarity index 72% rename from alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp rename to alib2algo/src/grammar/convert/ToGrammarRightRG.cpp index b784f0e5c03890be0b380aa067aeda5303706257..ae81d66fb1c4aa033c50964d9ecd8414199d9a24 100644 --- a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp +++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp @@ -1,28 +1,28 @@ /* - * LeftToRightRegularGrammar.cpp + * ToGrammarRightRG.cpp * * Created on: 8. 3. 2014 * Author: Tomas Pecka */ -#include "LeftToRightRegularGrammar.h" +#include "ToGrammarRightRG.h" #include <exception/AlibException.h> -namespace conversions { +namespace grammar { -namespace rg2rg { +namespace convert { -grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::Grammar& grammar) +grammar::RightRG ToGrammarRightRG::convert(const grammar::Grammar& grammar) { grammar::RightRG* out = NULL; - grammar.getData().Accept((void*) &out, LeftToRightRegularGrammar::LEFT_TO_RIGHT_REGULAR_GRAMMAR); + grammar.getData().Accept((void*) &out, ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG); grammar::RightRG res = std::move(*out); delete out; return res; } -grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& grammar) +grammar::RightRG ToGrammarRightRG::convert(const grammar::LeftRG& grammar) { // 1. alphabet::Symbol s = alphabet::createUniqueSymbol( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); @@ -71,29 +71,29 @@ grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& gramm return rrg; } -void LeftToRightRegularGrammar::Visit(void*, const grammar::RightRG&) const +void ToGrammarRightRG::Visit(void*, const grammar::RightRG&) const { throw exception::AlibException("Unsupported grammar type RightRG"); } -void LeftToRightRegularGrammar::Visit(void* userData, const grammar::LeftRG& grammar) const +void ToGrammarRightRG::Visit(void* userData, const grammar::LeftRG& grammar) const { grammar::RightRG* & out = *((grammar::RightRG**) userData); out = new grammar::RightRG(this->convert(grammar)); } -void LeftToRightRegularGrammar::Visit(void*, const grammar::RightLG&) const +void ToGrammarRightRG::Visit(void*, const grammar::RightLG&) const { throw exception::AlibException("Unsupported grammar type RightLG"); } -void LeftToRightRegularGrammar::Visit(void*, const grammar::LeftLG&) const +void ToGrammarRightRG::Visit(void*, const grammar::LeftLG&) const { throw exception::AlibException("Unsupported grammar type LeftLG"); } -const LeftToRightRegularGrammar LeftToRightRegularGrammar::LEFT_TO_RIGHT_REGULAR_GRAMMAR; +const ToGrammarRightRG ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG; -} /* namespace rg2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace grammar */ diff --git a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h b/alib2algo/src/grammar/convert/ToGrammarRightRG.h similarity index 67% rename from alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h rename to alib2algo/src/grammar/convert/ToGrammarRightRG.h index 350eef77aa296b3291b26245aed3e4399bd156c9..468b72aa3a8fac45598d0d68ce16fafce45ab5af 100644 --- a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h +++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.h @@ -1,26 +1,25 @@ /* - * LeftToRightRegularGrammar.h + * ToGrammarRightRG.h * * Created on: 8. 3. 2014 * Author: Tomas Pecka */ -#ifndef LEFT_TORIGHT_REGULAR_GRAMMAR_H_ -#define LEFT_TORIGHT_REGULAR_GRAMMAR_H_ +#ifndef TO_GRAMMAR_RIGHT_RG_H_ +#define TO_GRAMMAR_RIGHT_RG_H_ #include <grammar/Grammar.h> #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightRG.h> -namespace conversions{ +namespace grammar { -namespace rg2rg -{ +namespace convert { /** * Converts left regular grammar to right regular grammar. */ -class LeftToRightRegularGrammar : public grammar::VisitableConstRGBase +class ToGrammarRightRG : public grammar::VisitableConstRGBase { public: /** @@ -37,11 +36,11 @@ private: void Visit(void*, const grammar::RightLG& grammar) const; void Visit(void*, const grammar::LeftLG& grammar) const; - static const LeftToRightRegularGrammar LEFT_TO_RIGHT_REGULAR_GRAMMAR; + static const ToGrammarRightRG TO_GRAMMAR_RIGHT_RG; }; -} /* namespace rg2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace grammar */ -#endif /* LEFT_TO_RIGHT_REGULAR_GRAMMAR_H_ */ +#endif /* TO_GRAMMAR_RIGHT_RG_H_ */ diff --git a/alib2algo/src/grammar/convert/ToRegExp.cpp b/alib2algo/src/grammar/convert/ToRegExp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe2696f7f470e2e5c5dd274ab6bd0b2e437d3339 --- /dev/null +++ b/alib2algo/src/grammar/convert/ToRegExp.cpp @@ -0,0 +1,87 @@ +/* + * ToRegExp.cpp + * + * Created on: 4. 3. 2014 + * Author: Tomas Pecka + */ + +#include "ToRegExp.h" +#include "ToRegExpAlgebraic.h" +#include <exception/AlibException.h> + +namespace grammar { + +namespace convert { + +regexp::RegExp ToRegExp::convert(const grammar::Grammar& grammar) +{ + regexp::RegExp* out = NULL; + grammar.getData().Accept((void*) &out, ToRegExp::TO_REG_EXP); + regexp::RegExp res = std::move(*out); + delete out; + return res; +} + +void ToRegExp::Visit(void* userData, const grammar::RightRG& grammar) const +{ + regexp::RegExp* & out = *((regexp::RegExp**) userData); + out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar)); +} + +void ToRegExp::Visit(void* userData, const grammar::LeftRG& grammar) const +{ + regexp::RegExp* & out = *((regexp::RegExp**) userData); + out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar)); +} + +void ToRegExp::Visit(void*, const grammar::RightLG&) const +{ + throw exception::AlibException("Unsupported grammar type RightLG"); +} + +void ToRegExp::Visit(void*, const grammar::LeftLG&) const +{ + throw exception::AlibException("Unsupported grammar type LeftLG"); +} + +void ToRegExp::Visit(void*, const grammar::LG& ) const { + throw exception::AlibException("Unsupported grammar type LG"); +} + +void ToRegExp::Visit(void*, const grammar::CFG& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToRegExp::Visit(void*, const grammar::EpsilonFreeCFG& ) const { + throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG"); +} + +void ToRegExp::Visit(void*, const grammar::CNF& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToRegExp::Visit(void*, const grammar::GNF& ) const { + throw exception::AlibException("Unsupported grammar type GNF"); +} + +void ToRegExp::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void ToRegExp::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void ToRegExp::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void ToRegExp::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const ToRegExp ToRegExp::TO_REG_EXP; + +} /* namespace convert */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/convert/ToRegExp.h b/alib2algo/src/grammar/convert/ToRegExp.h new file mode 100644 index 0000000000000000000000000000000000000000..aace07b45d5fbccc3876959de1977eed6b8900ba --- /dev/null +++ b/alib2algo/src/grammar/convert/ToRegExp.h @@ -0,0 +1,52 @@ +/* + * ToRegExp.h + * + * Created on: 4. 3. 2014 + * Author: Jan Travnicek + */ + +#ifndef GRAMMAR_TO_REG_EXP_H_ +#define GRAMMAR_TO_REG_EXP_H_ + +#include <grammar/Grammar.h> +#include <grammar/Regular/RightRG.h> +#include <grammar/Regular/LeftRG.h> + +#include <regexp/RegExp.h> + +namespace grammar { + +namespace convert { + +class ToRegExp : public grammar::VisitableConstRGBase +{ +public: + /** + * @return regexp equivalent to source right regular grammar. + * @param grammar Grammar to convert + */ + static regexp::RegExp convert(const grammar::Grammar& grammar); + +protected: + void Visit(void*, const grammar::RightRG& grammar) const; + void Visit(void*, const grammar::LeftRG& grammar) const; + void Visit(void*, const grammar::RightLG& grammar) const; + void Visit(void*, const grammar::LeftLG& 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 ToRegExp TO_REG_EXP; +}; + +} /* namespace covert */ + +} /* namespace grammar */ + +#endif /* GRAMMAR_TO_REG_EXP_H_ */ diff --git a/alib2algo/src/conversions/rg2re/Algebraic.cpp b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp similarity index 77% rename from alib2algo/src/conversions/rg2re/Algebraic.cpp rename to alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp index cdef84a2159881e4153bc58198207787efdb4982..5deb9296f085beec26595d62bf97aa986aac94c4 100644 --- a/alib2algo/src/conversions/rg2re/Algebraic.cpp +++ b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp @@ -1,11 +1,11 @@ /* - * Algebraic.cpp + * ToRegExpAlgebraic.cpp * * Created on: 4. 3. 2014 * Author: Tomas Pecka */ -#include "Algebraic.h" +#include "ToRegExpAlgebraic.h" #include "../../equations/LeftRegularEquationSolver.h" #include "../../equations/RightRegularEquationSolver.h" @@ -13,22 +13,20 @@ #include <exception/AlibException.h> #include <regexp/unbounded/UnboundedRegExpElements.h> -namespace conversions -{ +namespace grammar { -namespace rg2re -{ +namespace convert { -regexp::RegExp Algebraic::convert(const grammar::Grammar& grammar) +regexp::RegExp ToRegExpAlgebraic::convert(const grammar::Grammar& grammar) { regexp::RegExp* out = NULL; - grammar.getData().Accept((void*) &out, Algebraic::RG_TO_RE_ALGEBRAIC); + grammar.getData().Accept((void*) &out, ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC); regexp::RegExp res = std::move(*out); delete out; return res; } -regexp::RegExp Algebraic::convert(const grammar::LeftRG& grammar) +regexp::RegExp ToRegExpAlgebraic::convert(const grammar::LeftRG& grammar) { equations::LeftRegularEquationSolver solver; @@ -58,7 +56,7 @@ regexp::RegExp Algebraic::convert(const grammar::LeftRG& grammar) return regexp::RegExp{solver.solve(grammar.getInitialSymbol())}; } -regexp::RegExp Algebraic::convert(const grammar::RightRG& grammar) +regexp::RegExp ToRegExpAlgebraic::convert(const grammar::RightRG& grammar) { equations::RightRegularEquationSolver solver; @@ -89,30 +87,30 @@ regexp::RegExp Algebraic::convert(const grammar::RightRG& grammar) return regexp::RegExp{solver.solve(grammar.getInitialSymbol())}; } -void Algebraic::Visit(void* userData, const grammar::RightRG& grammar) const +void ToRegExpAlgebraic::Visit(void* userData, const grammar::RightRG& grammar) const { regexp::RegExp* & out = *((regexp::RegExp**) userData); out = new regexp::RegExp(this->convert(grammar)); } -void Algebraic::Visit(void* userData, const grammar::LeftRG& grammar) const +void ToRegExpAlgebraic::Visit(void* userData, const grammar::LeftRG& grammar) const { regexp::RegExp* & out = *((regexp::RegExp**) userData); out = new regexp::RegExp(this->convert(grammar)); } -void Algebraic::Visit(void*, const grammar::RightLG&) const +void ToRegExpAlgebraic::Visit(void*, const grammar::RightLG&) const { throw exception::AlibException("Unsupported grammar type RightLG"); } -void Algebraic::Visit(void*, const grammar::LeftLG&) const +void ToRegExpAlgebraic::Visit(void*, const grammar::LeftLG&) const { throw exception::AlibException("Unsupported grammar type LeftLG"); } -const Algebraic Algebraic::RG_TO_RE_ALGEBRAIC; +const ToRegExpAlgebraic ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC; -} /* namespace rg2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace grammar */ diff --git a/alib2algo/src/conversions/rg2re/Algebraic.h b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.h similarity index 69% rename from alib2algo/src/conversions/rg2re/Algebraic.h rename to alib2algo/src/grammar/convert/ToRegExpAlgebraic.h index bd4741d891fc06927fcda73a3a6b229978bc165f..3370fc3dfd51c874edf9cefb109710e21294ab74 100644 --- a/alib2algo/src/conversions/rg2re/Algebraic.h +++ b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.h @@ -1,12 +1,12 @@ /* - * Algebraic.h + * ToRegExpAlgebraic.h * * Created on: 4. 3. 2014 * Author: Tomas Pecka */ -#ifndef RG2RE_ALGEBRAIC_H_ -#define RG2RE_ALGEBRAIC_H_ +#ifndef GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_ +#define GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_ #include <grammar/Grammar.h> #include <grammar/Regular/RightRG.h> @@ -14,13 +14,11 @@ #include <regexp/RegExp.h> -namespace conversions -{ +namespace grammar { -namespace rg2re -{ +namespace convert { -class Algebraic : public grammar::VisitableConstRGBase +class ToRegExpAlgebraic : public grammar::VisitableConstRGBase { public: /** @@ -38,11 +36,11 @@ protected: void Visit(void*, const grammar::RightLG& grammar) const; void Visit(void*, const grammar::LeftLG& grammar) const; - static const Algebraic RG_TO_RE_ALGEBRAIC; + static const ToRegExpAlgebraic TO_REG_EXP_ALGEBRAIC; }; -} /* namespace rg2re */ +} /* namespace covert */ -} /* namespace conversions */ +} /* namespace grammar */ -#endif /* RG2RE_ALGEBRAIC_H_ */ +#endif /* GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_ */ diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05d5808b08149ce611ada0968a2e3cd19622057b --- /dev/null +++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp @@ -0,0 +1,46 @@ +/* + * IsLanguageEmpty.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 <std/set.hpp> + +#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( ) ); +} + +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CFG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::GNF & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CNF & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftLG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftRG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightLG & grammar ); +template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightRG & grammar ); + +} /* namespace properties */ + +} /* namespace grammar */ + diff --git a/alib2algo/src/language/grammar/LanguagePropertiesCFG.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h similarity index 68% rename from alib2algo/src/language/grammar/LanguagePropertiesCFG.h rename to alib2algo/src/grammar/properties/IsLanguageEmpty.h index 5029d5be546d403d6382d25f6b89512955ed1075..8aa3a2e13571e57acb11635b84c3ef7760539d5e 100644 --- a/alib2algo/src/language/grammar/LanguagePropertiesCFG.h +++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h @@ -1,12 +1,12 @@ /* - * LanguagePropertiesCFG.h + * IsLanguageEmpty.h * * Created on: 22. 3. 2014 * Author: Tomas Pecka */ -#ifndef LANGUAGE_PROPERTIED_CFG_H_ -#define LANGUAGE_PROPERTIED_CFG_H_ +#ifndef IS_LANGUAGE_EMPTY_H_ +#define IS_LANGUAGE_EMPTY_H_ #include <algorithm> #include <deque> @@ -16,12 +16,14 @@ #include <alphabet/Symbol.h> -namespace language { +namespace grammar { + +namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class LanguagePropertiesCFG { +class IsLanguageEmpty { public: /* * Melichar 3.6 - decides whether L( grammar ) = \0 @@ -33,6 +35,8 @@ public: static bool isLanguageEmpty( const T & grammar ); }; -} +} /* namespace properties */ + +} /* namespace grammar */ -#endif /* LANGUAGE_PROPERTIED_CFG_H_ */ +#endif /* IS_LANGUAGE_EMPTY_H_ */ diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a4fbdd79ae93ac25e67a69d80638b49bb8cb4a7 --- /dev/null +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp @@ -0,0 +1,69 @@ +/* + * NonterminalUnitRuleCycle.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 <std/set.hpp> + +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::AlibException("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); +} + +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal); +template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal); + +} /* namespace properties */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h new file mode 100644 index 0000000000000000000000000000000000000000..2bfd991526c5a8844ff84ce607e69e3aac43f4e4 --- /dev/null +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h @@ -0,0 +1,45 @@ +/* + * NonterminalUnitRuleCycle.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_ +#define NONTERMINAL_UNIT_RULE_CYCLE_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> + +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace properties { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class NonterminalUnitRuleCycle { +public: + /** + * Retrieves set N = {B : A->^* B} for given grammar and nonterminal + * + * Source: Melichar, algorithm 2.6, step 1 + * + * @param grammar grammar + * @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); +}; + +} /* namespace properties */ + +} /* namespace grammar */ + +#endif /* NONTERMINAL_UNIT_RULE_CYCLE_H_ */ diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f61bf0b691d641f468f5861ca8199e85089be365 --- /dev/null +++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp @@ -0,0 +1,64 @@ +/* + * NullableNonterminals.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 <std/set.hpp> + +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); +} + +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CFG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::GNF& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CNF& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftLG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftRG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightLG& grammar ); +template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightRG& grammar ); + +} /* namespace properties */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h new file mode 100644 index 0000000000000000000000000000000000000000..c80c3b9bf83f4b43dd8db91c5cdd6759dd71d623 --- /dev/null +++ b/alib2algo/src/grammar/properties/NullableNonterminals.h @@ -0,0 +1,45 @@ +/* + * NullableNonterminals.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef NULLABLE_NONTERMINALS_H_ +#define NULLABLE_NONTERMINALS_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> + +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace properties { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class NullableNonterminals { +public: + /** + * Retrieve all nullable nonterminals from grammar + * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps + * + * Source: Melichar, algorithm 2.4, step 1 + * + * @param grammar grammar + * @return set of nullable nonterminals from grammar + */ + template<class T> + static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar); +}; + +} /* namespace properties */ + +} /* namespace grammar */ + +#endif /* NULLABLE_NONTERMINALS_H_ */ diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63e33cdb9ef352382d9daf3cb97737565d2c28c9 --- /dev/null +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp @@ -0,0 +1,69 @@ +/* + * ProductiveNonterminals.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 <std/set.hpp> + +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 ); +} + +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CFG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::GNF & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CNF & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftLG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftRG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar ); +template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar ); + +} /* namespace properties */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h new file mode 100644 index 0000000000000000000000000000000000000000..6139ad94085beb92027ab12dc8d84c4c4c1cca0a --- /dev/null +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h @@ -0,0 +1,40 @@ +/* + * GrammarPropertiesCFG.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef PRODUCTIVE_NONTERMINALS_H_ +#define PRODUCTIVE_NONTERMINALS_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> + +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace properties { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class ProductiveNonterminals { +public: + /** + * Implements steps 1 through 3 in Melichar 3.6 + */ + template<class T> + static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar ); + +}; + +} /* namespace properties */ + +} /* namespace grammar */ + +#endif /* PRODUCTIVE_NONTERMINALS_H_ */ diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2347f08ac4a42a3ce987b98d41fb20139fc18da6 --- /dev/null +++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp @@ -0,0 +1,70 @@ +/* + * UnreachableSymbols.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 <std/set.hpp> + +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 ); +} + +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CFG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::GNF & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CNF & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftLG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftRG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightLG & grammar ); +template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightRG & grammar ); + +} /* namespace properties */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h new file mode 100644 index 0000000000000000000000000000000000000000..d64351b858799a05f10ae70a546559be5572f87f --- /dev/null +++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h @@ -0,0 +1,40 @@ +/* + * UnreachableSymbols.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef UNREACHABLE_SYMBOLS_H_ +#define UNREACHABLE_SYMBOLS_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> + +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace properties { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class UnreachableSymbols { +public: + /** + * Implements + */ + template<class T> + static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar ); + +}; + +} /* namespace properties */ + +} /* namespace grammar */ + +#endif /* UNREACHABLE_SYMBOLS_H_ */ diff --git a/alib2algo/src/grammar/simplify/Trim.cpp b/alib2algo/src/grammar/simplify/Trim.cpp new file mode 100644 index 0000000000000000000000000000000000000000..862cbbc62179fa8943660673286d621937386974 --- /dev/null +++ b/alib2algo/src/grammar/simplify/Trim.cpp @@ -0,0 +1,118 @@ +/* + * Trim.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#include "Trim.h" + +#include <grammar/ContextFree/CFG.h> +#include <grammar/ContextFree/EpsilonFreeCFG.h> +#include <grammar/ContextFree/GNF.h> +#include <grammar/ContextFree/CNF.h> +#include <grammar/ContextFree/LG.h> +#include <grammar/Regular/LeftLG.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> + +#include <std/set.hpp> + +#include "UnreachableSymbolsRemover.h" +#include "UnproductiveSymbolsRemover.h" + +namespace grammar { + +namespace simplify { + +template<class T> +T Trim::trim( const T & grammar ) { + return grammar::simplify::UnreachableSymbolsRemover::remove( grammar::simplify::UnproductiveSymbolsRemover::remove( grammar ) ); +} + +template grammar::CFG Trim::trim( const grammar::CFG & grammar ); +template grammar::EpsilonFreeCFG Trim::trim( const grammar::EpsilonFreeCFG & grammar ); +template grammar::GNF Trim::trim( const grammar::GNF & grammar ); +template grammar::CNF Trim::trim( const grammar::CNF & grammar ); +template grammar::LG Trim::trim( const grammar::LG & grammar ); +template grammar::LeftLG Trim::trim( const grammar::LeftLG & grammar ); +template grammar::LeftRG Trim::trim( const grammar::LeftRG & grammar ); +template grammar::RightLG Trim::trim( const grammar::RightLG & grammar ); +template grammar::RightRG Trim::trim( const grammar::RightRG & grammar ); + +grammar::Grammar Trim::trim(const grammar::Grammar& grammar) { + grammar::Grammar* out = NULL; + grammar.getData().Accept((void*) &out, Trim::TRIM); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void Trim::Visit(void* data, const grammar::LeftLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::LeftRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::RightLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::RightRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::LG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::CFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::CNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void* data, const grammar::GNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->trim(grammar)); +} + +void Trim::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void Trim::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void Trim::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void Trim::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const Trim Trim::TRIM; + +} /* namespace simplify */ + +} /* namespace grammar */ + diff --git a/alib2algo/src/grammar/simplify/Trim.h b/alib2algo/src/grammar/simplify/Trim.h new file mode 100644 index 0000000000000000000000000000000000000000..30b78b8365f733ffdcb377c162789ec2b34c2078 --- /dev/null +++ b/alib2algo/src/grammar/simplify/Trim.h @@ -0,0 +1,58 @@ +/* + * Trim.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#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 { + +namespace simplify { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class Trim : public grammar::VisitableGrammarBase::const_visitor_type { +public: + static grammar::Grammar trim( const grammar::Grammar & automaton ); + + /** + * Removes unproductive and useless symbols - Melichar 3.12 + */ + template<class T> + static T trim( 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 Trim TRIM; +}; + +} /* namespace simplify */ + +} /* namespace grammar */ + +#endif /* GRAMMAR_TRIM_H_ */ diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43d2044ab0db60b6d023888d18b7be9bbeb21233 --- /dev/null +++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp @@ -0,0 +1,145 @@ +/* + * UnproductiveSymbolsRemover.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#include "UnproductiveSymbolsRemover.h" + +#include <grammar/ContextFree/CFG.h> +#include <grammar/ContextFree/EpsilonFreeCFG.h> +#include <grammar/ContextFree/GNF.h> +#include <grammar/ContextFree/CNF.h> +#include <grammar/ContextFree/LG.h> +#include <grammar/Regular/LeftLG.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> + +#include <std/set.hpp> + +#include "../properties/ProductiveNonterminals.h" + +namespace grammar { + +namespace simplify { + +template<class T> +T UnproductiveSymbolsRemover::remove( const T & grammar ) { + // 1. + std::set<alphabet::Symbol> Nt = grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ); + + T ret(grammar.getInitialSymbol( ) ); + + for( const auto & symbol : Nt ) + ret.addNonterminalSymbol( symbol ); + + for( const auto & symbol : grammar.getTerminalAlphabet( ) ) + ret.addTerminalSymbol( symbol ); + + const std::set<alphabet::Symbol> & terminals = ret.getTerminalAlphabet( ); + for( const auto & rule : grammar.getRawRules( ) ) { + if( Nt.count( rule.first ) ) { + for( const auto & rhs : rule.second ) { + if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const alphabet::Symbol & symbol ) { + return Nt.count( symbol ) || terminals.count( symbol ); + } ) ) + ret.addRawRule( rule.first, rhs ); + } + } + } + + + /* if( ! G1.getNonTerminalSymbols( ) . count( grammar.getInitialSymbol( ) ) ) + throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." ); */ + + // 2. + return ret; +} + +template grammar::CFG UnproductiveSymbolsRemover::remove( const grammar::CFG & grammar ); +template grammar::EpsilonFreeCFG UnproductiveSymbolsRemover::remove( const grammar::EpsilonFreeCFG & grammar ); +template grammar::GNF UnproductiveSymbolsRemover::remove( const grammar::GNF & grammar ); +template grammar::CNF UnproductiveSymbolsRemover::remove( const grammar::CNF & grammar ); +template grammar::LG UnproductiveSymbolsRemover::remove( const grammar::LG & grammar ); +template grammar::LeftLG UnproductiveSymbolsRemover::remove( const grammar::LeftLG & grammar ); +template grammar::LeftRG UnproductiveSymbolsRemover::remove( const grammar::LeftRG & grammar ); +template grammar::RightLG UnproductiveSymbolsRemover::remove( const grammar::RightLG & grammar ); +template grammar::RightRG UnproductiveSymbolsRemover::remove( const grammar::RightRG & grammar ); + +grammar::Grammar UnproductiveSymbolsRemover::remove(const grammar::Grammar& grammar) { + grammar::Grammar* out = NULL; + grammar.getData().Accept((void*) &out, UnproductiveSymbolsRemover::UNPRODUCTIVE_SYMBOLS_REMOVER); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LeftLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LeftRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::RightLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::RightRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::CFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::CNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void* data, const grammar::GNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnproductiveSymbolsRemover::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void UnproductiveSymbolsRemover::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void UnproductiveSymbolsRemover::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void UnproductiveSymbolsRemover::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const UnproductiveSymbolsRemover UnproductiveSymbolsRemover::UNPRODUCTIVE_SYMBOLS_REMOVER; + +} /* namespace simplify */ + +} /* namespace grammar */ + diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h new file mode 100644 index 0000000000000000000000000000000000000000..de8a17830edf1f3a94a4910f9247c3bfc978ebcf --- /dev/null +++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h @@ -0,0 +1,58 @@ +/* + * UnproductiveSymbolsRemover.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef UNPRODUCTIVE_SYMBOLS_REMOVER_H_ +#define UNPRODUCTIVE_SYMBOLS_REMOVER_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> +#include <grammar/Grammar.h> +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace simplify { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class UnproductiveSymbolsRemover : public grammar::VisitableGrammarBase::const_visitor_type { +public: + static grammar::Grammar remove( const grammar::Grammar & automaton ); + + /** + * Removes unproductive (or useless - terminology) symbols - Melichar 3.12 + */ + template<class T> + static T remove( 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 UnproductiveSymbolsRemover UNPRODUCTIVE_SYMBOLS_REMOVER; +}; + +} /* namespace simplify */ + +} /* namespace grammar */ + +#endif /* UNPRODUCTIVE_SYMBOLS_REMOVER_H_ */ diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp new file mode 100644 index 0000000000000000000000000000000000000000..627d6d469f2d2f2d3173175fcfd041584234929d --- /dev/null +++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp @@ -0,0 +1,145 @@ +/* + * UnreachableSymbolsRemover.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#include "UnreachableSymbolsRemover.h" + +#include <grammar/ContextFree/CFG.h> +#include <grammar/ContextFree/EpsilonFreeCFG.h> +#include <grammar/ContextFree/GNF.h> +#include <grammar/ContextFree/CNF.h> +#include <grammar/ContextFree/LG.h> +#include <grammar/Regular/LeftLG.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> + +#include <std/set.hpp> + +#include "../properties/UnreachableSymbols.h" + +namespace grammar { + +namespace simplify { + +template<class T> +T UnreachableSymbolsRemover::remove( const T & grammar) { + // 1. + std::set<alphabet::Symbol> Vt = grammar::properties::UnreachableSymbols::getUnreachableSymbols( grammar ); + + T ret(grammar.getInitialSymbol( ) ); + + std::set<alphabet::Symbol> newNonTerminals, newTerminals; + + set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) ); + for( const auto & symbol : newNonTerminals ) + ret.addNonterminalSymbol( symbol ); + + set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) ); + for( const auto & symbol : newTerminals ) + ret.addTerminalSymbol( symbol ); + + // A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P + for( const auto & rule : grammar.getRawRules( ) ) { + if( newNonTerminals.count( rule.first ) ) { + for( const auto& rhs : rule.second ) { + if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( alphabet::Symbol const& symb ) -> bool { + return Vt.count( symb ); + } ) ) + ret.addRawRule( rule.first, rhs ); + } + } + } + + // 2. + return ret; +} + +template grammar::CFG UnreachableSymbolsRemover::remove( const grammar::CFG & grammar ); +template grammar::EpsilonFreeCFG UnreachableSymbolsRemover::remove( const grammar::EpsilonFreeCFG & grammar ); +template grammar::GNF UnreachableSymbolsRemover::remove( const grammar::GNF & grammar ); +template grammar::CNF UnreachableSymbolsRemover::remove( const grammar::CNF & grammar ); +template grammar::LG UnreachableSymbolsRemover::remove( const grammar::LG & grammar ); +template grammar::LeftLG UnreachableSymbolsRemover::remove( const grammar::LeftLG & grammar ); +template grammar::LeftRG UnreachableSymbolsRemover::remove( const grammar::LeftRG & grammar ); +template grammar::RightLG UnreachableSymbolsRemover::remove( const grammar::RightLG & grammar ); +template grammar::RightRG UnreachableSymbolsRemover::remove( const grammar::RightRG & grammar ); + +grammar::Grammar UnreachableSymbolsRemover::remove(const grammar::Grammar& grammar) { + grammar::Grammar* out = NULL; + grammar.getData().Accept((void*) &out, UnreachableSymbolsRemover::UNREACHABLE_SYMBOLS_REMOVER); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::LeftLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::LeftRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::RightLG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::RightRG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::LG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::CFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::CNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void* data, const grammar::GNF& grammar) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(this->remove(grammar)); +} + +void UnreachableSymbolsRemover::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void UnreachableSymbolsRemover::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void UnreachableSymbolsRemover::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void UnreachableSymbolsRemover::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const UnreachableSymbolsRemover UnreachableSymbolsRemover::UNREACHABLE_SYMBOLS_REMOVER; + +} /* namespace simplify */ + +} /* namespace grammar */ + diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h new file mode 100644 index 0000000000000000000000000000000000000000..1144d510cc1d3c5f7bd30364e921bd8d45f15926 --- /dev/null +++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h @@ -0,0 +1,58 @@ +/* + * UnreachableSymbolsRemover.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef UNREACHABLE_SYMBOLS_REMOVER_H_ +#define UNREACHABLE_SYMBOLS_REMOVER_H_ + +#include <algorithm> +#include <deque> +#include <set> + +#include <exception/AlibException.h> +#include <grammar/Grammar.h> +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace simplify { + +/** + * Implements algorithms from Melichar, chapter 3.3 + */ +class UnreachableSymbolsRemover : public grammar::VisitableGrammarBase::const_visitor_type { +public: + static grammar::Grammar remove( const grammar::Grammar & automaton ); + + /* + * Removes unreachable symbols - Melichar 3.9 + */ + template<class T> + static T remove( 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 UnreachableSymbolsRemover UNREACHABLE_SYMBOLS_REMOVER; +}; + +} /* namespace simplify */ + +} /* namespace grammar */ + +#endif /* UNREACHABLE_SYMBOLS_REMOVER_H_ */ diff --git a/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp b/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp deleted file mode 100644 index 23070a8688d488286b684b16e81759c446341be5..0000000000000000000000000000000000000000 --- a/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * LanguagePropertiesCFG.cpp - * - * Created on: 22. 3. 2014 - * Author: Tomas Pecka - */ - -#include "LanguagePropertiesCFG.h" - -#include <grammar/ContextFree/CFG.h> -#include <grammar/ContextFree/EpsilonFreeCFG.h> -#include <grammar/ContextFree/GNF.h> -#include <grammar/ContextFree/CNF.h> -#include <grammar/ContextFree/LG.h> -#include <grammar/Regular/LeftLG.h> -#include <grammar/Regular/LeftRG.h> -#include <grammar/Regular/RightLG.h> -#include <grammar/Regular/RightRG.h> - -#include <std/set.hpp> - -#include "../../grammar/GrammarPropertiesCFG.h" - -namespace language { - -template<class T> -bool LanguagePropertiesCFG::isLanguageEmpty( const T & grammar ) { - return grammar::GrammarPropertiesCFG::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) ); -} - -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::CFG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::GNF & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::CNF & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LeftLG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LeftRG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::RightLG & grammar ); -template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::RightRG & grammar ); - -} - diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.h b/alib2algo/src/normalize/dfa/NormalizeDFA.h deleted file mode 100644 index 9980cbad5bc957de97a94e19e2fbc6ac946e8f72..0000000000000000000000000000000000000000 --- a/alib2algo/src/normalize/dfa/NormalizeDFA.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * NormalizeDFA.h - * - * Created on: Dec 9, 2013 - * Author: Jan Travnicek - */ - -#ifndef NORMALIZE_DFA_H_ -#define NORMALIZE_DFA_H_ - -#include "automaton/FSM/DFA.h" - -namespace normalize { - -class NormalizeDFA { -public: - static automaton::DFA normalize(automaton::DFA& dfa); - -}; - -} - -#endif /* NORMALIZE_DFA_H_ */ diff --git a/alib2algo/src/regexp/GlushkovTraversal.cpp b/alib2algo/src/regexp/GlushkovTraversal.cpp index 0069f0bf75313d1a4e60f1cd90423f3c122ff5de..b622ed1a01b315c4cd03eac7e3ade2fd37d101bb 100644 --- a/alib2algo/src/regexp/GlushkovTraversal.cpp +++ b/alib2algo/src/regexp/GlushkovTraversal.cpp @@ -7,7 +7,7 @@ #include "GlushkovTraversal.h" -#include "RegExpEpsilon.h" +#include "properties/RegExpEpsilon.h" using namespace alib; using namespace regexp; @@ -112,7 +112,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::first( regexp::Unb tmp = first( element ); ret.insert( tmp.begin( ), tmp.end( ) ); - if(! regexp::RegExpEpsilon::languageContainsEpsilon(*element)) // If regexp of this subtree can match epsilon, then we need to add next subtree + if(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(*element)) // If regexp of this subtree can match epsilon, then we need to add next subtree break; } @@ -188,7 +188,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::last( regexp::Unbo tmp = last( *it ); ret.insert( tmp.begin( ), tmp.end( ) ); - if( ! regexp::RegExpEpsilon::languageContainsEpsilon(**it) ) + if( ! regexp::properties::RegExpEpsilon::languageContainsEpsilon(**it) ) break; } @@ -276,7 +276,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::follow( regexp::Un tmp = first( *f ); ret.insert( tmp.begin( ), tmp.end( ) ); - if( ! regexp::RegExpEpsilon::languageContainsEpsilon( **f ) ) + if( ! regexp::properties::RegExpEpsilon::languageContainsEpsilon( **f ) ) break; } } diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..781ecccc3f25eb9e53b5d00c0116e2ec24d2fd28 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp @@ -0,0 +1,40 @@ +/* + * ToAutomaton.cpp + * + * Created on: 11. 1. 2014 + * Author: Jan Travnicek + */ + +#include "ToAutomaton.h" +#include "ToAutomatonGlushkov.h" +#include <exception/AlibException.h> + +namespace regexp { + +namespace convert { + +automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp) +{ + automaton::Automaton* out = NULL; + regexp.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +void ToAutomaton::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + automaton::Automaton* &out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp)); +} +void ToAutomaton::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + automaton::Automaton* &out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp)); +} + +const ToAutomaton ToAutomaton::TO_AUTOMATON; + +} /* namespace convert */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h new file mode 100644 index 0000000000000000000000000000000000000000..9894aff99762f91750c1da349f7353fea6b0e4e0 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToAutomaton.h @@ -0,0 +1,42 @@ +/* + * RegExpToAutomaton.h + * + * Created on: 11. 1. 2014 + * Author: Tomas Pecka + */ + +#ifndef REG_EXP_TO_AUTOMATON_H_ +#define REG_EXP_TO_AUTOMATON_H_ + +#include <regexp/RegExp.h> +#include <regexp/formal/FormalRegExp.h> +#include <regexp/unbounded/UnboundedRegExp.h> + +#include <automaton/Automaton.h> +#include <automaton/FSM/NFA.h> + +namespace regexp { + +namespace convert { + +class ToAutomaton : public regexp::VisitableRegExpBase::const_visitor_type +{ +public: + /** + * Performs conversion. + * @return FSM equivalent to original regular expression. + */ + static automaton::Automaton convert(const regexp::RegExp& regexp); + +private: + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + + static const ToAutomaton TO_AUTOMATON; +}; + +} /* namespace convert */ + +} /* namespace regexp */ + +#endif /* REG_EXP_TO_AUTOMATON_H_ */ diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp similarity index 64% rename from alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp rename to alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp index 4916c8e363c1e150ae8c3401d588ea1f8e5e00fa..b6fe2135bd87a144d4b0bad8c806c7ce8382111c 100644 --- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp @@ -1,11 +1,11 @@ /* - * BrzozowskiDerivation.cpp + * ToAutomatonDerivation.cpp * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#include "BrzozowskiDerivation.h" +#include "ToAutomatonDerivation.h" #include <set> #include <deque> @@ -15,31 +15,28 @@ #include <string/LinearString.h> #include <std/hexavigesimal.h> -#include "../../regexp/RegExpDerivation.h" -#include "../../regexp/RegExpOptimize.h" -#include "../../regexp/RegExpEpsilon.h" +#include "../transform/RegExpDerivation.h" +#include "../simplify/RegExpOptimize.h" +#include "../properties/RegExpEpsilon.h" -namespace conversions -{ +namespace regexp { -namespace re2fa -{ +namespace convert { -automaton::Automaton BrzozowskiDerivation::convert(const regexp::RegExp& regexp) +automaton::Automaton ToAutomatonDerivation::convert(const regexp::RegExp& regexp) { automaton::Automaton* out = NULL; - regexp.getData().Accept((void*) &out, BrzozowskiDerivation::BRZOZOWSKI_DERIVATION); + regexp.getData().Accept((void*) &out, ToAutomatonDerivation::TO_AUTOMATON_DERIVATION); automaton::Automaton res = std::move(*out); delete out; return res; } template<class T> -automaton::NFA BrzozowskiDerivation::convert(const T& regexp) +automaton::NFA ToAutomatonDerivation::convert(const T& regexp) { // 1. - regexp::RegExpOptimize opt; - regexp::RegExp V = regexp::RegExp{regexp::RegExpOptimize::optimize(regexp)}; + regexp::RegExp V = regexp::RegExp{regexp::simplify::RegExpOptimize::optimize(regexp)}; std::set<regexp::RegExp> Q = { V }; std::deque<std::set<regexp::RegExp>> Qi; @@ -62,7 +59,7 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp) { string::LinearString string(std::vector<alphabet::Symbol>{a}); regexp::RegExp derived = deriv.derivation(dregexp, string); - derived = regexp::RegExpOptimize::optimize(derived); + derived = regexp::simplify::RegExpOptimize::optimize(derived); // this will also add \emptyset as a regexp (and as FA state) if(Q.count(derived) == 0) // if this state has already been found, do not add @@ -103,7 +100,7 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp) { string::LinearString string(std::vector<alphabet::Symbol>{a}); regexp::RegExp derived = deriv.derivation(r, string); - derived = regexp::RegExpOptimize::optimize(derived); + derived = regexp::simplify::RegExpOptimize::optimize(derived); automaton.addTransition(stateMap.find(r)->second, a, stateMap.find(derived)->second); } @@ -111,29 +108,29 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp) for(const auto& r : Q) { - if(regexp::RegExpEpsilon::languageContainsEpsilon(r)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(r)) automaton.addFinalState(stateMap.find(r)->second); } return automaton; } -template automaton::NFA BrzozowskiDerivation::convert(const regexp::FormalRegExp& regexp); -template automaton::NFA BrzozowskiDerivation::convert(const regexp::UnboundedRegExp& regexp); +template automaton::NFA ToAutomatonDerivation::convert(const regexp::FormalRegExp& regexp); +template automaton::NFA ToAutomatonDerivation::convert(const regexp::UnboundedRegExp& regexp); -void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const +void ToAutomatonDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const { automaton::Automaton* &out = *((automaton::Automaton**) userData); out = new automaton::Automaton(this->convert(regexp)); } -void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +void ToAutomatonDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { automaton::Automaton* &out = *((automaton::Automaton**) userData); out = new automaton::Automaton(this->convert(regexp)); } -const BrzozowskiDerivation BrzozowskiDerivation::BRZOZOWSKI_DERIVATION; +const ToAutomatonDerivation ToAutomatonDerivation::TO_AUTOMATON_DERIVATION; -} /* namespace re2fa */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h similarity index 67% rename from alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h rename to alib2algo/src/regexp/convert/ToAutomatonDerivation.h index a3c249dfe7ab5465b2547b4100af12c1139a50f6..7b26ff65f4d23332521b1e7e02b05748d756bf71 100644 --- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h +++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h @@ -1,12 +1,12 @@ /* - * BrzozowskiDerivation.h + * ToAutomatonDerivation.h * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#ifndef RE2FA_BRZOZOWSKIDERIVATION_H_ -#define RE2FA_BRZOZOWSKIDERIVATION_H_ +#ifndef TO_AUTOMATON_DERIVATION_H_ +#define TO_AUTOMATON_DERIVATION_H_ #include <regexp/RegExp.h> #include <regexp/formal/FormalRegExp.h> @@ -15,17 +15,15 @@ #include <automaton/Automaton.h> #include <automaton/FSM/NFA.h> -namespace conversions -{ +namespace regexp { -namespace re2fa -{ +namespace convert { /** * Converts regular expression to finite automaton using BrzozowskiDerivation algorithm (derivations of regular expressions). * Source: Melichar 2.110 */ -class BrzozowskiDerivation : public regexp::VisitableRegExpBase::const_visitor_type +class ToAutomatonDerivation : public regexp::VisitableRegExpBase::const_visitor_type { public: /** @@ -41,11 +39,11 @@ private: void Visit(void* , const regexp::FormalRegExp& regexp) const; void Visit(void* , const regexp::UnboundedRegExp& regexp) const; - static const BrzozowskiDerivation BRZOZOWSKI_DERIVATION; + static const ToAutomatonDerivation TO_AUTOMATON_DERIVATION; }; -} /* namespace re2fa */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ -#endif /* RE2FA_BRZOZOWSKIDERIVATION_H_ */ +#endif /* TO_AUTOMATON_DERIVATION_H_ */ diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp similarity index 61% rename from alib2algo/src/conversions/re2fa/GlushkovNFA.cpp rename to alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp index 825eee70c8a475aec170c4e51a3c9f3d9bd4c503..fb75db1789ad7c80434a234dde542e92d8c36c1e 100644 --- a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp @@ -1,34 +1,34 @@ /* - * GlushkovNFA.cpp + * ToAutomatonGlushkov.cpp * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#include "GlushkovNFA.h" +#include "ToAutomatonGlushkov.h" #include "label/Label.h" #include "label/LabelPairLabel.h" -#include "../../regexp/GlushkovTraversal.h" -#include "../../regexp/GlushkovPair.h" -#include "../../regexp/GlushkovSymbol.h" +#include "../GlushkovTraversal.h" +#include "../GlushkovPair.h" +#include "../GlushkovSymbol.h" -#include "../../regexp/RegExpEpsilon.h" +#include "../properties/RegExpEpsilon.h" -namespace conversions{ +namespace regexp { -namespace re2fa { +namespace convert { -automaton::NFA GlushkovNFA::convert(const regexp::RegExp& regexp) { +automaton::NFA ToAutomatonGlushkov::convert(const regexp::RegExp& regexp) { automaton::NFA* out = nullptr; - regexp.getData().Accept((void*) &out, GlushkovNFA::GLUSHKOV_NFA); + regexp.getData().Accept((void*) &out, ToAutomatonGlushkov::TO_AUTOMATON_GLUSHKOV); automaton::NFA res = std::move(*out); delete out; return res; } -automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) +automaton::NFA ToAutomatonGlushkov::convert(const regexp::UnboundedRegExp& regexp) { automaton::State q0( label::Label( label::LabelPairLabel( std::make_pair( label::labelFrom( 'q' ), label::labelFrom( 0 ) ) ) ) ); automaton::NFA automaton( q0 ); @@ -38,9 +38,9 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) automaton.addInputSymbol( symbol ); // steps 2, 3, 4 - std::set<regexp::GlushkovPair> pairs; - const std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp); - const std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp); + std::set<regexp::GlushkovPair> pairs; + const std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp); + const std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp); for( auto const& x : regexp::GlushkovTraversal::getSymbols( regexp ) ) for( auto const& f : regexp::GlushkovTraversal::follow( regexp, x ) ) { pairs.insert( regexp::GlushkovPair( x, f ) ); @@ -48,7 +48,7 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) // \e in q0 check is in step 7 // step 5 - std::map<regexp::GlushkovSymbol, automaton::State> stateMap; + std::map<regexp::GlushkovSymbol, automaton::State> stateMap; for( auto const& symbol : regexp::GlushkovTraversal::getSymbols( regexp ) ) { automaton::State q( label::Label( label::LabelPairLabel( std::make_pair( label::labelFrom( symbol.getInputSymbol( ) ), label::labelFrom( symbol.getId( ) ) ) ) ) ); @@ -77,13 +77,18 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) automaton.addFinalState( q ); } - if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(regexp)) automaton.addFinalState( q0 ); return automaton; } -void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) const +automaton::NFA ToAutomatonGlushkov::convert(const regexp::FormalRegExp& regexp) +{ + throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO +} + +void ToAutomatonGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const { /* automaton::NFA* & out = *((automaton::NFA**) userData); @@ -92,14 +97,14 @@ void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) cons throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO } -void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +void ToAutomatonGlushkov::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { automaton::NFA* & out = *((automaton::NFA**) userData); out = new automaton::NFA(this->convert(regexp)); } -const GlushkovNFA GlushkovNFA::GLUSHKOV_NFA; +const ToAutomatonGlushkov ToAutomatonGlushkov::TO_AUTOMATON_GLUSHKOV; -} /* namespace fa2re */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h new file mode 100644 index 0000000000000000000000000000000000000000..edf737ad00edd4ba0ca3f0793c44b56a6eb5cdf3 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h @@ -0,0 +1,50 @@ +/* + * ToAutomatonGlushkov.h + * + * Created on: 11. 1. 2014 + * Author: Tomas Pecka + */ + +#ifndef TO_AUTOMATON_GLUSHKOV_H_ +#define TO_AUTOMATON_GLUSHKOV_H_ + +#include <map> + +#include <automaton/FSM/NFA.h> +#include <regexp/RegExp.h> +#include <regexp/formal/FormalRegExp.h> +#include <regexp/unbounded/UnboundedRegExp.h> + +namespace regexp { + +namespace convert { + +/** + * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm. + * Source: Melichar 2.107 + */ +class ToAutomatonGlushkov : public regexp::VisitableRegExpBase::const_visitor_type +{ +public: + /** + * Performs conversion. + * @param re Original regular expression. + * @return NFA equivalent to original regular expression. + */ + static automaton::NFA convert(const regexp::RegExp& re); + + static automaton::NFA convert(const regexp::UnboundedRegExp& re); + static automaton::NFA convert(const regexp::FormalRegExp& re); + +private: + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + + static const ToAutomatonGlushkov TO_AUTOMATON_GLUSHKOV; +}; + +} /* namespace convert */ + +} /* namespace regexp */ + +#endif /* TO_AUTOMATON_GLUSHKOV_H_ */ diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp similarity index 84% rename from alib2algo/src/conversions/re2fa/Thompson.cpp rename to alib2algo/src/regexp/convert/ToAutomatonThompson.cpp index b3fe522f0f88b5101de8432cfa56b841dd040145..a2b2611735233efccf2102e05f220a63527a234e 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp @@ -1,36 +1,34 @@ /* - * Thompson.cpp + * ToAutomatonThompson.cpp * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#include "Thompson.h" +#include "ToAutomatonThompson.h" #include <tuple> -namespace conversions -{ +namespace regexp { -namespace re2fa -{ +namespace convert { -automaton::Automaton Thompson::convert(const regexp::RegExp& regexp) +automaton::Automaton ToAutomatonThompson::convert(const regexp::RegExp& regexp) { automaton::Automaton* out = NULL; - regexp.getData().Accept((void*) &out, Thompson::THOMPSON); + regexp.getData().Accept((void*) &out, ToAutomatonThompson::TO_AUTOMATON_THOMPSON); automaton::Automaton res = std::move(*out); delete out; return res; } template<class T> -automaton::EpsilonNFA Thompson::convert(const T& regexp) +automaton::EpsilonNFA ToAutomatonThompson::convert(const T& regexp) { //FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(automaton::State(0)), 1, nullptr, nullptr); automaton::EpsilonNFA& automaton = std::get<0>(out); automaton.setInputSymbols(regexp.getAlphabet()); - regexp.getRegExp().Accept((void*) &out, Thompson::THOMPSON); + regexp.getRegExp().Accept((void*) &out, ToAutomatonThompson::TO_AUTOMATON_THOMPSON); automaton.setInitialState(*std::get<2>(out)); automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)}); @@ -42,13 +40,13 @@ automaton::EpsilonNFA Thompson::convert(const T& regexp) // ---------------------------------------------------------------------------- -void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const { automaton::Automaton* & out = *((automaton::Automaton**) userData); out = new automaton::Automaton(this->convert(regexp)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { automaton::Automaton* & out = *((automaton::Automaton**) userData); out = new automaton::Automaton(this->convert(regexp)); @@ -56,7 +54,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) cons // ---------------------------------------------------------------------------- -void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -78,7 +76,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alte std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; @@ -95,7 +93,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& co // std::get<3>(out) = std::get<3>(out); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; @@ -116,7 +114,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iterat std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; @@ -132,7 +130,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) c std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; @@ -148,7 +146,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const +void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; @@ -166,7 +164,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const // ---------------------------------------------------------------------------- -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -187,7 +185,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& a std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -206,7 +204,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& std::get<3>(out) = tails[tails.size()-1].second; } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -226,7 +224,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& ite std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -241,7 +239,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -256,7 +254,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) cons std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const +void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; automaton::EpsilonNFA& automaton = std::get<0>(out); @@ -270,8 +268,8 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const std::get<3>(out) = &(*automaton.getStates().find(tail)); } -const Thompson Thompson::THOMPSON; +const ToAutomatonThompson ToAutomatonThompson::TO_AUTOMATON_THOMPSON; -} /* namespace re2fa */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h similarity index 81% rename from alib2algo/src/conversions/re2fa/Thompson.h rename to alib2algo/src/regexp/convert/ToAutomatonThompson.h index e127f07f54e53f48e9691986e9f04e6d0af0f312..e2608c9b1c12adccb75c390ac621a93fe5aa92a3 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.h +++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h @@ -1,12 +1,12 @@ /* - * Thompson.h + * ToAutomatonThompson.h * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#ifndef THOMPSON_H_ -#define THOMPSON_H_ +#ifndef TO_AUTOMATON_THOMPSON_H_ +#define TO_AUTOMATON_THOMPSON_H_ #include <regexp/RegExp.h> #include <regexp/formal/FormalRegExpElements.h> @@ -14,11 +14,9 @@ #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace conversions -{ +namespace regexp { -namespace re2fa -{ +namespace convert { /** * Converts regular expression to finite automaton using Thompson's Construction Algorithm (TCA). @@ -28,7 +26,7 @@ namespace re2fa * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.7450&rep=rep1&type=ps * Melichar 2.112 */ -class Thompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type +class ToAutomatonThompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type { public: /** @@ -59,11 +57,11 @@ private: void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const; void Visit(void*, const regexp::FormalRegExpEmpty& empty) const; - static const Thompson THOMPSON; + static const ToAutomatonThompson TO_AUTOMATON_THOMPSON; }; -} /* namespace re2fa */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ -#endif /* THOMPSON_H_ */ +#endif /* TO_AUTOMATON_THOMPSON_H_ */ diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0eb7d88c9b2f33ff5deb0bebca7adeaea7a0edec --- /dev/null +++ b/alib2algo/src/regexp/convert/ToGrammar.cpp @@ -0,0 +1,41 @@ +/* + * ToGrammar.cpp + * + * Created on: 6. 3. 2014 + * Author: Jan Travnicek + */ + +#include "ToGrammar.h" +#include "ToGrammarRightRGGlushkov.h" +#include <exception/AlibException.h> + +namespace regexp { + +namespace convert { + +grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp) +{ + grammar::Grammar* out = NULL; + regexp.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void ToGrammar::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + grammar::Grammar* &out = *((grammar::Grammar**) userData); + out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp)); +} + +void ToGrammar::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + grammar::Grammar* &out = *((grammar::Grammar**) userData); + out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp)); +} + +const ToGrammar ToGrammar::TO_GRAMMAR; + +} /* namespace convert */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h new file mode 100644 index 0000000000000000000000000000000000000000..de8438c541638213b0e98dbde6cfd691d0b6b784 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToGrammar.h @@ -0,0 +1,38 @@ +/* + * ToGrammar.h + * + * Created on: 6. 3. 2014 + * Author: Jan Travnicek + */ + +#ifndef REG_EXP_TO_GRAMMAR_H_ +#define REG_EXP_TO_GRAMMAR_H_ + +#include <grammar/Grammar.h> +#include <regexp/RegExp.h> + +namespace regexp { + +namespace convert { + +class ToGrammar : public regexp::VisitableRegExpBase::const_visitor_type +{ +public: + /** + * Performs conversion. + * @return right regular grammar equivalent to source regexp. + */ + static grammar::Grammar convert(const regexp::RegExp& regexp); + +private: + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + + static const ToGrammar TO_GRAMMAR; +}; + +} /* namespace convert */ + +} /* namespace regexp */ + +#endif /* REG_EXP_TO_GRAMMAR_H_ */ diff --git a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp similarity index 68% rename from alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp rename to alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp index 27e75fcdf0a0881a8e38572c4da0969b75cf5243..1f9106c2a9624b82db2353ee8398f2c70341ff6f 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp @@ -1,11 +1,11 @@ /* - * BrzozowskiDerivation.cpp + * ToGrammarRightRGDerivation.cpp * * Created on: 6. 3. 2014 - * Author: tomas + * Author: Tomas Pecka */ -#include "BrzozowskiDerivation.h" +#include "ToGrammarRightRGDerivation.h" #include <set> #include <deque> @@ -14,30 +14,28 @@ #include <std/hexavigesimal.h> -#include "../../../regexp/RegExpOptimize.h" -#include "../../../regexp/RegExpDerivation.h" -#include "../../../regexp/RegExpEpsilon.h" +#include "../simplify/RegExpOptimize.h" +#include "../transform/RegExpDerivation.h" +#include "../properties/RegExpEpsilon.h" -namespace conversions -{ +namespace regexp { -namespace re2rg -{ +namespace convert { -grammar::RightRG BrzozowskiDerivation::convert(const regexp::RegExp& regexp) +grammar::RightRG ToGrammarRightRGDerivation::convert(const regexp::RegExp& regexp) { grammar::RightRG* out = NULL; - regexp.getData().Accept((void*) &out, BrzozowskiDerivation::BRZOZOWSKI_DERIVATION); + regexp.getData().Accept((void*) &out, ToGrammarRightRGDerivation::TO_GRAMMAR_RIGHT_RG_DERIVATION); grammar::RightRG res = std::move(*out); delete out; return res; } template<class T> -grammar::RightRG BrzozowskiDerivation::convert(const T& regexp) +grammar::RightRG ToGrammarRightRGDerivation::convert(const T& regexp) { // 1. - regexp::RegExp V = regexp::RegExp{regexp::RegExpOptimize::optimize(regexp)}; + regexp::RegExp V = regexp::RegExp{regexp::simplify::RegExpOptimize::optimize(regexp)}; std::set<regexp::RegExp> N = { V }; std::deque<std::set<regexp::RegExp>> Ni; @@ -60,7 +58,7 @@ grammar::RightRG BrzozowskiDerivation::convert(const T& regexp) { string::LinearString string(std::vector<alphabet::Symbol>{a}); regexp::RegExp derived = deriv.derivation(dregexp, string); - derived = regexp::RegExpOptimize::optimize(derived); + derived = regexp::simplify::RegExpOptimize::optimize(derived); // this will also add \emptyset as a regexp (and as FA state) if(N.count(derived) == 0) // if this state has already been found, do not add @@ -101,37 +99,37 @@ grammar::RightRG BrzozowskiDerivation::convert(const T& regexp) { string::LinearString string(std::vector<alphabet::Symbol>{a}); regexp::RegExp derived = deriv.derivation(r, string); - derived = regexp::RegExpOptimize::optimize(derived); + derived = regexp::simplify::RegExpOptimize::optimize(derived); grammar.addRule(nonterminalMap.find(r)->second, std::make_pair(a, nonterminalMap.find(derived)->second)); - if(regexp::RegExpEpsilon::languageContainsEpsilon(derived)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(derived)) grammar.addRule(nonterminalMap.find(r)->second, a); } } grammar.setInitialSymbol(nonterminalMap.find(V)->second); - if(regexp::RegExpEpsilon::languageContainsEpsilon(V)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(V)) grammar.setGeneratesEpsilon(true); // okay, because of this feature we do not have to bother with extending the grammar with new rules and nonterminals. YAY! return grammar; } -void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const +void ToGrammarRightRGDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const { grammar::RightRG* &out = *((grammar::RightRG**) userData); out = new grammar::RightRG(this->convert(regexp)); } -void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +void ToGrammarRightRGDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { grammar::RightRG* &out = *((grammar::RightRG**) userData); out = new grammar::RightRG(this->convert(regexp)); } -const BrzozowskiDerivation BrzozowskiDerivation::BRZOZOWSKI_DERIVATION; +const ToGrammarRightRGDerivation ToGrammarRightRGDerivation::TO_GRAMMAR_RIGHT_RG_DERIVATION; -} /* namespace re2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h similarity index 63% rename from alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h rename to alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h index 7a5814ad9ab02a7e4c166b5301f4582f6f676ad3..4027f7169173a6f70cfdfa406e9e8f70e2b14818 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h @@ -1,29 +1,27 @@ /* - * BrzozowskiDerivation.h + * ToGrammarRightRGDerivation.h * * Created on: 6. 3. 2014 * Author: Tomas Pecka */ -#ifndef RE2RG_BRZOZOWSKIDERIVATION_H_ -#define RE2RG_BRZOZOWSKIDERIVATION_H_ +#ifndef TO_GRAMMAR_RIGHT_RG_DERIVATION_H_ +#define TO_GRAMMAR_RIGHT_RG_DERIVATION_H_ #include <grammar/Regular/RightRG.h> #include <regexp/RegExp.h> #include <regexp/formal/FormalRegExp.h> #include <regexp/unbounded/UnboundedRegExp.h> -namespace conversions -{ +namespace regexp { -namespace re2rg -{ +namespace convert { /** * Converts reg. expression to right regular grammar using brzozowski derivation algorithm. * Source: Melichar 2.137 */ -class BrzozowskiDerivation : public regexp::VisitableRegExpBase::const_visitor_type +class ToGrammarRightRGDerivation : public regexp::VisitableRegExpBase::const_visitor_type { public: /** @@ -39,11 +37,11 @@ private: void Visit(void*, const regexp::FormalRegExp& regexp) const; void Visit(void*, const regexp::UnboundedRegExp& regexp) const; - static const BrzozowskiDerivation BRZOZOWSKI_DERIVATION; + static const ToGrammarRightRGDerivation TO_GRAMMAR_RIGHT_RG_DERIVATION; }; -} /* namespace re2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ -#endif /* RE2RG_BRZOZOWSKIDERIVATION_H_ */ +#endif /* TO_GRAMMAR_RIGHT_RG_DERIVATION_H_ */ diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp similarity index 71% rename from alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp rename to alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp index a49c6d9aacc3547918bd05bdf831c9bc3c8df61d..cb1ba5388b18391895ef03502df76fa223757992 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp @@ -1,11 +1,11 @@ /* - * Glushkov.cpp + * ToGrammarRightRGGlushkov.cpp * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#include "GlushkovNFA.h" +#include "ToGrammarRightRGGlushkov.h" #include <algorithm> @@ -13,28 +13,26 @@ #include <label/LabelPairLabel.h> -#include "../../../regexp/GlushkovTraversal.h" -#include "../../../regexp/GlushkovPair.h" -#include "../../../regexp/GlushkovSymbol.h" +#include "../GlushkovTraversal.h" +#include "../GlushkovPair.h" +#include "../GlushkovSymbol.h" -#include "../../../regexp/RegExpEpsilon.h" +#include "../properties/RegExpEpsilon.h" -namespace conversions -{ +namespace regexp { -namespace re2rg -{ +namespace convert { -grammar::Grammar GlushkovNFA::convert(const regexp::RegExp& regexp) +grammar::Grammar ToGrammarRightRGGlushkov::convert(const regexp::RegExp& regexp) { grammar::Grammar* out = NULL; - regexp.getData().Accept((void*) &out, GlushkovNFA::GLUSHKOV_NFA); + regexp.getData().Accept((void*) &out, ToGrammarRightRGGlushkov::TO_GRAMMAR_RIGHT_RG_GLUSHKOV); grammar::Grammar res = std::move(*out); delete out; return res; } -grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) +grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::UnboundedRegExp& regexp) { alphabet::Symbol S = alphabet::symbolFrom("S"); grammar::RightRG grammar(S); @@ -89,14 +87,17 @@ grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) grammar.addRule(rule.first, rhs.at(0)); } - if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(regexp)) grammar.setGeneratesEpsilon(true); return grammar; } +grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::FormalRegExp& regexp) { + throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO +} -void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) const +void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const { /* grammar::Grammar* & out = *((grammar::Grammar**) userData); @@ -105,14 +106,14 @@ void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) cons throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO } -void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { grammar::Grammar* & out = *((grammar::Grammar**) userData); out = new grammar::Grammar(this->convert(regexp)); } -const GlushkovNFA GlushkovNFA::GLUSHKOV_NFA; +const ToGrammarRightRGGlushkov ToGrammarRightRGGlushkov::TO_GRAMMAR_RIGHT_RG_GLUSHKOV; -} /* namespace re2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h similarity index 68% rename from alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h rename to alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h index 32de94e8b020907573114155fb9c1c8b33bea075..42a9cb9e82f76a6c94e63c5cd75a9763672e1957 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h @@ -1,12 +1,12 @@ /* - * Glushkov.h + * ToGrammarRightRGGlushkov.h * * Created on: 11. 1. 2014 * Author: Tomas Pecka */ -#ifndef RE2RG_GLUSHKOVNFA_H_ -#define RE2RG_GLUSHKOVNFA_H_ +#ifndef TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_ +#define TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_ #include <grammar/Grammar.h> #include <grammar/Regular/RightRG.h> @@ -15,17 +15,15 @@ #include <regexp/formal/FormalRegExp.h> #include <regexp/unbounded/UnboundedRegExp.h> -namespace conversions -{ +namespace regexp { -namespace re2rg -{ +namespace convert { /** * Converts regular expression to right regular grammar using Glushkov algorithm. * Source: None yet. */ -class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type +class ToGrammarRightRGGlushkov : public regexp::VisitableRegExpBase::const_visitor_type { public: /** @@ -42,11 +40,11 @@ private: void Visit(void*, const regexp::FormalRegExp& regexp) const; void Visit(void*, const regexp::UnboundedRegExp& regexp) const; - static const GlushkovNFA GLUSHKOV_NFA; + static const ToGrammarRightRGGlushkov TO_GRAMMAR_RIGHT_RG_GLUSHKOV; }; -} /* namespace re2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace regexp */ -#endif /* RE2RG_GLUSHKOVNFA_H_ */ +#endif /* TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_ */ diff --git a/alib2algo/src/generator/RandomRegExpFactory.cpp b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp similarity index 97% rename from alib2algo/src/generator/RandomRegExpFactory.cpp rename to alib2algo/src/regexp/generate/RandomRegExpFactory.cpp index 7dfd8eca9ecdbbcf29aa6bab8ef28d4dece83278..196802377d61ebe9fc9e4d690c0756b4090d4837 100644 --- a/alib2algo/src/generator/RandomRegExpFactory.cpp +++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp @@ -9,7 +9,9 @@ #include <algorithm> -namespace generator { +namespace regexp { + +namespace generate { regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize ) { srand( time( NULL ) ); @@ -142,4 +144,6 @@ const regexp::UnboundedRegExpElement* RandomRegExpFactory::SimpleUnboundedRegExp } } -} +} /* namespace generate */ + +} /* namespace regexp */ diff --git a/alib2algo/src/generator/RandomRegExpFactory.h b/alib2algo/src/regexp/generate/RandomRegExpFactory.h similarity index 91% rename from alib2algo/src/generator/RandomRegExpFactory.h rename to alib2algo/src/regexp/generate/RandomRegExpFactory.h index 0459faf3acffa1f6d7308dd508a4fe17b6f92179..eaee929c6c09017ebf1921415077a29dc98fe290 100644 --- a/alib2algo/src/generator/RandomRegExpFactory.h +++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.h @@ -15,7 +15,9 @@ #include <regexp/unbounded/UnboundedRegExp.h> #include <regexp/unbounded/UnboundedRegExpElements.h> -namespace generator { +namespace regexp { + +namespace generate { class RandomRegExpFactory { public: @@ -27,6 +29,8 @@ private: static const regexp::UnboundedRegExpElement* SimpleUnboundedRegExpElement(size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems); }; -} +} /* namespace generate */ + +} /* namespace regexp */ #endif /* RANDOM_REG_EXP_FACTORY_H_ */ diff --git a/alib2algo/src/regexp/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp similarity index 98% rename from alib2algo/src/regexp/RegExpEmpty.cpp rename to alib2algo/src/regexp/properties/RegExpEmpty.cpp index 16247f9328df4c77308a87236084275b3f58f622..eae0d1262feea3bd2b7c561eda283fede9a3af34 100644 --- a/alib2algo/src/regexp/RegExpEmpty.cpp +++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp @@ -7,8 +7,9 @@ #include "RegExpEmpty.h" -namespace regexp -{ +namespace regexp { + +namespace properties { bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) { @@ -157,4 +158,6 @@ void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExp& regexp) const const RegExpEmpty RegExpEmpty::REG_EXP_EMPTY; +} /* namespace properties */ + } /* namespace regexp */ diff --git a/alib2algo/src/regexp/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h similarity index 96% rename from alib2algo/src/regexp/RegExpEmpty.h rename to alib2algo/src/regexp/properties/RegExpEmpty.h index 8b2958e121a1cf60d0ee7035768d100262684711..d76fa5fac364d1b933b73f399832cf47fc14f20e 100644 --- a/alib2algo/src/regexp/RegExpEmpty.h +++ b/alib2algo/src/regexp/properties/RegExpEmpty.h @@ -12,8 +12,9 @@ #include <regexp/formal/FormalRegExpElements.h> #include <regexp/unbounded/UnboundedRegExpElements.h> -namespace regexp -{ +namespace regexp { + +namespace properties { /** * Determines whether regular expression is empty (regexp == \0) @@ -48,6 +49,8 @@ private: static const RegExpEmpty REG_EXP_EMPTY; }; +} /* namespace properties */ + } /* namespace regexp */ #endif /* REG_EXP_EMPTY_H_ */ diff --git a/alib2algo/src/regexp/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp similarity index 98% rename from alib2algo/src/regexp/RegExpEpsilon.cpp rename to alib2algo/src/regexp/properties/RegExpEpsilon.cpp index c697cbbdd16061eb579353d0eec35df5bbb9e96a..58c9ed6497bf7235d1c71695143cf1ab1004481f 100644 --- a/alib2algo/src/regexp/RegExpEpsilon.cpp +++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp @@ -7,8 +7,9 @@ #include "RegExpEpsilon.h" -namespace regexp -{ +namespace regexp { + +namespace properties { bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) { @@ -174,4 +175,6 @@ void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExp& regexp) con const RegExpEpsilon RegExpEpsilon::REG_EXP_EPSILON; +} /* namespace properties */ + } /* namespace regexp */ diff --git a/alib2algo/src/regexp/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h similarity index 96% rename from alib2algo/src/regexp/RegExpEpsilon.h rename to alib2algo/src/regexp/properties/RegExpEpsilon.h index 4472068c2c856e87ecb974eedb962b284915b797..58d2518919684da699a1d26048048ac3d0e72198 100644 --- a/alib2algo/src/regexp/RegExpEpsilon.h +++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h @@ -12,8 +12,9 @@ #include <regexp/formal/FormalRegExpElements.h> #include <regexp/unbounded/UnboundedRegExpElements.h> -namespace regexp -{ +namespace regexp { + +namespace properties { /** * Checks, whether regexp (or its subtree) describes epsilon (empty string). @@ -53,6 +54,8 @@ private: static const RegExpEpsilon REG_EXP_EPSILON; }; +} /* namespace properties */ + } /* namespace regexp */ #endif /* REG_EXP_EPSILON_H_ */ diff --git a/alib2algo/src/regexp/RegExpOptimize.cpp b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp similarity index 97% rename from alib2algo/src/regexp/RegExpOptimize.cpp rename to alib2algo/src/regexp/simplify/RegExpOptimize.cpp index 42573dc1e8e492d60fa8725e47fdfce805a2e0dd..e3c630f1a4863b676e1ce32f9d2235e4939ae32a 100644 --- a/alib2algo/src/regexp/RegExpOptimize.cpp +++ b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp @@ -7,7 +7,7 @@ #include "RegExpOptimize.h" -#include "RegExpEpsilon.h" +#include "../properties/RegExpEpsilon.h" #include <cassert> #include <iostream> @@ -15,6 +15,8 @@ namespace regexp { +namespace simplify { + regexp::RegExp RegExpOptimize::optimize(const regexp::RegExp& regexp) { regexp::RegExp * out = NULL; @@ -157,7 +159,9 @@ void RegExpOptimize::optimize( UnboundedRegExpElement & element ) { const RegExpOptimize RegExpOptimize::REG_EXP_OPTIMIZE; +} /* namespace regexp */ + +} /* namespace simplify */ + #include "RegExpOptimizeUnboundedPart.cxx" #include "RegExpOptimizeFormalPart.cxx" - -} diff --git a/alib2algo/src/regexp/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h similarity index 98% rename from alib2algo/src/regexp/RegExpOptimize.h rename to alib2algo/src/regexp/simplify/RegExpOptimize.h index 1cd12f7a686a47d3719e46feffaad8c78d8b00b6..f0d7ba78c0fb52a2045b8ac01daa2f1f07b95c5d 100644 --- a/alib2algo/src/regexp/RegExpOptimize.h +++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h @@ -24,6 +24,8 @@ namespace regexp { +namespace simplify { + /* * Optimizes RegExp (or its subtree) using axioms defined in Melichar 2.87 * (A1 to A10) and Melichar 2.95(V1 through V6 and V8, V9, V10) @@ -134,6 +136,8 @@ private: static const RegExpOptimize REG_EXP_OPTIMIZE; }; -} +} /* namespace simplify */ + +} /* namespace regexp */ #endif /* REGEXPNORMALIZE_H_ */ diff --git a/alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx similarity index 98% rename from alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx rename to alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx index 8a6793f16eb4c2ed513811918ff5bcb935edd104..d2ac3dd6313390a3e61cefdff287af821574d653 100644 --- a/alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx +++ b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx @@ -1,3 +1,14 @@ +/* + * RegExpOptimize.cpp + * + * Created on: 20. 1. 2014 + * Author: Jan Travnicek + */ + +namespace regexp { + +namespace simplify { + FormalRegExpElement* RegExpOptimize::optimize( FormalRegExpElement const * const & node ) const { FormalRegExpElement* elem = node->clone(); @@ -567,4 +578,9 @@ bool RegExpOptimize::X1( FormalRegExpElement * & n ) const } return false; + } + +} /* namespace simplify */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx similarity index 98% rename from alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx rename to alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx index 95f668405c83e2e049b28433eabb50babf150b8a..9d3faf3058028244f8f590e68ee93c2d9fe712b7 100644 --- a/alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx +++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx @@ -1,3 +1,14 @@ +/* + * RegExpOptimize.cpp + * + * Created on: 20. 1. 2014 + * Author: Tomas Pecka + */ + +namespace regexp { + +namespace simplify { + UnboundedRegExpElement* RegExpOptimize::optimize( UnboundedRegExpElement const * const & node ) const { const UnboundedRegExpAlternation * alternation = dynamic_cast<const UnboundedRegExpAlternation*>( node ); @@ -999,7 +1010,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const auto it2 = it; advance( it2, - (int)concat->elements.size( ) ); - if( regexp::RegExpEpsilon::languageContainsEpsilon(*concat) && + if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) && distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) && equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) ) { @@ -1025,7 +1036,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const auto prev = std::prev( it ); - if( regexp::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev ) + if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev ) { delete * prev; it = node->elements.erase( prev ); @@ -1160,3 +1171,7 @@ bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node ) const return false; } + +} /* namespace simplify */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/RegExpAlternate.cpp b/alib2algo/src/regexp/transform/RegExpAlternate.cpp similarity index 100% rename from alib2algo/src/regexp/RegExpAlternate.cpp rename to alib2algo/src/regexp/transform/RegExpAlternate.cpp diff --git a/alib2algo/src/regexp/RegExpAlternate.h b/alib2algo/src/regexp/transform/RegExpAlternate.h similarity index 100% rename from alib2algo/src/regexp/RegExpAlternate.h rename to alib2algo/src/regexp/transform/RegExpAlternate.h diff --git a/alib2algo/src/regexp/RegExpConcatenate.cpp b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp similarity index 100% rename from alib2algo/src/regexp/RegExpConcatenate.cpp rename to alib2algo/src/regexp/transform/RegExpConcatenate.cpp diff --git a/alib2algo/src/regexp/RegExpConcatenate.h b/alib2algo/src/regexp/transform/RegExpConcatenate.h similarity index 100% rename from alib2algo/src/regexp/RegExpConcatenate.h rename to alib2algo/src/regexp/transform/RegExpConcatenate.h diff --git a/alib2algo/src/regexp/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp similarity index 97% rename from alib2algo/src/regexp/RegExpDerivation.cpp rename to alib2algo/src/regexp/transform/RegExpDerivation.cpp index ac198be43829e95377b16dc06b1f1c2eddb3f9a0..cbf0f3a744251b1c9541e9cdca6735b6ef92a87f 100644 --- a/alib2algo/src/regexp/RegExpDerivation.cpp +++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp @@ -7,7 +7,7 @@ #include "RegExpDerivation.h" -#include "RegExpEpsilon.h" +#include "../properties/RegExpEpsilon.h" namespace regexp { @@ -97,7 +97,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatena delete leftDerivative; delete rightElement; - if(regexp::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement())) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement())) { const regexp::FormalRegExpElement *alternation = out.second, *rightDerivative = nullptr; static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this); @@ -186,7 +186,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat ret->appendElement(std::move(*concat)); delete concat; - if(regexp::RegExpEpsilon::languageContainsEpsilon(**child)) + if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(**child)) continue; // this IF construct is intentional "to match algorithm" break; } diff --git a/alib2algo/src/regexp/RegExpDerivation.h b/alib2algo/src/regexp/transform/RegExpDerivation.h similarity index 100% rename from alib2algo/src/regexp/RegExpDerivation.h rename to alib2algo/src/regexp/transform/RegExpDerivation.h diff --git a/alib2algo/src/regexp/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp similarity index 100% rename from alib2algo/src/regexp/RegExpIntegral.cpp rename to alib2algo/src/regexp/transform/RegExpIntegral.cpp diff --git a/alib2algo/src/regexp/RegExpIntegral.h b/alib2algo/src/regexp/transform/RegExpIntegral.h similarity index 100% rename from alib2algo/src/regexp/RegExpIntegral.h rename to alib2algo/src/regexp/transform/RegExpIntegral.h diff --git a/alib2algo/src/regexp/RegExpIterate.cpp b/alib2algo/src/regexp/transform/RegExpIterate.cpp similarity index 100% rename from alib2algo/src/regexp/RegExpIterate.cpp rename to alib2algo/src/regexp/transform/RegExpIterate.cpp diff --git a/alib2algo/src/regexp/RegExpIterate.h b/alib2algo/src/regexp/transform/RegExpIterate.h similarity index 100% rename from alib2algo/src/regexp/RegExpIterate.h rename to alib2algo/src/regexp/transform/RegExpIterate.h diff --git a/alib2algo/src/compare/string/CyclicStringCompare.cpp b/alib2algo/src/string/compare/CyclicStringCompare.cpp similarity index 94% rename from alib2algo/src/compare/string/CyclicStringCompare.cpp rename to alib2algo/src/string/compare/CyclicStringCompare.cpp index 0e8fc8b879a6c37df39f19602558af4bf8d20191..0e33dfbe2a59f8bc0255e2ee2d8f28346597dc13 100644 --- a/alib2algo/src/compare/string/CyclicStringCompare.cpp +++ b/alib2algo/src/string/compare/CyclicStringCompare.cpp @@ -6,8 +6,10 @@ #include "CyclicStringCompare.h" +namespace string { + namespace compare { - + bool CyclicStringCompare::equals(const string::LinearString& u, const string::LinearString& v) { int n = (int)u.getContent().size(); int i = -1, j = -1, k; @@ -39,4 +41,6 @@ int CyclicStringCompare::compare(const string::LinearString& u, const string::Li return last ? 1 : - 1; } -} +} /* namespace compare */ + +} /* namespace string */ diff --git a/alib2algo/src/compare/string/CyclicStringCompare.h b/alib2algo/src/string/compare/CyclicStringCompare.h similarity index 86% rename from alib2algo/src/compare/string/CyclicStringCompare.h rename to alib2algo/src/string/compare/CyclicStringCompare.h index 18e062432185332ba40c38737496ee25aea62d60..267a791376918e9f287bb714706e58e1163ce2ca 100644 --- a/alib2algo/src/compare/string/CyclicStringCompare.h +++ b/alib2algo/src/string/compare/CyclicStringCompare.h @@ -10,6 +10,8 @@ #include "string/LinearString.h" +namespace string { + namespace compare { class CyclicStringCompare { @@ -19,6 +21,8 @@ public: }; -} +} /* namespace compare */ + +} /* namespace string */ #endif /* CYCLIC_STRING_COMPARE_H_ */ diff --git a/alib2algo/src/trim/grammar/TrimCFG.cpp b/alib2algo/src/trim/grammar/TrimCFG.cpp deleted file mode 100644 index 0a5fe0f974df1edc42ae7b022db0b4622468a0d5..0000000000000000000000000000000000000000 --- a/alib2algo/src/trim/grammar/TrimCFG.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * TrimCFG.cpp - * - * Created on: 22. 3. 2014 - * Author: Tomas Pecka - */ - -#include "TrimCFG.h" - -#include <grammar/ContextFree/CFG.h> -#include <grammar/ContextFree/EpsilonFreeCFG.h> -#include <grammar/ContextFree/GNF.h> -#include <grammar/ContextFree/CNF.h> -#include <grammar/ContextFree/LG.h> -#include <grammar/Regular/LeftLG.h> -#include <grammar/Regular/LeftRG.h> -#include <grammar/Regular/RightLG.h> -#include <grammar/Regular/RightRG.h> - -#include <std/set.hpp> - -#include "../../grammar/GrammarPropertiesCFG.h" - -namespace trim { - -template<class T> -T TrimCFG::removeUnreachableSymbols( const T & grammar) { - // 1. - std::set<alphabet::Symbol> Vt = grammar::GrammarPropertiesCFG::getUnreachableSymbols( grammar ); - - T ret(grammar.getInitialSymbol( ) ); - - std::set<alphabet::Symbol> newNonTerminals, newTerminals; - - set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) ); - for( const auto & symbol : newNonTerminals ) - ret.addNonterminalSymbol( symbol ); - - set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) ); - for( const auto & symbol : newTerminals ) - ret.addTerminalSymbol( symbol ); - - // A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P - for( const auto & rule : grammar.getRawRules( ) ) { - if( newNonTerminals.count( rule.first ) ) { - for( const auto& rhs : rule.second ) { - if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( alphabet::Symbol const& symb ) -> bool { - return Vt.count( symb ); - } ) ) - ret.addRawRule( rule.first, rhs ); - } - } - } - - // 2. - return ret; -} - -template grammar::CFG TrimCFG::removeUnreachableSymbols( const grammar::CFG & grammar ); -template grammar::EpsilonFreeCFG TrimCFG::removeUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar ); -template grammar::GNF TrimCFG::removeUnreachableSymbols( const grammar::GNF & grammar ); -template grammar::CNF TrimCFG::removeUnreachableSymbols( const grammar::CNF & grammar ); -template grammar::LG TrimCFG::removeUnreachableSymbols( const grammar::LG & grammar ); -template grammar::LeftLG TrimCFG::removeUnreachableSymbols( const grammar::LeftLG & grammar ); -template grammar::LeftRG TrimCFG::removeUnreachableSymbols( const grammar::LeftRG & grammar ); -template grammar::RightLG TrimCFG::removeUnreachableSymbols( const grammar::RightLG & grammar ); -template grammar::RightRG TrimCFG::removeUnreachableSymbols( const grammar::RightRG & grammar ); - -template<class T> -T TrimCFG::removeUnproductiveSymbols( const T & grammar ) { - // 1. - std::set<alphabet::Symbol> Nt = grammar::GrammarPropertiesCFG::getProductiveNonterminals( grammar ); - - T ret(grammar.getInitialSymbol( ) ); - - for( const auto & symbol : Nt ) - ret.addNonterminalSymbol( symbol ); - - for( const auto & symbol : grammar.getTerminalAlphabet( ) ) - ret.addTerminalSymbol( symbol ); - - const std::set<alphabet::Symbol> & terminals = ret.getTerminalAlphabet( ); - for( const auto & rule : grammar.getRawRules( ) ) { - if( Nt.count( rule.first ) ) { - for( const auto & rhs : rule.second ) { - if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const alphabet::Symbol & symbol ) { - return Nt.count( symbol ) || terminals.count( symbol ); - } ) ) - ret.addRawRule( rule.first, rhs ); - } - } - } - - - /* if( ! G1.getNonTerminalSymbols( ) . count( grammar.getInitialSymbol( ) ) ) - throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." ); */ - - // 2. - return ret; -} - -template grammar::CFG TrimCFG::removeUnproductiveSymbols( const grammar::CFG & grammar ); -template grammar::EpsilonFreeCFG TrimCFG::removeUnproductiveSymbols( const grammar::EpsilonFreeCFG & grammar ); -template grammar::GNF TrimCFG::removeUnproductiveSymbols( const grammar::GNF & grammar ); -template grammar::CNF TrimCFG::removeUnproductiveSymbols( const grammar::CNF & grammar ); -template grammar::LG TrimCFG::removeUnproductiveSymbols( const grammar::LG & grammar ); -template grammar::LeftLG TrimCFG::removeUnproductiveSymbols( const grammar::LeftLG & grammar ); -template grammar::LeftRG TrimCFG::removeUnproductiveSymbols( const grammar::LeftRG & grammar ); -template grammar::RightLG TrimCFG::removeUnproductiveSymbols( const grammar::RightLG & grammar ); -template grammar::RightRG TrimCFG::removeUnproductiveSymbols( const grammar::RightRG & grammar ); - -template<class T> -T TrimCFG::trim( const T & grammar ) { - return removeUnreachableSymbols( removeUnproductiveSymbols( grammar ) ); -} - -template grammar::CFG TrimCFG::trim( const grammar::CFG & grammar ); -template grammar::EpsilonFreeCFG TrimCFG::trim( const grammar::EpsilonFreeCFG & grammar ); -template grammar::GNF TrimCFG::trim( const grammar::GNF & grammar ); -template grammar::CNF TrimCFG::trim( const grammar::CNF & grammar ); -template grammar::LG TrimCFG::trim( const grammar::LG & grammar ); -template grammar::LeftLG TrimCFG::trim( const grammar::LeftLG & grammar ); -template grammar::LeftRG TrimCFG::trim( const grammar::LeftRG & grammar ); -template grammar::RightLG TrimCFG::trim( const grammar::RightLG & grammar ); -template grammar::RightRG TrimCFG::trim( const grammar::RightRG & grammar ); - -} - diff --git a/alib2algo/src/trim/grammar/TrimCFG.h b/alib2algo/src/trim/grammar/TrimCFG.h deleted file mode 100644 index 3b320cdcd81e328fec37f06feffbf998faa365d9..0000000000000000000000000000000000000000 --- a/alib2algo/src/trim/grammar/TrimCFG.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * TrimCFG.h - * - * Created on: 22. 3. 2014 - * Author: Tomas Pecka - */ - -#ifndef TRIM_CFG_H_ -#define TRIM_CFG_H_ - -#include <algorithm> -#include <deque> -#include <set> - -#include <exception/AlibException.h> - -#include <alphabet/Symbol.h> - -namespace trim { - -/** - * Implements algorithms from Melichar, chapter 3.3 - */ -class TrimCFG { -public: - /* - * Removes unreachable symbols - Melichar 3.9 - */ - template<class T> - static T removeUnreachableSymbols( const T & grammar ); - - /** - * Removes unproductive (or useless - terminology) symbols - Melichar 3.12 - */ - template<class T> - static T removeUnproductiveSymbols( const T & grammar ); - - /** - * Removes unproductive and useless symbols - Melichar 3.12 - */ - template<class T> - static T trim( const T & grammar ); -}; - -} - -#endif /* TRIM_CFG_H_ */ diff --git a/alib2algo/test-src/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp similarity index 94% rename from alib2algo/test-src/determinize/determinizeTest.cpp rename to alib2algo/test-src/automaton/determinize/determinizeTest.cpp index fe1bf1fb1b60013fe6ad594a3a5ac49256f6ee68..f2408f344d5c7d37098c5298661be4d6ca3f7b7b 100644 --- a/alib2algo/test-src/determinize/determinizeTest.cpp +++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp @@ -1,8 +1,7 @@ #include <list> #include "determinizeTest.h" -#include "determinize/nfa/NFADeterminizer.h" -#include "determinize/idpda/IDPDADeterminizer.h" +#include "automaton/determinize/Determinize.h" #include "factory/DataFactory.hpp" @@ -30,7 +29,7 @@ void determinizeTest::testDeterminizeNFA() { automaton.addFinalState(automaton::State(3)); - automaton::DFA determinized = determinize::NFADeterminizer::determinize(automaton); + automaton::DFA determinized = automaton::determinize::Determinize::determinize(automaton); CPPUNIT_ASSERT(determinized.getStates().size() == 3); @@ -54,7 +53,7 @@ void determinizeTest::testDeterminizeIDPDA() { automaton.addInitialState(automaton::State(1)); automaton.addFinalState(automaton::State(3)); - automaton::DPDA determinized = determinize::IDPDADeterminizer::determinize(automaton); + automaton::DPDA determinized = automaton::determinize::Determinize::determinize(automaton); CPPUNIT_ASSERT(determinized.getStates().size() == 3); } diff --git a/alib2algo/test-src/determinize/determinizeTest.h b/alib2algo/test-src/automaton/determinize/determinizeTest.h similarity index 100% rename from alib2algo/test-src/determinize/determinizeTest.h rename to alib2algo/test-src/automaton/determinize/determinizeTest.h diff --git a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp similarity index 67% rename from alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp rename to alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp index 2b592081c33f62e8ee438c32f90909549bcfbb19..4a7ce40ba2436070e58dd19219c0bf2bd3e6a1a7 100644 --- a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp +++ b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp @@ -1,8 +1,10 @@ #include "FSMSingleInitialStateTest.h" -#include "automaton/FSMSingleInitialState.h" -#include "determinize/nfa/NFADeterminizer.h" -#include "normalize/dfa/NormalizeDFA.h" +#include "automaton/simplify/SingleInitialState.h" +#include "automaton/determinize/Determinize.h" +#include "automaton/simplify/Normalize.h" + +#include "automaton/FSM/MultiInitialStateNFA.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -33,7 +35,7 @@ void FSMSingleInitialStateTest::testSingleInitialState() { automaton1.addTransition(q1, b, q2); automaton1.addTransition(q2, a, q3); - automaton::NFA automaton2 = automaton::FSMSingleInitialState::convert(automaton1); + automaton::NFA automaton2 = automaton::simplify::SingleInitialState::convert(automaton1); automaton::NFA automaton3(q); automaton3.setStates({q, q1, q2, q3}); @@ -45,8 +47,8 @@ void FSMSingleInitialStateTest::testSingleInitialState() { automaton3.addTransition(q1, b, q2); automaton3.addTransition(q2, a, q3); - automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(automaton2); - automaton::DFA dfa3 = determinize::NFADeterminizer::determinize(automaton3); + automaton::DFA dfa2 = automaton::determinize::Determinize::determinize(automaton2); + automaton::DFA dfa3 = automaton::determinize::Determinize::determinize(automaton3); - CPPUNIT_ASSERT(normalize::NormalizeDFA::normalize(dfa3) == normalize::NormalizeDFA::normalize(dfa3)); + CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(dfa3) == automaton::simplify::Normalize::normalize(dfa3)); } diff --git a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.h b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.h similarity index 100% rename from alib2algo/test-src/automaton/FSMSingleInitialStateTest.h rename to alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.h diff --git a/alib2algo/test-src/automaton/FSMTotalTest.cpp b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp similarity index 62% rename from alib2algo/test-src/automaton/FSMTotalTest.cpp rename to alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp index c5ce5a4a1577636a6477d45f850d7e639ec7a934..7e6ba6ab2c652bf696f5b4e901da0882ba65cedc 100644 --- a/alib2algo/test-src/automaton/FSMTotalTest.cpp +++ b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp @@ -2,9 +2,9 @@ #include <automaton/FSM/DFA.h> -#include "automaton/FSMTotal.h" -#include "normalize/dfa/NormalizeDFA.h" -#include "trim/automaton/Trim.h" +#include "automaton/simplify/Total.h" +#include "automaton/simplify/Normalize.h" +#include "automaton/simplify/Trim.h" CPPUNIT_TEST_SUITE_REGISTRATION( TotalTest ); @@ -35,11 +35,11 @@ void TotalTest::testTotal() { automaton.addTransition(q1, c, q2); automaton.addTransition(q2, c, q2); - automaton::DFA totalAutomaton = automaton::FSMTotal::total(automaton); + automaton::DFA totalAutomaton = automaton::simplify::Total::total(automaton); CPPUNIT_ASSERT(totalAutomaton.isTotal()); - automaton::DFA trimmedAutomaton = trim::Trim::trim(automaton); - automaton::DFA trimmedTotalAutomaton = trim::Trim::trim(totalAutomaton); + automaton::DFA trimmedAutomaton = automaton::simplify::Trim::trim(automaton); + automaton::DFA trimmedTotalAutomaton = automaton::simplify::Trim::trim(totalAutomaton); - CPPUNIT_ASSERT(normalize::NormalizeDFA::normalize(trimmedAutomaton) == normalize::NormalizeDFA::normalize(trimmedTotalAutomaton)); + CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(trimmedAutomaton) == automaton::simplify::Normalize::normalize(trimmedTotalAutomaton)); } diff --git a/alib2algo/test-src/automaton/FSMTotalTest.h b/alib2algo/test-src/automaton/simplify/FSMTotalTest.h similarity index 100% rename from alib2algo/test-src/automaton/FSMTotalTest.h rename to alib2algo/test-src/automaton/simplify/FSMTotalTest.h diff --git a/alib2algo/test-src/minimize/minimizeTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp similarity index 87% rename from alib2algo/test-src/minimize/minimizeTest.cpp rename to alib2algo/test-src/automaton/simplify/minimizeTest.cpp index 8351ca03e5d2039a8643b24b244f5cf5f2ad077b..f5153ba2896850a7642f3deab3567acd5b425f33 100644 --- a/alib2algo/test-src/minimize/minimizeTest.cpp +++ b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp @@ -1,7 +1,7 @@ #include <list> #include "minimizeTest.h" -#include "minimize/dfa/MinimizeDFA.h" +#include "automaton/simplify/Minimize.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -27,7 +27,7 @@ void minimizeTest::testMinimize() { automaton.addFinalState(automaton::State(3)); - automaton::DFA minimized = minimize::MinimizeDFA::minimize(automaton); + automaton::DFA minimized = automaton::simplify::Minimize::minimize(automaton); CPPUNIT_ASSERT(minimized.getStates().size() == 3); diff --git a/alib2algo/test-src/minimize/minimizeTest.h b/alib2algo/test-src/automaton/simplify/minimizeTest.h similarity index 100% rename from alib2algo/test-src/minimize/minimizeTest.h rename to alib2algo/test-src/automaton/simplify/minimizeTest.h diff --git a/alib2algo/test-src/normalize/normalizeTest.cpp b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp similarity index 87% rename from alib2algo/test-src/normalize/normalizeTest.cpp rename to alib2algo/test-src/automaton/simplify/normalizeTest.cpp index 6ffd51fbb4a46fa4db81076b89458f2677d28f81..e12bbec861366f3257b4d66c05883c1e0c1f99e4 100644 --- a/alib2algo/test-src/normalize/normalizeTest.cpp +++ b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp @@ -1,7 +1,7 @@ #include <list> #include "normalizeTest.h" -#include "normalize/dfa/NormalizeDFA.h" +#include "automaton/simplify/Normalize.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -27,7 +27,7 @@ void normalizeTest::testNormalize() { automaton.addFinalState(automaton::State(2)); - automaton::DFA normalized = normalize::NormalizeDFA::normalize(automaton); + automaton::DFA normalized = automaton::simplify::Normalize::normalize(automaton); CPPUNIT_ASSERT(normalized.getStates().size() == 3); diff --git a/alib2algo/test-src/normalize/normalizeTest.h b/alib2algo/test-src/automaton/simplify/normalizeTest.h similarity index 100% rename from alib2algo/test-src/normalize/normalizeTest.h rename to alib2algo/test-src/automaton/simplify/normalizeTest.h diff --git a/alib2algo/test-src/trim/trimTest.cpp b/alib2algo/test-src/automaton/simplify/trimTest.cpp similarity index 91% rename from alib2algo/test-src/trim/trimTest.cpp rename to alib2algo/test-src/automaton/simplify/trimTest.cpp index 2de4d81f8470561ae675f430f5dd53763ae9a858..a4b46abe0f2eff9d34ceb896442136f5519293c6 100644 --- a/alib2algo/test-src/trim/trimTest.cpp +++ b/alib2algo/test-src/automaton/simplify/trimTest.cpp @@ -1,8 +1,8 @@ #include <list> #include "trimTest.h" -#include "trim/automaton/Trim.h" -#include "trim/grammar/TrimCFG.h" +#include "automaton/simplify/Trim.h" +#include "grammar/simplify/Trim.h" #include "automaton/FSM/DFA.h" #include "grammar/Regular/RightRG.h" @@ -32,7 +32,7 @@ void trimTest::testTrimAutomaton() { automaton.addFinalState(automaton::State(1)); - automaton::DFA trimed = trim::Trim::trim(automaton); + automaton::DFA trimed = automaton::simplify::Trim::trim(automaton); CPPUNIT_ASSERT(trimed.getStates().size() == 2); } @@ -58,7 +58,7 @@ void trimTest::testTrimGrammar() { rrGrammar.addRule(alphabet::symbolFrom(5), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(2))); rrGrammar.addRule(alphabet::symbolFrom(6), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(6))); - grammar::RightRG trimed = trim::TrimCFG::trim(rrGrammar); + grammar::RightRG trimed = grammar::simplify::Trim::trim(rrGrammar); CPPUNIT_ASSERT(trimed.getNonterminalAlphabet().size() == 3); } diff --git a/alib2algo/test-src/trim/trimTest.h b/alib2algo/test-src/automaton/simplify/trimTest.h similarity index 100% rename from alib2algo/test-src/trim/trimTest.h rename to alib2algo/test-src/automaton/simplify/trimTest.h diff --git a/alib2algo/test-src/compare/compareTest.cpp b/alib2algo/test-src/compare/compareTest.cpp deleted file mode 100644 index 9ada8b24b774329e4cdd2df6d348854630fcb378..0000000000000000000000000000000000000000 --- a/alib2algo/test-src/compare/compareTest.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include <list> -#include "compareTest.h" - -#include "compare/string/CyclicStringCompare.h" -#include "string/LinearString.h" - -#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) - -CPPUNIT_TEST_SUITE_REGISTRATION( compareTest ); - -void compareTest::setUp() { -} - -void compareTest::tearDown() { -} - -void compareTest::testCyclicStringCompareBoolean() { - string::LinearString str1("alfa"); - string::LinearString str2("aalf"); - str2.addSymbolsToAlphabet(str1.getAlphabet()); - str1.addSymbolsToAlphabet(str2.getAlphabet()); - - CPPUNIT_ASSERT(compare::CyclicStringCompare::equals(str1, str2)); -} - -void compareTest::testCyclicStringCompareInt() { - string::LinearString str1("alfa"); - string::LinearString str2("aalf"); - str2.addSymbolsToAlphabet(str1.getAlphabet()); - str1.addSymbolsToAlphabet(str2.getAlphabet()); - - CPPUNIT_ASSERT(compare::CyclicStringCompare::compare(str1, str2) == 0); -} diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp deleted file mode 100644 index 9adb79a4c57b375ed7e1360c009cec27ed8b8a02..0000000000000000000000000000000000000000 --- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include <list> -#include "re2faTest.h" - -#include "conversions/re2fa/BrzozowskiDerivation.h" -#include "conversions/re2fa/GlushkovNFA.h" -#include "conversions/re2fa/Thompson.h" -#include "conversions/fa2re/Algebraic.h" -#include "determinize/nfa/NFADeterminizer.h" -#include "minimize/dfa/MinimizeDFA.h" -#include "normalize/dfa/NormalizeDFA.h" -#include "epsilon/fsm/FSMEpsilonRemover.h" - -#include "regexp/unbounded/UnboundedRegExp.h" -#include "regexp/RegExpFromStringParser.h" - -#include "automaton/FSM/NFA.h" -#include <factory/DataFactory.hpp> - -CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest ); - -void re2faTest::setUp() { -} - -void re2faTest::tearDown() { -} - -void re2faTest::testThompson() { - std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp1( parser.parseValue() ); - - automaton::Automaton enfa1 = conversions::re2fa::Thompson::convert(regexp1); - - regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(enfa1) ); - - automaton::Automaton enfa2 = conversions::re2fa::Thompson::convert(regexp2); - - automaton::Automaton nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1); - automaton::Automaton nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2); - - automaton::Automaton dfa1 = determinize::NFADeterminizer::determinize(nfa1); - automaton::Automaton dfa2 = determinize::NFADeterminizer::determinize(nfa2); - - automaton::Automaton mdfa1 = minimize::MinimizeDFA::minimize(dfa1); - automaton::Automaton mdfa2 = minimize::MinimizeDFA::minimize(dfa2); - - CPPUNIT_ASSERT( mdfa1 == mdfa2); -} - -void re2faTest::testGlushkov() { - std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); - - conversions::re2fa::GlushkovNFA glushkov1; - automaton::NFA nfa1 = glushkov1.convert(regexp1); - - regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( conversions::fa2re::Algebraic::convert(nfa1) ) ); - - conversions::re2fa::GlushkovNFA glushkov2; - automaton::NFA nfa2 = glushkov2.convert(regexp2); - - automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1); - automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2); - - automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1); - automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2); - - CPPUNIT_ASSERT( mdfa1 == mdfa2); -} - -void re2faTest::testBrzozowski() { - std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp1( parser.parseValue() ); - - automaton::Automaton nfa1 = conversions::re2fa::BrzozowskiDerivation::convert(regexp1); - - regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) ); - - automaton::Automaton nfa2 = conversions::re2fa::BrzozowskiDerivation::convert(regexp2); - - automaton::DFA mdfa1_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa1.getData())); - automaton::DFA mdfa1_2 = minimize::MinimizeDFA::minimize(mdfa1_1); - automaton::DFA mdfa1_3 = normalize::NormalizeDFA::normalize(mdfa1_2); - - automaton::DFA mdfa2_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa2.getData())); - automaton::DFA mdfa2_2 = minimize::MinimizeDFA::minimize(mdfa2_1); - automaton::DFA mdfa2_3 = normalize::NormalizeDFA::normalize(mdfa2_2); - - CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3); -} diff --git a/alib2algo/test-src/grammar/GrammarPropertiesTest.cpp b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp similarity index 78% rename from alib2algo/test-src/grammar/GrammarPropertiesTest.cpp rename to alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp index d3f8019d1bd33a7ddf3f4d824adc920517dd72c0..dcc23b4012cf396551bb9bdea178d5398cbafe9b 100644 --- a/alib2algo/test-src/grammar/GrammarPropertiesTest.cpp +++ b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp @@ -5,7 +5,8 @@ #include <alphabet/LabeledSymbol.h> #include <alphabet/Symbol.h> -#include "grammar/GrammarPropertiesCFG.h" +#include "grammar/properties/NullableNonterminals.h" +#include "grammar/properties/NonterminalUnitRuleCycle.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -36,7 +37,7 @@ void GrammarPropertiesTest::testNullable() { grammar.addRule(Z, std::vector<alphabet::Symbol>{ X, Y, Z }); std::set<alphabet::Symbol> res = {X, Y}; - CPPUNIT_ASSERT(res == grammar::GrammarPropertiesCFG::getNullableNonterminals(grammar)); + CPPUNIT_ASSERT(res == grammar::properties::NullableNonterminals::getNullableNonterminals(grammar)); } void GrammarPropertiesTest::testUnitRules() { @@ -67,8 +68,8 @@ void GrammarPropertiesTest::testUnitRules() { std::set<alphabet::Symbol> N_B = {B}; std::set<alphabet::Symbol> N_C = {C}; - CPPUNIT_ASSERT(N_S == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, S)); - CPPUNIT_ASSERT(N_A == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, A)); - CPPUNIT_ASSERT(N_B == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, B)); - CPPUNIT_ASSERT(N_C == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, C)); + CPPUNIT_ASSERT(N_S == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, S)); + CPPUNIT_ASSERT(N_A == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, A)); + CPPUNIT_ASSERT(N_B == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, B)); + CPPUNIT_ASSERT(N_C == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, C)); } diff --git a/alib2algo/test-src/grammar/GrammarPropertiesTest.h b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.h similarity index 100% rename from alib2algo/test-src/grammar/GrammarPropertiesTest.h rename to alib2algo/test-src/grammar/properties/GrammarPropertiesTest.h diff --git a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp similarity index 91% rename from alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp rename to alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp index 42bb8b4a644d69cae0feefcb14e4147e9ef81a35..ebf7a14df0cd2755058c0f973ce4c4e695c6cac5 100644 --- a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp +++ b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp @@ -1,8 +1,8 @@ #include <list> #include "rg2rgTest.h" -#include "conversions/rg2rg/RightToLeftRegularGrammar.h" -#include "conversions/rg2rg/LeftToRightRegularGrammar.h" +#include "grammar/convert/ToGrammarLeftRG.h" +#include "grammar/convert/ToGrammarRightRG.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -27,7 +27,7 @@ void rg2rgTest::testConversion() { rrGrammar.addRule(alphabet::symbolFrom(2), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(3))); rrGrammar.addRule(alphabet::symbolFrom(3), alphabet::symbolFrom("a")); - grammar::LeftRG lrGrammar = conversions::rg2rg::RightToLeftRegularGrammar::convert(rrGrammar); + grammar::LeftRG lrGrammar = grammar::convert::ToGrammarLeftRG::convert(rrGrammar); grammar::LeftRG lrGrammarRef(alphabet::symbolFrom(4)); @@ -58,7 +58,7 @@ void rg2rgTest::testConversion2() { lrGrammar.addRule(alphabet::symbolFrom(3), std::make_pair(alphabet::symbolFrom(2), alphabet::symbolFrom("b"))); lrGrammar.addRule(alphabet::symbolFrom(4), std::make_pair(alphabet::symbolFrom(3), alphabet::symbolFrom("a"))); - grammar::RightRG rrGrammar = conversions::rg2rg::LeftToRightRegularGrammar::convert(lrGrammar); + grammar::RightRG rrGrammar = grammar::convert::ToGrammarRightRG::convert(lrGrammar); grammar::RightRG rrGrammarRef(alphabet::symbolFrom(5)); diff --git a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.h b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.h similarity index 100% rename from alib2algo/test-src/conversions/rg2rg/rg2rgTest.h rename to alib2algo/test-src/grammar/toGrammar/rg2rgTest.h diff --git a/alib2algo/test-src/conversions/playTest.cpp b/alib2algo/test-src/playTest.cpp similarity index 71% rename from alib2algo/test-src/conversions/playTest.cpp rename to alib2algo/test-src/playTest.cpp index 9931f8f8794d4241bc4db1e50e4212280fddc789..82c3c242baab48d1d7af6a09cd14b94ac0e26b27 100644 --- a/alib2algo/test-src/conversions/playTest.cpp +++ b/alib2algo/test-src/playTest.cpp @@ -4,14 +4,12 @@ #include <cstdlib> #include <ctime> -#include "determinize/nfa/NFADeterminizer.h" -#include "minimize/dfa/MinimizeDFA.h" - -#include "generator/RandomAutomatonFactory.h" -#include "normalize/dfa/NormalizeDFA.h" -#include "trim/automaton/Trim.h" -#include "epsilon/fsm/FSMEpsilonRemover.h" -#include "minimize/dfa/MinimizeDFA.h" +#include "automaton/determinize/Determinize.h" +#include "automaton/generate/RandomAutomatonFactory.h" +#include "automaton/simplify/Minimize.h" +#include "automaton/simplify/Normalize.h" +#include "automaton/simplify/Trim.h" +#include "automaton/simplify/EpsilonRemover.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -31,7 +29,7 @@ void playTest::tearDown(){} automaton::NFA playTest::randomNFA(void) const { - return generator::RandomAutomatonFactory::generateNFA( + return automaton::generate::RandomAutomatonFactory::generateNFA( rand() % TEST_AUTOMATON_STATES_MAX + 1, rand() % TEST_AUTOMATON_ALPHABET_MAX + 1, static_cast<double> (rand()) / (static_cast<double> (RAND_MAX/TEST_AUTOMATON_DENSITY_MAX)) @@ -40,12 +38,12 @@ automaton::NFA playTest::randomNFA(void) const automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const { - automaton::NFA nfa = epsilon::FSMEpsilonRemover::remove(automaton); - nfa = trim::Trim::trim(nfa); - automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa); - dfa = trim::Trim::trim(dfa); - dfa = minimize::MinimizeDFA::minimize(dfa); - dfa = normalize::NormalizeDFA::normalize(dfa); + automaton::NFA nfa = automaton::simplify::EpsilonRemover::remove(automaton); + nfa = automaton::simplify::Trim::trim(nfa); + automaton::DFA dfa = automaton::determinize::Determinize::determinize(nfa); + dfa = automaton::simplify::Trim::trim(dfa); + dfa = automaton::simplify::Minimize::minimize(dfa); + dfa = automaton::simplify::Normalize::normalize(dfa); return dfa; } diff --git a/alib2algo/test-src/conversions/playTest.h b/alib2algo/test-src/playTest.h similarity index 100% rename from alib2algo/test-src/conversions/playTest.h rename to alib2algo/test-src/playTest.h diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp similarity index 78% rename from alib2algo/test-src/regexp/RegExpEmptyTest.cpp rename to alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp index d451d65689f3eded0b6de2b67ecad26accad47de..bf5dfdb0d2eb2d29e33bed488af62e7c972d2633 100644 --- a/alib2algo/test-src/regexp/RegExpEmptyTest.cpp +++ b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp @@ -1,6 +1,6 @@ #include "RegExpEmptyTest.h" -#include "regexp/RegExpEmpty.h" +#include "regexp/properties/RegExpEmpty.h" #include <sstream> #include <regexp/RegExp.h> @@ -21,7 +21,7 @@ void RegExpEmptyTest::testRegExpEmpty() { regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(regexp::RegExpEmpty::languageIsEmpty(re)); + CPPUNIT_ASSERT(regexp::properties::RegExpEmpty::languageIsEmpty(re)); } { std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )"; @@ -29,6 +29,6 @@ void RegExpEmptyTest::testRegExpEmpty() { regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(! regexp::RegExpEmpty::languageIsEmpty(re)); + CPPUNIT_ASSERT(! regexp::properties::RegExpEmpty::languageIsEmpty(re)); } } diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.h b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpEmptyTest.h rename to alib2algo/test-src/regexp/properties/RegExpEmptyTest.h diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp similarity index 69% rename from alib2algo/test-src/regexp/RegExpEpsilonTest.cpp rename to alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp index 86e177beb8af91690b5535d0f35e19bba1604bd3..05c2af2065968df9099cdaed0aa53ef92ca67c56 100644 --- a/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp +++ b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp @@ -1,6 +1,6 @@ #include "RegExpEpsilonTest.h" -#include "regexp/RegExpEpsilon.h" +#include "regexp/properties/RegExpEpsilon.h" #include <sstream> #include <regexp/RegExpFromStringParser.h> @@ -20,54 +20,54 @@ void RegExpEpsilonTest::testRegExpEpsilon() { regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "( a* )( a* )"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "a + #0"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "#E + a #E + a*"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "a* a*"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "a s d #E + #E #0"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } { std::string input = "a + #0"; std::stringstream inputs(input); regexp::RegExpFromStringParser parser(inputs); regexp::RegExp re = parser.parseValue(); - CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re)); - } + CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); + } } diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.h b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpEpsilonTest.h rename to alib2algo/test-src/regexp/properties/RegExpEpsilonTest.h diff --git a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp similarity index 88% rename from alib2algo/test-src/regexp/RegExpOptimizeTest.cpp rename to alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp index bbe21afc1d430dbcc739efb3e810cc04ff34df0f..41c7be67a9006ea009c44b3576c81664d859832c 100644 --- a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp +++ b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp @@ -4,7 +4,7 @@ #include "regexp/unbounded/UnboundedRegExp.h" #include "regexp/RegExpFromStringParser.h" -#include "regexp/RegExpOptimize.h" +#include "regexp/simplify/RegExpOptimize.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -25,8 +25,7 @@ void RegExpOptimizeTest::testOptimize() { regexp::RegExpFromStringParser parser(inputs); regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); - regexp::RegExpOptimize opt; - regexp::UnboundedRegExp res = opt.optimize(regexp); + regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp); } { std::string input = "a+a* (b+a)* c"; diff --git a/alib2algo/test-src/regexp/RegExpOptimizeTest.h b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpOptimizeTest.h rename to alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.h diff --git a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d02597094105a569b0e960ce5d3ef3e6d190fa89 --- /dev/null +++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp @@ -0,0 +1,96 @@ +#include <list> +#include "re2faTest.h" + +#include "regexp/convert/ToAutomatonDerivation.h" +#include "regexp/convert/ToAutomatonGlushkov.h" +#include "regexp/convert/ToAutomatonThompson.h" +#include "automaton/convert/ToRegExpAlgebraic.h" +#include "automaton/determinize/Determinize.h" +#include "automaton/simplify/Minimize.h" +#include "automaton/simplify/Normalize.h" +#include "automaton/simplify/EpsilonRemover.h" + +#include "regexp/unbounded/UnboundedRegExp.h" +#include "regexp/RegExpFromStringParser.h" + +#include "automaton/FSM/NFA.h" +#include <factory/DataFactory.hpp> + +CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest ); + +void re2faTest::setUp() { +} + +void re2faTest::tearDown() { +} + +void re2faTest::testThompson() { + std::string input = "a+a* b*"; + std::stringstream inputs(input); + + regexp::RegExpFromStringParser parser(inputs); + regexp::RegExp regexp1( parser.parseValue() ); + + automaton::Automaton enfa1 = regexp::convert::ToAutomatonThompson::convert(regexp1); + + regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::convert(enfa1) ); + + automaton::Automaton enfa2 = regexp::convert::ToAutomatonThompson::convert(regexp2); + + automaton::Automaton nfa1 = automaton::simplify::EpsilonRemover::remove(enfa1); + automaton::Automaton nfa2 = automaton::simplify::EpsilonRemover::remove(enfa2); + + automaton::Automaton dfa1 = automaton::determinize::Determinize::determinize(nfa1); + automaton::Automaton dfa2 = automaton::determinize::Determinize::determinize(nfa2); + + automaton::Automaton mdfa1 = automaton::simplify::Minimize::minimize(dfa1); + automaton::Automaton mdfa2 = automaton::simplify::Minimize::minimize(dfa2); + + CPPUNIT_ASSERT( mdfa1 == mdfa2); +} + +void re2faTest::testGlushkov() { + std::string input = "a+a* b*"; + std::stringstream inputs(input); + + regexp::RegExpFromStringParser parser(inputs); + regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + + automaton::NFA nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1); + + regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) ); + + automaton::NFA nfa2 = regexp::convert::ToAutomatonGlushkov::convert(regexp2); + + automaton::DFA dfa1 = automaton::determinize::Determinize::determinize(nfa1); + automaton::DFA dfa2 = automaton::determinize::Determinize::determinize(nfa2); + + automaton::DFA mdfa1 = automaton::simplify::Minimize::minimize(dfa1); + automaton::DFA mdfa2 = automaton::simplify::Minimize::minimize(dfa2); + + CPPUNIT_ASSERT( mdfa1 == mdfa2); +} + +void re2faTest::testBrzozowski() { + std::string input = "a+a* b*"; + std::stringstream inputs(input); + + regexp::RegExpFromStringParser parser(inputs); + regexp::RegExp regexp1( parser.parseValue() ); + + automaton::Automaton nfa1 = regexp::convert::ToAutomatonDerivation::convert(regexp1); + + regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) ); + + automaton::Automaton nfa2 = regexp::convert::ToAutomatonDerivation::convert(regexp2); + + automaton::DFA mdfa1_1 = automaton::determinize::Determinize::determinize(static_cast<const automaton::NFA&>(nfa1.getData())); + automaton::DFA mdfa1_2 = automaton::simplify::Minimize::minimize(mdfa1_1); + automaton::DFA mdfa1_3 = automaton::simplify::Normalize::normalize(mdfa1_2); + + automaton::DFA mdfa2_1 = automaton::determinize::Determinize::determinize(static_cast<const automaton::NFA&>(nfa2.getData())); + automaton::DFA mdfa2_2 = automaton::simplify::Minimize::minimize(mdfa2_1); + automaton::DFA mdfa2_3 = automaton::simplify::Normalize::normalize(mdfa2_2); + + CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3); +} diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.h b/alib2algo/test-src/regexp/toAutomaton/re2faTest.h similarity index 100% rename from alib2algo/test-src/conversions/re2fa/re2faTest.h rename to alib2algo/test-src/regexp/toAutomaton/re2faTest.h diff --git a/alib2algo/test-src/regexp/RegExpConcatenateTest.cpp b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp similarity index 98% rename from alib2algo/test-src/regexp/RegExpConcatenateTest.cpp rename to alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp index 531302826131cf14140c72b09f20198dac631133..0f2441f469e218f41409a42723644f9ebfd5f69e 100644 --- a/alib2algo/test-src/regexp/RegExpConcatenateTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp @@ -1,6 +1,6 @@ #include "RegExpConcatenateTest.h" -#include "regexp/RegExpConcatenate.h" +#include "regexp/transform/RegExpConcatenate.h" #include <sstream> #include <regexp/RegExp.h> diff --git a/alib2algo/test-src/regexp/RegExpConcatenateTest.h b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpConcatenateTest.h rename to alib2algo/test-src/regexp/transform/RegExpConcatenateTest.h diff --git a/alib2algo/test-src/regexp/RegExpDerivationTest.cpp b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp similarity index 97% rename from alib2algo/test-src/regexp/RegExpDerivationTest.cpp rename to alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp index cab3743a202371b31a429b810188b1f109f4170a..268a9e20f936b96374d06e57f72eb5c918997a5c 100644 --- a/alib2algo/test-src/regexp/RegExpDerivationTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp @@ -2,7 +2,7 @@ #include "RegExpDerivationTest.h" -#include "regexp/RegExpDerivation.h" +#include "regexp/transform/RegExpDerivation.h" #include <regexp/RegExpFromStringParser.h> #include <regexp/RegExpToStringComposer.h> diff --git a/alib2algo/test-src/regexp/RegExpDerivationTest.h b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpDerivationTest.h rename to alib2algo/test-src/regexp/transform/RegExpDerivationTest.h diff --git a/alib2algo/test-src/regexp/RegExpIntegralTest.cpp b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp similarity index 96% rename from alib2algo/test-src/regexp/RegExpIntegralTest.cpp rename to alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp index fa92bed0de55b13b21347a9361888c5a8a65896c..a4ec1514eebc58aa91f618f0aaa248d04fb38aef 100644 --- a/alib2algo/test-src/regexp/RegExpIntegralTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp @@ -2,7 +2,7 @@ #include "RegExpIntegralTest.h" -#include "regexp/RegExpIntegral.h" +#include "regexp/transform/RegExpIntegral.h" #include <regexp/RegExpFromStringParser.h> #include <regexp/RegExpToStringComposer.h> diff --git a/alib2algo/test-src/regexp/RegExpIntegralTest.h b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.h similarity index 100% rename from alib2algo/test-src/regexp/RegExpIntegralTest.h rename to alib2algo/test-src/regexp/transform/RegExpIntegralTest.h diff --git a/alib2algo/test-src/string/compare/compareTest.cpp b/alib2algo/test-src/string/compare/compareTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d75ef51ca8a3414a4b7b5eea6e901d5e1c099851 --- /dev/null +++ b/alib2algo/test-src/string/compare/compareTest.cpp @@ -0,0 +1,33 @@ +#include <list> +#include "compareTest.h" + +#include "string/compare/CyclicStringCompare.h" +#include "string/LinearString.h" + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( compareTest ); + +void compareTest::setUp() { +} + +void compareTest::tearDown() { +} + +void compareTest::testCyclicStringCompareBoolean() { + string::LinearString str1("alfa"); + string::LinearString str2("aalf"); + str2.addSymbolsToAlphabet(str1.getAlphabet()); + str1.addSymbolsToAlphabet(str2.getAlphabet()); + + CPPUNIT_ASSERT(string::compare::CyclicStringCompare::equals(str1, str2)); +} + +void compareTest::testCyclicStringCompareInt() { + string::LinearString str1("alfa"); + string::LinearString str2("aalf"); + str2.addSymbolsToAlphabet(str1.getAlphabet()); + str1.addSymbolsToAlphabet(str2.getAlphabet()); + + CPPUNIT_ASSERT(string::compare::CyclicStringCompare::compare(str1, str2) == 0); +} diff --git a/alib2algo/test-src/compare/compareTest.h b/alib2algo/test-src/string/compare/compareTest.h similarity index 100% rename from alib2algo/test-src/compare/compareTest.h rename to alib2algo/test-src/string/compare/compareTest.h diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h index cb53ab3f2428175058505e687839b569e31bc2a2..0ff6327c5b07830da28a2b96e53d4eb5ee8f3bd7 100644 --- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h +++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h @@ -13,6 +13,12 @@ namespace regexp { +namespace simplify { + +class RegExpOptimize; + +} /* namespace simplify */ + /** * Represents alternation operator in the regular expression. Contains list of FormalRegExpElement * as operands of the operator. @@ -98,7 +104,7 @@ public: */ virtual void operator>>(std::ostream& out) const; - friend class RegExpOptimize; + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h index 1f539385db24877572a4c93f22fd7c20cc3a0ebd..b88af6b5898241739b62c8517685c9770fa80147 100644 --- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h +++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h @@ -14,6 +14,12 @@ namespace regexp { +namespace simplify { + +class RegExpOptimize; + +} /* namespace simplify */ + /** * Represents concatenation operator in the regular expression. Contains list of FormalRegExpElement * as operands of the operator. @@ -96,7 +102,7 @@ public: */ virtual void operator>>(std::ostream& out) const; - friend class RegExpOptimize; + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h index aa35c9b21c2ca029ad37d1c023825fd894c7367c..9d0629cd7679d693a3e3811dad0541705c8c4ac6 100644 --- a/alib2data/src/regexp/formal/FormalRegExpIteration.h +++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h @@ -13,6 +13,12 @@ namespace regexp { +namespace simplify { + +class RegExpOptimize; + +} /* namespace simplify */ + /** * Represents iteration operator in the regular expression. Contains one FormalRegExpElement * as operand. @@ -91,7 +97,7 @@ public: */ virtual void operator>>(std::ostream& out) const; - friend class RegExpOptimize; + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h index 18b9dec3a776af697f014f46a41278c99ba06b39..ab78cbfdac74d2f6e2a7b8b4b349a22337c05ea1 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h @@ -13,8 +13,12 @@ namespace regexp { +namespace simplify { + class RegExpOptimize; +} /* namespace simplify */ + /** * Represents alternation operator in the regular expression. Contains list of UnboundedRegExpElement * as operands of the operator. @@ -94,7 +98,7 @@ public: */ virtual void operator>>(std::ostream& out) const; - friend class RegExpOptimize; + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h index feb155a2eb9cbfdb123dc38b3e371552da260bea..04314dfad668306318fc7fbc8d5b2cc7452a1469 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h @@ -13,8 +13,12 @@ namespace regexp { +namespace simplify { + class RegExpOptimize; +} /* namespace simplify */ + /** * Represents concatenation operator in the regular expression. Contains list of UnboundedRegExpElement * as operands of the operator. @@ -92,8 +96,8 @@ public: * @copydoc UnboundedRegExpElement::operator>>() const */ virtual void operator>>(std::ostream& out) const; - - friend class RegExpOptimize; + + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h index 55b53447b360e77d5e0debe9a0977ad8faee3547..26901d9629db18efcb720fa1a0a1f0c73886ddd5 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h @@ -13,8 +13,12 @@ namespace regexp { +namespace simplify { + class RegExpOptimize; +} /* namespace simplify */ + /** * Represents iteration operator in the regular expression. Contains one UnboundedRegExpElement * as operand. @@ -92,7 +96,7 @@ public: */ virtual void operator>>(std::ostream& out) const; - friend class RegExpOptimize; + friend class simplify::RegExpOptimize; virtual operator std::string() const; diff --git a/aminimize2/src/aminimize.cpp b/aminimize2/src/aminimize.cpp index b2c963e5e4ba9d0055b2da791c8ed2b4b87a1719..db1764078fdefe2cf45788cb8c1610f1c282730b 100644 --- a/aminimize2/src/aminimize.cpp +++ b/aminimize2/src/aminimize.cpp @@ -8,7 +8,7 @@ #include <exception/AlibException.h> #include <factory/DataFactory.hpp> -#include "minimize/dfa/MinimizeDFA.h" +#include "automaton/simplify/Minimize.h" int main(int argc, char** argv) { @@ -17,9 +17,9 @@ int main(int argc, char** argv) { std::cout << "Automaton minimize." << std::endl << "Usage: aminimize automaton.xml" << std::endl; return -1; } else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) { - alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>())); + alib::DataFactory::toStdout(automaton::simplify::Minimize::minimize(alib::DataFactory::fromStdin<automaton::Automaton>())); } else if (argc == 2) { - alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>())); + alib::DataFactory::toStdout(automaton::simplify::Minimize::minimize(alib::DataFactory::fromFile<automaton::Automaton>(argv[1]))); } else { std::cout << "Automaton minimize require deterministic finite automaton" << std::endl; return 1; diff --git a/anormalize2/src/anormalize.cpp b/anormalize2/src/anormalize.cpp index 0c76be0727c4378c6b59953a7e04254d5db3b60a..66763a09ae2a399e99dd394cd6db85c0ff135971 100644 --- a/anormalize2/src/anormalize.cpp +++ b/anormalize2/src/anormalize.cpp @@ -9,7 +9,7 @@ #include "exception/AlibException.h" #include "factory/DataFactory.hpp" -#include "normalize/dfa/NormalizeDFA.h" +#include "automaton/simplify/Normalize.h" int main(int argc, char** argv) { @@ -29,7 +29,7 @@ int main(int argc, char** argv) { return 1; } - automaton::DFA res = normalize::NormalizeDFA::normalize(*automatonPointer); + automaton::DFA res = automaton::simplify::Normalize::normalize(*automatonPointer); alib::DataFactory::toStdout(res); delete automatonPointer; diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp index ca55037be601a3b3028cfb82f7fdd410e4c0ea13..316e99a031900f7404b8576b6f79940a6cfa2b56 100644 --- a/arand2/src/arand.cpp +++ b/arand2/src/arand.cpp @@ -15,8 +15,8 @@ #include <automaton/FSM/NFA.h> #include <regexp/unbounded/UnboundedRegExp.h> #include <factory/DataFactory.hpp> -#include "generator/RandomAutomatonFactory.h" -#include "generator/RandomRegExpFactory.h" +#include "automaton/generate/RandomAutomatonFactory.h" +#include "regexp/generate/RandomRegExpFactory.h" void help( void ) { @@ -116,7 +116,7 @@ int main(int argc, char* argv[]) return 1; } - automaton::NFA res = generator::RandomAutomatonFactory::generateNFA( statesCount, alphabetSize, density ); + automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA( statesCount, alphabetSize, density ); alib::DataFactory::toStdout(res); } else if( type == "RE" ) { @@ -139,7 +139,7 @@ int main(int argc, char* argv[]) return 1; } - regexp::UnboundedRegExp res = generator::RandomRegExpFactory::generateUnboundedRegExp(leafNodes, height, alphabetSize ); + regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp(leafNodes, height, alphabetSize ); alib::DataFactory::toStdout(res); } diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp index cf10cfcc21da413d6ea63245fb3bf1891b2e6121..5c4c11f8a360c8a955476ccbc77c6b03446b965f 100644 --- a/atrim2/src/atrim.cpp +++ b/atrim2/src/atrim.cpp @@ -4,11 +4,13 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "trim/grammar/TrimCFG.h" -#include "trim/automaton/Trim.h" -#include "trim/automaton/UselessStatesRemover.h" -#include "trim/automaton/UnreachableStatesRemover.h" -#include "regexp/RegExpOptimize.h" +#include "grammar/simplify/Trim.h" +#include "grammar/simplify/UnproductiveSymbolsRemover.h" +#include "grammar/simplify/UnreachableSymbolsRemover.h" +#include "automaton/simplify/Trim.h" +#include "automaton/simplify/UselessStatesRemover.h" +#include "automaton/simplify/UnreachableStatesRemover.h" +#include "regexp/simplify/RegExpOptimize.h" void help( void ) { std::cout << "atrim 0.01" << std::endl; @@ -23,64 +25,28 @@ void help( void ) { std::cout << std::endl; } -template<typename T> -grammar::GrammarBase* dynamicTrim(const grammar::Grammar& g, bool del_unreachable, bool del_useless) { - const T* gp = dynamic_cast<const T*>(&g.getData()); - - if(gp) { - T res(*gp); - if( del_unreachable ) - res = trim::TrimCFG::removeUnreachableSymbols( res ); - if( del_useless ) - res = trim::TrimCFG::removeUnproductiveSymbols( res ); - return std::move(res).plunder(); - } else { - return NULL; - } -} - -grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_useless) { - grammar::GrammarBase* res = NULL; - - res = dynamicTrim<grammar::CFG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::EpsilonFreeCFG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::GNF>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::CNF>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::LeftLG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::LeftRG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::RightLG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - res = dynamicTrim<grammar::RightRG>(g, del_unreachable, del_useless); - if(res) return grammar::Grammar(*res); - - throw exception::AlibException("Unsupported grammar type"); +grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_unproductive) { + if( del_unreachable && del_unproductive ) + return grammar::simplify::Trim::trim( g ); + if( del_unreachable ) + return grammar::simplify::UnreachableSymbolsRemover::remove( g ); + if( del_unproductive ) + return grammar::simplify::UnproductiveSymbolsRemover::remove( g ); + return g; } automaton::Automaton trimAutomaton(const automaton::Automaton& g, bool del_unreachable, bool del_useless) { if( del_unreachable && del_useless ) - return trim::Trim::trim( g ); + return automaton::simplify::Trim::trim( g ); if( del_unreachable ) - return trim::UnreachableStatesRemover::remove( g ); + return automaton::simplify::UnreachableStatesRemover::remove( g ); if( del_useless ) - return trim::UnreachableStatesRemover::remove( g ); + return automaton::simplify::UselessStatesRemover::remove( g ); return g; } regexp::RegExp optimizeRegExp(const regexp::RegExp& r) { - return regexp::RegExpOptimize::optimize( r ); + return regexp::simplify::RegExpOptimize::optimize( r ); } int main(int argc, char* argv[]) {