diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index 19b682589707be7a3698400624d49b0bbdca8080..064a18fa3f840e7ad55b4874107b507f5bee1029 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -7,16 +7,15 @@ #include "ConversionHandler.h" -#include "automaton/toRegexp/StateElimination.h" -#include "automaton/toRegexp/Algebraic.h" +#include "automaton/convert/ToRegExpStateElimination.h" +#include "automaton/convert/ToRegExpAlgebraic.h" +#include "automaton/convert/ToLeftRG.h" +#include "automaton/convert/ToRightRG.h" #include "regexp/toAutomaton/GlushkovNFA.h" #include "regexp/toAutomaton/Thompson.h" #include "regexp/toAutomaton/BrzozowskiDerivation.h" -#include "automaton/toGrammar/fa2lrg/FAtoLRGConverter.h" -#include "automaton/toGrammar/fa2rrg/FAtoRRGConverter.h" - #include "grammar/toAutomaton/RGtoFA.h" #include "grammar/toRegexp/Algebraic.h" @@ -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::ToRightRG::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::ToLeftRG::convert(fsm)); break; } } diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp index 518323f0b72ffb4bfc5bd229ae3a95f2941350fa..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 "automaton/simplify/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/alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/automaton/convert/ToLeftRG.cpp similarity index 78% rename from alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.cpp rename to alib2algo/src/automaton/convert/ToLeftRG.cpp index 5fffa8038cc2c02c8d46eb9d80d2630e6fe572f9..aa2672d61f70c94433e7bb7705e420c6eeeb3cba 100644 --- a/alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.cpp +++ b/alib2algo/src/automaton/convert/ToLeftRG.cpp @@ -1,17 +1,22 @@ -#include "FAtoLRGConverter.h" +/* + * ToLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#include "ToLeftRG.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 ToLeftRG::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 ToLeftRG::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 ToLeftRG::convert(const automaton::Automaton& automaton) { grammar::Grammar* out = NULL; - automaton.getData().Accept((void*) &out, FAtoLRGConverter::FA_TO_LRG_CONVERTER); + automaton.getData().Accept((void*) &out, ToLeftRG::TO_LEFT_RG); grammar::Grammar res = std::move(*out); delete out; return res; } -void FAtoLRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const { +void ToLeftRG::Visit(void*, const automaton::EpsilonNFA& ) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void FAtoLRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const { +void ToLeftRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void FAtoLRGConverter::Visit(void* data, const automaton::NFA& automaton) const { +void ToLeftRG::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 ToLeftRG::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 ToLeftRG::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FAtoLRGConverter::Visit(void*, const automaton::CompactNFA& ) const { +void ToLeftRG::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const FAtoLRGConverter FAtoLRGConverter::FA_TO_LRG_CONVERTER; +const ToLeftRG ToLeftRG::TO_LEFT_RG; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/automaton/convert/ToLeftRG.h similarity index 73% rename from alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.h rename to alib2algo/src/automaton/convert/ToLeftRG.h index 37056683d83d9f8b557e7e2b2ef7ebf461f800e2..881e35f73f9e6a6cded110a8ebb25663b754d338 100644 --- a/alib2algo/src/automaton/toGrammar/fa2lrg/FAtoLRGConverter.h +++ b/alib2algo/src/automaton/convert/ToLeftRG.h @@ -1,5 +1,12 @@ -#ifndef __FATOLRGCONVERTER_H__ -#define __FATOLRGCONVERTER_H__ +/* + * ToLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#ifndef __TO_LEFT_RG_H__ +#define __TO_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 ToLeftRG : 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 ToLeftRG TO_LEFT_RG; }; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* __FATOLRGCONVERTER_H__ */ +#endif /* __TO_LEFT_RG_H__ */ diff --git a/alib2algo/src/automaton/toRegexp/Algebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp similarity index 79% rename from alib2algo/src/automaton/toRegexp/Algebraic.cpp rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp index 959996376c9d64e233fc5fabadd70c5d6df70738..49711c8239066135fb061bad75f5ca1465b2b115 100644 --- a/alib2algo/src/automaton/toRegexp/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/automaton/toRegexp/Algebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h similarity index 80% rename from alib2algo/src/automaton/toRegexp/Algebraic.h rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.h index a03bc8a78775eaddc5da14f9a8176a9c2f4c46ad..86ac929536a9a5ece30a2291aa3669addfe67338 100644 --- a/alib2algo/src/automaton/toRegexp/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 TO_REG_EXP_ALGEBRAIC_H_ +#define 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 /* TO_REG_EXP_ALGEBRAIC_H_ */ diff --git a/alib2algo/src/automaton/toRegexp/StateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp similarity index 77% rename from alib2algo/src/automaton/toRegexp/StateElimination.cpp rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp index fd34e15a10191b99a6bce645013c437d7e111685..7de147e0d1d2f0539a457929535d8a4095c1bdfd 100644 --- a/alib2algo/src/automaton/toRegexp/StateElimination.cpp +++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp @@ -1,11 +1,11 @@ /* - * 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> @@ -15,23 +15,21 @@ #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())); @@ -58,7 +56,7 @@ regexp::RegExp StateElimination::convert(const T& automaton) } -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()); @@ -85,7 +83,7 @@ automaton::ExtendedNFA StateElimination::eliminateState(const automaton::Extende 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 { })); @@ -97,7 +95,7 @@ const regexp::RegExp StateElimination::transition(const automaton::ExtendedNFA& return regexp::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 +129,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/automaton/toRegexp/StateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h similarity index 79% rename from alib2algo/src/automaton/toRegexp/StateElimination.h rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.h index ab54785825b8d9aaefa96fb8cceab9030eacb7cb..a70f35786f360798690a08044790f78f12cbb04a 100644 --- a/alib2algo/src/automaton/toRegexp/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/toGrammar/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/automaton/convert/ToRightRG.cpp similarity index 79% rename from alib2algo/src/automaton/toGrammar/fa2rrg/FAtoRRGConverter.cpp rename to alib2algo/src/automaton/convert/ToRightRG.cpp index 4825bf5e7a6667b97b7756c40a9381d8acdd155a..e08935f2f50ccc1067b13f5b758a6272098b0da9 100644 --- a/alib2algo/src/automaton/toGrammar/fa2rrg/FAtoRRGConverter.cpp +++ b/alib2algo/src/automaton/convert/ToRightRG.cpp @@ -1,16 +1,19 @@ -#include "FAtoRRGConverter.h" - +/* + * ToRightRG.cpp + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#include "ToRightRG.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 ToRightRG::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 ToRightRG::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 ToRightRG::convert(const automaton::Automaton& automaton) { grammar::Grammar* out = NULL; - automaton.getData().Accept((void*) &out, FAtoRRGConverter::FA_TO_RRG_CONVERTER); + automaton.getData().Accept((void*) &out, ToRightRG::TO_RIGHT_RG); grammar::Grammar res = std::move(*out); delete out; return res; } -void FAtoRRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const { +void ToRightRG::Visit(void*, const automaton::EpsilonNFA& ) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } -void FAtoRRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const { +void ToRightRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const { throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); } -void FAtoRRGConverter::Visit(void* data, const automaton::NFA& automaton) const { +void ToRightRG::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 ToRightRG::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 ToRightRG::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } -void FAtoRRGConverter::Visit(void*, const automaton::CompactNFA& ) const { +void ToRightRG::Visit(void*, const automaton::CompactNFA& ) const { throw exception::AlibException("Unsupported automaton type CompactNFA"); } -const FAtoRRGConverter FAtoRRGConverter::FA_TO_RRG_CONVERTER; +const ToRightRG ToRightRG::TO_RIGHT_RG; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/toGrammar/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/automaton/convert/ToRightRG.h similarity index 73% rename from alib2algo/src/automaton/toGrammar/fa2rrg/FAtoRRGConverter.h rename to alib2algo/src/automaton/convert/ToRightRG.h index 1c301fc2b62da66b78625d149d0bab4389229cc0..c29795825dc149e94060fbc84f5ac3b0b0ae8f52 100644 --- a/alib2algo/src/automaton/toGrammar/fa2rrg/FAtoRRGConverter.h +++ b/alib2algo/src/automaton/convert/ToRightRG.h @@ -1,5 +1,12 @@ -#ifndef __FATORRGCONVERTER_H__ -#define __FATORRGCONVERTER_H__ +/* + * ToRightRG.h + * + * Created on: 9. 2. 2014 + * Author: Tomas Pecka + */ + +#ifndef __TO_RIGHT_RG_H__ +#define __TO_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 ToRightRG : 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 ToRightRG TO_RIGHT_RG; }; -} /* namespace fa2rg */ +} /* namespace convert */ -} /* namespace conversions */ +} /* namespace automaton */ -#endif /* __FATORRGCONVERTER_H__ */ +#endif /* __TO_RIGHT_RG_H__ */ diff --git a/alib2algo/src/automaton/generator/RandomAutomatonFactory.cpp b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp similarity index 97% rename from alib2algo/src/automaton/generator/RandomAutomatonFactory.cpp rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp index 3bed804ba9ce1cdbb3b91a41367baf1b0d24a656..6aacce65f39fc38f350fe42da960413777057e1e 100644 --- a/alib2algo/src/automaton/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/automaton/generator/RandomAutomatonFactory.h b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h similarity index 87% rename from alib2algo/src/automaton/generator/RandomAutomatonFactory.h rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.h index 3501e45b780c4fb39ddd2e26ce1d6220c50f8678..0f2881e34ac187fd9d26f16969dd93e2a6789d46 100644 --- a/alib2algo/src/automaton/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/properties/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp index 9a18afd765a950bb330621d0a20728180393121b..91758e4f8672d6bb2779d31e3c4f467a3f4333da 100644 --- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp @@ -23,6 +23,8 @@ 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"); @@ -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/properties/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h index 2d98d57a6b7389067ec88c7fb1c0b632779033c3..eb768f772a770a47cb9a4547c72255c476ae121c 100644 --- a/alib2algo/src/automaton/properties/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/properties/UnreachableStates.cpp b/alib2algo/src/automaton/properties/UnreachableStates.cpp index 9e868c8fcd624b0e5ee543779fa56738ddd922c2..fd730f3edc02d1a39921aa28d7dbad8737db6012 100644 --- a/alib2algo/src/automaton/properties/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/properties/UnreachableStates.h b/alib2algo/src/automaton/properties/UnreachableStates.h index e18f17aa9d6343a255cc82cbc0a98e54d7264aa4..d50644c4b792f54b71d30572f0cfb82dceb1cdd6 100644 --- a/alib2algo/src/automaton/properties/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/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp index 68e4837dcad9afc9d4d67a98132ce0a9b076f7c9..83a53781ae67b769a84e42fa7b9b14bc8c294994 100644 --- a/alib2algo/src/automaton/properties/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/properties/UsefullStates.h b/alib2algo/src/automaton/properties/UsefullStates.h index db9a641cb2ca1c0ec1f886d0a1d21570b5597bfa..81a11580298976eeaa14056bce2b453a1dfa1fba 100644 --- a/alib2algo/src/automaton/properties/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/automaton/simplify/FSMEpsilonRemover.cpp b/alib2algo/src/automaton/simplify/EpsilonRemover.cpp similarity index 57% rename from alib2algo/src/automaton/simplify/FSMEpsilonRemover.cpp rename to alib2algo/src/automaton/simplify/EpsilonRemover.cpp index d2b0f108fb82dadc54ac318319725cab9f36e3d5..7435740493845871c3028ad4c788b368305d52ed 100644 --- a/alib2algo/src/automaton/simplify/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 "../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/automaton/simplify/FSMEpsilonRemover.h b/alib2algo/src/automaton/simplify/EpsilonRemover.h similarity index 84% rename from alib2algo/src/automaton/simplify/FSMEpsilonRemover.h rename to alib2algo/src/automaton/simplify/EpsilonRemover.h index 380deb2c814487e2476088e71d774aed3fdec8cd..38aa69f2e356ef0011ae618a8ffaa621a250b325 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/MinimizeDFA.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp similarity index 82% rename from alib2algo/src/automaton/simplify/MinimizeDFA.cpp rename to alib2algo/src/automaton/simplify/Minimize.cpp index 4f60e53c71c74fafd0b9a1fe8d323e21b0bd0d17..548354a3d65b95256027b3cf0e37ed4ba0e8d084 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/MinimizeDFA.h b/alib2algo/src/automaton/simplify/Minimize.h similarity index 84% rename from alib2algo/src/automaton/simplify/MinimizeDFA.h rename to alib2algo/src/automaton/simplify/Minimize.h index 01e2d9d8033ac3083c0b73fcbbf29333874bec82..cc16d9f6200d94fcae80febf1c920f11afe201ab 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/NormalizeDFA.cpp b/alib2algo/src/automaton/simplify/Normalize.cpp similarity index 90% rename from alib2algo/src/automaton/simplify/NormalizeDFA.cpp rename to alib2algo/src/automaton/simplify/Normalize.cpp index d7b11ef6a5e55f2a45c0beb3d751d7ec70e02b62..1780efd4503954c258aee59cd8b885a7fc39b574 100644 --- a/alib2algo/src/automaton/simplify/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/simplify/NormalizeDFA.h b/alib2algo/src/automaton/simplify/NormalizeDFA.h deleted file mode 100644 index 9980cbad5bc957de97a94e19e2fbc6ac946e8f72..0000000000000000000000000000000000000000 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/FSMSingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp similarity index 60% rename from alib2algo/src/automaton/simplify/FSMSingleInitialState.cpp rename to alib2algo/src/automaton/simplify/SingleInitialState.cpp index b76387d69771b78b60e6732746c8bb3587add580..372b09d47ba5383a649c5852c0edd66e5bc947e6 100644 --- a/alib2algo/src/automaton/simplify/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/simplify/FSMSingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h similarity index 84% rename from alib2algo/src/automaton/simplify/FSMSingleInitialState.h rename to alib2algo/src/automaton/simplify/SingleInitialState.h index ef69e4f093f3f0cd291728876fa7931b0bbc7255..e5b1f6085c2530196514dfc7b907429540eccedf 100644 --- a/alib2algo/src/automaton/simplify/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/simplify/FSMTotal.cpp b/alib2algo/src/automaton/simplify/Total.cpp similarity index 71% rename from alib2algo/src/automaton/simplify/FSMTotal.cpp rename to alib2algo/src/automaton/simplify/Total.cpp index 74cc8ce3aee704291e7a4d1b70f3628cb3b69146..970caa05c824fddf926c731b96b437794e3b4c41 100644 --- a/alib2algo/src/automaton/simplify/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/simplify/FSMTotal.h b/alib2algo/src/automaton/simplify/Total.h similarity index 81% rename from alib2algo/src/automaton/simplify/FSMTotal.h rename to alib2algo/src/automaton/simplify/Total.h index 604ddb74823dcd4111b0a11c652a7a946b1dec16..9730b0b96e28ad005665707d71f2d285695f75e1 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp index 7964bbcc2f8e5faadd8174916a474e4b43e8d67f..416378528dcca262c97a848fc653c92cb5a36f05 100644 --- a/alib2algo/src/automaton/simplify/Trim.cpp +++ b/alib2algo/src/automaton/simplify/Trim.cpp @@ -19,7 +19,9 @@ #include "automaton/common/State.h" #include "automaton/Automaton.h" -namespace trim { +namespace automaton { + +namespace simplify { template<class T> T Trim::trim( const T & fsm ) { @@ -113,5 +115,7 @@ void Trim::Visit(void*, const automaton::OneTapeDTM&) const { const Trim Trim::TRIM; -} +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/simplify/Trim.h b/alib2algo/src/automaton/simplify/Trim.h index 1c88bae446df6df1846654b4d4d4894f6dea2c49..e5c085bd268d6640af6b9157515a836579fa5e64 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp index 6f913f8f6575add36d4b71363375ff2f8f6d48d2..cfab0b7c602f88b987b818f08f6759553b1f6776 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp @@ -20,12 +20,14 @@ #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/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index 2c3143d3a997423395937647d411f454813a728f..1422d99aa9e3d8c8555f0c8af678bc0bb0b291d9 100644 --- a/alib2algo/src/automaton/simplify/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/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp index e7c31d1fb5134fb656ba9a2f1d815d7daddc37f4..540d6723dfd8691e1f06e1fbc726f68783f2a017 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp @@ -20,12 +20,14 @@ #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/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h index 30df905885469fa05ed96de576316c1ea2c66307..dbf462579d108bb3d0eb3e0924c6d1f9a51b2e66 100644 --- a/alib2algo/src/automaton/simplify/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/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/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/grammar/properties/LanguagePropertiesCFG.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h similarity index 68% rename from alib2algo/src/grammar/properties/LanguagePropertiesCFG.h rename to alib2algo/src/grammar/properties/IsLanguageEmpty.h index 5029d5be546d403d6382d25f6b89512955ed1075..8aa3a2e13571e57acb11635b84c3ef7760539d5e 100644 --- a/alib2algo/src/grammar/properties/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/LanguagePropertiesCFG.cpp b/alib2algo/src/grammar/properties/LanguagePropertiesCFG.cpp deleted file mode 100644 index 23070a8688d488286b684b16e81759c446341be5..0000000000000000000000000000000000000000 --- a/alib2algo/src/grammar/properties/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/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/TrimCFG.cpp b/alib2algo/src/grammar/simplify/TrimCFG.cpp deleted file mode 100644 index 0a5fe0f974df1edc42ae7b022db0b4622468a0d5..0000000000000000000000000000000000000000 --- a/alib2algo/src/grammar/simplify/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/grammar/simplify/TrimCFG.h b/alib2algo/src/grammar/simplify/TrimCFG.h deleted file mode 100644 index 3b320cdcd81e328fec37f06feffbf998faa365d9..0000000000000000000000000000000000000000 --- a/alib2algo/src/grammar/simplify/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/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/regexp/generator/RandomRegExpFactory.cpp b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp similarity index 100% rename from alib2algo/src/regexp/generator/RandomRegExpFactory.cpp rename to alib2algo/src/regexp/generate/RandomRegExpFactory.cpp diff --git a/alib2algo/src/regexp/generator/RandomRegExpFactory.h b/alib2algo/src/regexp/generate/RandomRegExpFactory.h similarity index 100% rename from alib2algo/src/regexp/generator/RandomRegExpFactory.h rename to alib2algo/src/regexp/generate/RandomRegExpFactory.h diff --git a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp index fb93f60b8ead7782b9fe72f3eb3326f5081d3c37..e6aacc111501d55f0bc046dbeb5b1abfd5979795 100644 --- a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp +++ b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp @@ -1,8 +1,8 @@ #include "FSMSingleInitialStateTest.h" -#include "automaton/simplify/FSMSingleInitialState.h" +#include "automaton/simplify/SingleInitialState.h" #include "automaton/determinize/nfa/NFADeterminizer.h" -#include "automaton/simplify/NormalizeDFA.h" +#include "automaton/simplify/Normalize.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -33,7 +33,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}); @@ -48,5 +48,5 @@ void FSMSingleInitialStateTest::testSingleInitialState() { automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(automaton2); automaton::DFA dfa3 = determinize::NFADeterminizer::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/simplify/FSMTotalTest.cpp b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp index 4e53aa877f62e42c7632418dd7d278d69cb2ec2f..7e6ba6ab2c652bf696f5b4e901da0882ba65cedc 100644 --- a/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp +++ b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp @@ -2,8 +2,8 @@ #include <automaton/FSM/DFA.h> -#include "automaton/simplify/FSMTotal.h" -#include "automaton/simplify/NormalizeDFA.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/simplify/minimizeTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp index 4c8809dc3e593e8d6122aa8715699722179257b4..f5153ba2896850a7642f3deab3567acd5b425f33 100644 --- a/alib2algo/test-src/automaton/simplify/minimizeTest.cpp +++ b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp @@ -1,7 +1,7 @@ #include <list> #include "minimizeTest.h" -#include "automaton/simplify/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/automaton/simplify/normalizeTest.cpp b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp index 19fdf692f5107744c0e9bccdb1586243147e8d0c..e12bbec861366f3257b4d66c05883c1e0c1f99e4 100644 --- a/alib2algo/test-src/automaton/simplify/normalizeTest.cpp +++ b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp @@ -1,7 +1,7 @@ #include <list> #include "normalizeTest.h" -#include "automaton/simplify/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/automaton/simplify/trimTest.cpp b/alib2algo/test-src/automaton/simplify/trimTest.cpp index 981a29e634847eb847ff29997e240a3ad3dec2e6..a4b46abe0f2eff9d34ceb896442136f5519293c6 100644 --- a/alib2algo/test-src/automaton/simplify/trimTest.cpp +++ b/alib2algo/test-src/automaton/simplify/trimTest.cpp @@ -2,7 +2,7 @@ #include "trimTest.h" #include "automaton/simplify/Trim.h" -#include "grammar/simplify/TrimCFG.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/grammar/properties/GrammarPropertiesTest.cpp b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp index d3f8019d1bd33a7ddf3f4d824adc920517dd72c0..dcc23b4012cf396551bb9bdea178d5398cbafe9b 100644 --- a/alib2algo/test-src/grammar/properties/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/playTest.cpp b/alib2algo/test-src/playTest.cpp index cd691d058e5e95a2535a0349f2cffca8efade37d..6396095747e032b793f278383886db90e8a5793b 100644 --- a/alib2algo/test-src/playTest.cpp +++ b/alib2algo/test-src/playTest.cpp @@ -5,13 +5,11 @@ #include <ctime> #include "automaton/determinize/nfa/NFADeterminizer.h" -#include "automaton/simplify/MinimizeDFA.h" - -#include "automaton/generator/RandomAutomatonFactory.h" -#include "automaton/simplify/NormalizeDFA.h" +#include "automaton/generate/RandomAutomatonFactory.h" +#include "automaton/simplify/Minimize.h" +#include "automaton/simplify/Normalize.h" #include "automaton/simplify/Trim.h" -#include "automaton/simplify/FSMEpsilonRemover.h" -#include "automaton/simplify/MinimizeDFA.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::NFA nfa = automaton::simplify::EpsilonRemover::remove(automaton); + nfa = automaton::simplify::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); + 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/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp index 831e1ee3f9a37b0788cec9a2a68ffa5d86b4c0f0..d24b039525c921e57b097cd85f1f240108bbcc29 100644 --- a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp +++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp @@ -4,11 +4,11 @@ #include "regexp/toAutomaton/BrzozowskiDerivation.h" #include "regexp/toAutomaton/GlushkovNFA.h" #include "regexp/toAutomaton/Thompson.h" -#include "automaton/toRegexp/Algebraic.h" +#include "automaton/convert/ToRegExpAlgebraic.h" #include "automaton/determinize/nfa/NFADeterminizer.h" -#include "automaton/simplify/MinimizeDFA.h" -#include "automaton/simplify/NormalizeDFA.h" -#include "automaton/simplify/FSMEpsilonRemover.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" @@ -33,18 +33,18 @@ void re2faTest::testThompson() { automaton::Automaton enfa1 = conversions::re2fa::Thompson::convert(regexp1); - regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(enfa1) ); + regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::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 nfa1 = automaton::simplify::EpsilonRemover::remove(enfa1); + automaton::Automaton nfa2 = automaton::simplify::EpsilonRemover::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); + automaton::Automaton mdfa1 = automaton::simplify::Minimize::minimize(dfa1); + automaton::Automaton mdfa2 = automaton::simplify::Minimize::minimize(dfa2); CPPUNIT_ASSERT( mdfa1 == mdfa2); } @@ -56,10 +56,10 @@ void re2faTest::testGlushkov() { regexp::RegExpFromStringParser parser(inputs); regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); - conversions::re2fa::GlushkovNFA glushkov1; + conversions::re2fa::GlushkovNFA glushkov1; automaton::NFA nfa1 = glushkov1.convert(regexp1); - regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( conversions::fa2re::Algebraic::convert(nfa1) ) ); + regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) ); conversions::re2fa::GlushkovNFA glushkov2; automaton::NFA nfa2 = glushkov2.convert(regexp2); @@ -67,8 +67,8 @@ void re2faTest::testGlushkov() { 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); + automaton::DFA mdfa1 = automaton::simplify::Minimize::minimize(dfa1); + automaton::DFA mdfa2 = automaton::simplify::Minimize::minimize(dfa2); CPPUNIT_ASSERT( mdfa1 == mdfa2); } @@ -82,17 +82,17 @@ void re2faTest::testBrzozowski() { automaton::Automaton nfa1 = conversions::re2fa::BrzozowskiDerivation::convert(regexp1); - regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) ); + regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::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 mdfa1_2 = automaton::simplify::Minimize::minimize(mdfa1_1); + automaton::DFA mdfa1_3 = automaton::simplify::Normalize::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); + 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/aminimize2/src/aminimize.cpp b/aminimize2/src/aminimize.cpp index 99d8f2cc4ec00f8486556e37c9fe1a73b8e941ec..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 "automaton/simplify/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 229b5792c9c63cd9bfd1066cdce459d9b435719d..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 "automaton/simplify/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 b43574ed925802c7aa65f71aab6e6d73683339f3..81bc884f1e1468e047fcb89e51fb4ebb4c360e85 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 "automaton/generator/RandomAutomatonFactory.h" -#include "regexp/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" ) { diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp index e4edcbbd95bc9d1d5db5fa5ee0887df21db290d5..ef96bd61530178b7ae35712fa3d54943b6f35ab1 100644 --- a/atrim2/src/atrim.cpp +++ b/atrim2/src/atrim.cpp @@ -4,7 +4,9 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "grammar/simplify/TrimCFG.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" @@ -23,59 +25,23 @@ 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; }