diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index 0e90d271fbfc9f7f94443ca38f0d815b004b3ffc..f21b211734337ca77178f6a3fc366303dac23639 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -25,8 +25,8 @@ #include "regexp/convert/ToGrammarRightRGGlushkov.h" #include "regexp/convert/ToGrammarRightRGDerivation.h" +#include "rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.h" #include "rte/convert/ToPostfixPushdownAutomatonGlushkov.h" -#include "rte/convert/ToPostfixPushdownAutomatonGlushkovV3.h" #include <factory/XmlDataFactory.hpp> #include <exception/CommonException.h> @@ -342,8 +342,8 @@ void ConversionHandler::convertRTEtoPDA ( void ) { measurements::start ( "Algorithm", measurements::Type::MAIN ); switch ( m_algorithm ) { - case GLUSHKOV_RTE: { - automaton::NPDA < > automaton = rte::convert::ToPostfixPushdownAutomatonGlushkov::convert ( rte ); + case GLUSHKOV_RTE_NAIVE: { + automaton::NPDA < > automaton = rte::convert::ToPostfixPushdownAutomatonGlushkovNaive::convert ( rte ); measurements::end ( ); measurements::start ( "Output write", measurements::Type::AUXILIARY ); @@ -351,8 +351,8 @@ void ConversionHandler::convertRTEtoPDA ( void ) { alib::XmlDataFactory::toStdout ( automaton ); break; } - case GLUSHKOV_RTE_V3: { - automaton::Automaton automaton = rte::convert::ToPostfixPushdownAutomatonGlushkovV3::convert ( rte ); + case GLUSHKOV_RTE: { + automaton::Automaton automaton = rte::convert::ToPostfixPushdownAutomatonGlushkov::convert ( rte ); measurements::end ( ); measurements::start ( "Output write", measurements::Type::AUXILIARY ); @@ -444,9 +444,9 @@ ConversionHandler::TAlgorithm ConversionHandler::parseAlgorithmFromString ( cons if ( algorithm == "bottomup" ) return BOTTOM_UP; - if ( algorithm == "glushkovrte" ) return GLUSHKOV_RTE; + if ( algorithm == "glushkovrtenaive" ) return GLUSHKOV_RTE_NAIVE; - if ( algorithm == "glushkovrtev3" ) return GLUSHKOV_RTE_V3; + if ( algorithm == "glushkovrte" ) return GLUSHKOV_RTE; if ( ( algorithm == "" ) || ( algorithm == "default" ) ) return DEFAULT; diff --git a/aconversions2/src/ConversionHandler.h b/aconversions2/src/ConversionHandler.h index 1961101188bd0c66f366d9c1e1564871d3c76988..e9c61e97ab93676ccfe307c501e197cb291e36f9 100644 --- a/aconversions2/src/ConversionHandler.h +++ b/aconversions2/src/ConversionHandler.h @@ -30,7 +30,7 @@ public: /* CFG to PDA */ BOTTOM_UP, TOP_DOWN, /* RTE to PDA */ - GLUSHKOV_RTE, GLUSHKOV_RTE_V3, + GLUSHKOV_RTE_NAIVE, GLUSHKOV_RTE, }; enum TFormalism { diff --git a/aconversions2/src/aconversion.cpp b/aconversions2/src/aconversion.cpp index 5fc891a875eed141cc3c30e6098789ff0742c5ec..dfaecc8e24f5c79fb279877239594d28d16ed5dc 100644 --- a/aconversions2/src/aconversion.cpp +++ b/aconversions2/src/aconversion.cpp @@ -30,7 +30,7 @@ int main ( int argc, char * argv[] ) { cmd.add ( target ); std::vector < std::string > algorithms { - "algebraic", "elimination", "brzozowski", "glushkov", "thompson", "incoming", "outgoing", "bottomup", "topdown", "default", "glushkovrte", "glushkovrtev3" + "algebraic", "elimination", "brzozowski", "glushkov", "thompson", "incoming", "outgoing", "bottomup", "topdown", "default", "glushkovrtenaive", "glushkovrte" }; TCLAP::ValuesConstraint < std::string > allowedAlgorithms ( algorithms ); TCLAP::ValueArg < std::string > algorithm ( "a", "algorithm", "Specifies algorithm to use", false, "default", & allowedAlgorithms ); diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.cpp b/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.cpp index 4d10836452b4b2a6a46ae4c03fd222e20539876c..638b45232ca5511184e1ceaced24d240b960c6c2 100644 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.cpp +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.cpp @@ -6,7 +6,7 @@ */ #include "ToPostfixPushdownAutomaton.h" -#include "ToPostfixPushdownAutomatonGlushkov.h" +#include "ToPostfixPushdownAutomatonGlushkovNaive.h" #include <exception/CommonException.h> #include <registration/AlgoRegistration.hpp> @@ -19,7 +19,7 @@ automaton::Automaton ToPostfixPushdownAutomaton::convert ( const rte::RTE & rte } automaton::Automaton ToPostfixPushdownAutomaton::convert ( const rte::FormalRTE < > & rte ) { - return automaton::Automaton ( ToPostfixPushdownAutomatonGlushkov::convert ( rte ) ); + return automaton::Automaton ( ToPostfixPushdownAutomatonGlushkovNaive::convert ( rte ) ); } auto ToAutomatonFormalRegExp = registration::OverloadRegister < ToPostfixPushdownAutomaton, automaton::Automaton, rte::FormalRTE < > > ( ToPostfixPushdownAutomaton::convert ); diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.h b/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.h index b0572f93e28425953c6fb71414e47dd474227221..f618d427aad6e104ed083ce8c5d0b7730b811498 100644 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.h +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomaton.h @@ -13,8 +13,6 @@ #include <rte/RTE.h> #include <rte/formal/FormalRTE.h> -// #include <rte/unbounded/UnboundedRegExp.h> - #include <automaton/Automaton.h> namespace rte { diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.cpp b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.cpp index c32399341808fc7225117620564bd5f4a8381f57..bbed287580e01027bcc5551959ad567a252bf807 100644 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.cpp +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.cpp @@ -1,43 +1,42 @@ /* - * ToPostfixPushdownAutomatonGlushkov.h + * ToPostfixPushdownAutomatonGlushkov.cpp * - * Created on: 11. 4. 2016 + * Created on: 26. 7. 2017 * Author: Tomas Pecka */ #include "ToPostfixPushdownAutomatonGlushkov.h" -#include "alphabet/BottomOfTheStackSymbol.h" -#include "alphabet/EndSymbol.h" - #include <automaton/Automaton.h> +#include <alphabet/BottomOfTheStackSymbol.h> +#include <alphabet/EndSymbol.h> -#include "global/GlobalData.h" +#include <global/GlobalData.h> +#include <registration/AlgoRegistration.hpp> #include "../glushkov/GlushkovFollow.h" #include "../glushkov/GlushkovIndexate.h" #include "../glushkov/GlushkovFirst.h" -#include <registration/AlgoRegistration.hpp> +#include "../glushkov/GlushkovSubstitutionMap.h" namespace rte { namespace convert { -automaton::NPDA < > ToPostfixPushdownAutomatonGlushkov::convert ( const rte::RTE & rte ) { +automaton::Automaton ToPostfixPushdownAutomatonGlushkov::convert ( const rte::RTE & rte ) { return dispatch ( rte.getData ( ) ); } -std::vector < DefaultSymbolType > phi ( const std::vector < std::ranked_symbol < > > & follow ) { - return std::transform < DefaultSymbolType > ( follow, []( const std::ranked_symbol < > & symbol ) { return DefaultSymbolType ( alphabet::RankedSymbol < > ( symbol ) ); } ); -} - -bool isSubstSymbolPresent ( const std::set < std::ranked_symbol < > > & container, const std::set < std::ranked_symbol < > > & substAlphabet ) { +template < class SymbolType, class RankType > +bool ToPostfixPushdownAutomatonGlushkov::isSubstSymbolPresent ( const std::set < std::ranked_symbol < SymbolType, RankType > > & container, const TAlphabet < SymbolType, RankType > & substAlphabet ) { std::vector < std::ranked_symbol < > > intersection; std::set_intersection ( container.begin ( ), container.end ( ), substAlphabet.begin ( ), substAlphabet.end ( ), std::back_inserter ( intersection ) ); return intersection.size ( ) > 0; } -automaton::NPDA < > ToPostfixPushdownAutomatonGlushkov::convert ( const rte::FormalRTE < > & rte ) { +template < class SymbolType, class RankType > +automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > +ToPostfixPushdownAutomatonGlushkov::convert ( const rte::FormalRTE < > & rte ) { // step 1; index RTE rte::FormalRTE < > indexedRTE = rte::GlushkovIndexate::index ( rte ); @@ -47,26 +46,31 @@ automaton::NPDA < > ToPostfixPushdownAutomatonGlushkov::convert ( const rte::For const std::set < std::ranked_symbol < > > firstSet = rte::GlushkovFirst::first ( indexedRTE ); // - follow set for every element of (non-indexed) RTE alphabet element - std::map < std::ranked_symbol < >, std::set < std::vector < std::ranked_symbol < > > > > followSet; + const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > substMapTree = GlushkovSubstitutionMap::substMap ( indexedRTE ); + std::map < std::ranked_symbol < >, std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > > followSet; for ( const std::ranked_symbol < > & symbol : indexedRTE.getAlphabet ( ) ) - followSet.insert ( std::make_pair ( symbol, rte::GlushkovFollow::follow ( indexedRTE, symbol ) ) ); + followSet.insert ( std::make_pair ( symbol, rte::GlushkovFollow::follow ( indexedRTE, symbol, substMapTree ) ) ); - /* check for exceptions -> there must be NO substitution symbol in first or follow sets */ + /* check for exceptions -> there must be NO substitution symbol in first set */ if ( isSubstSymbolPresent ( firstSet, rte.getSubstitutionAlphabet ( ) ) ) throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in the first set" ); + /* check end */ - for ( const auto & kv : followSet ) - for ( const auto & followTuple : kv.second ) - if ( isSubstSymbolPresent ( std::set < std::ranked_symbol < > > ( followTuple.begin ( ), followTuple.end ( ) ), rte.getSubstitutionAlphabet ( ) ) ) - throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in a follow set" ); - + /* check for exceptions -> there must be NO substitution symbol in follow sets */ + for ( const std::pair < const std::ranked_symbol < SymbolType, RankType >, std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > > & kv : followSet ) + for ( const GlushkovFollow::TFollowTuple < SymbolType, RankType > & followTuple : kv.second ) // TFollowTuple = vector < set < ranked_symbol > > + for ( const std::set < std::ranked_symbol < SymbolType, RankType > > & followTupleElem : followTuple ) + if ( isSubstSymbolPresent ( followTupleElem, rte.getSubstitutionAlphabet ( ) ) ) + throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in a follow set" ); /* check end */ // step 3; create PDA (w/o transitions yet) and initialize input alphabet = (non-indexed) RTE alphabet and END symbol DefaultStateType q = DefaultStateType ( 'q' ); DefaultStateType f = DefaultStateType ( 'f' ); - automaton::NPDA < > automaton ( q, alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) ); + + auto BotS = std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >::template from < alphabet::BottomOfTheStackSymbol > ( ); + automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > automaton ( q, BotS ); automaton.addState ( f ); automaton.addFinalState ( f ); @@ -76,11 +80,22 @@ automaton::NPDA < > ToPostfixPushdownAutomatonGlushkov::convert ( const rte::For automaton.addInputSymbol ( alphabet::EndSymbol::instance < DefaultSymbolType > ( ) ); - // step 4; create pushdown store alphabet; it consists of elements of indexed RTE alphabet and BotS symbol + // step 4; create pushdown store alphabet; + + // simple for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) - automaton.addPushdownStoreSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) ); + automaton.addPushdownStoreSymbol ( std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > ( { symb } ) ); - /* DEBUG */ + // complex + for ( const std::pair < const rte::FormalRTEElement < SymbolType, RankType >* const, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > & kv : substMapTree ) { + if ( dynamic_cast < const rte::FormalRTESymbolSubst < SymbolType, RankType > * const > ( kv.first ) ) { + for ( const std::pair < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv2 : kv.second ) { + automaton.addPushdownStoreSymbol ( kv2.second ); + } + } + } + + /* DEBUG */ if ( common::GlobalData::verbose ) { std::cerr << "RTE:" << std::endl; @@ -96,47 +111,122 @@ automaton::NPDA < > ToPostfixPushdownAutomatonGlushkov::convert ( const rte::For std::cerr << std::endl; - for ( const auto & kv : followSet ) { + // std::map < std::ranked_symbol < >, std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > > followSet; + for ( const std::pair < const std::ranked_symbol < >, std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > >& kv : followSet ) { std::cerr << "Follow(RTE, " << kv.first << "):" << std::endl; if ( kv.second.empty ( ) ) std::cerr << "\t" << "{}" << std::endl; - for ( const auto & follow : kv.second ) { - for ( const auto & symbol : follow ) - std::cerr << "\t" << symbol << std::endl; + for ( const GlushkovFollow::TFollowTuple < SymbolType, RankType > & followTuple : kv.second ) { // TFollowTuple = vector < set < ranked_symbol > > + std::cerr << " \t - FollowTuple:" << std::endl; + for ( const std::set < std::ranked_symbol < > > & child : followTuple ) + std::cerr << "\t\t - " << child << std::endl; std::cerr << std::endl; } std::cerr << std::endl; } + + std::cerr << "---------------------------------------------------------" << std::endl; + std::cerr << "PDA:" << std::endl; + std::cerr << "pds symbols" << std::endl; + + for ( const auto & symb : automaton.getPushdownStoreAlphabet ( ) ) + std::cerr << "\t" << symb << std::endl; + std::cerr << std::endl; } /* DEBUG END */ + + /* TRANSITIONS */ + // Pattern 3 and 2 for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) { - if ( symb.getRank ( ) == primitive::Unsigned ( 0 ) ) - automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), { }, q, { DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) } ); - else - for ( const std::vector < std::ranked_symbol < > > & follow : followSet[symb] ) { - std::vector < DefaultSymbolType > fstring = phi ( follow ); - std::reverse ( fstring.begin ( ), fstring.end ( ) ); - automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), fstring, q, { DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) } ); + if ( symb.getRank ( ) == primitive::Unsigned ( 0 ) ) { + std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > push; + push.push_back( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); + + if ( common::GlobalData::verbose ) { + std::cerr << "Transition 3: " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << + "\t" << "[]" << std::endl << + "\t ->" << std::endl << + "\t" << push << std::endl << std::endl; } + automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), { }, q, push ); + } else { + for ( const GlushkovFollow::TFollowTuple < SymbolType, RankType > & followTuple : followSet [ symb ] ) { //tuple = vector < set < symb > > + std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop, push; + + /* + for ( const auto & e : symbFollowTuple ) + pop.push_back ( e ); + std::reverse ( pop.begin ( ), pop.end ( ) ); // <------------ WTF. CRASHES HERE // FIXME + */ + for ( const auto & e : followTuple ) + pop.insert ( pop.begin ( ), e ); + + push.push_back( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); + + if ( common::GlobalData::verbose ) { + std::cerr << "Transition 2: " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << + "\t" << pop << std::endl << + "\t ->" << std::endl << + "\t" << push << std::endl << std::endl; + } + automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), pop, q, push ); + } + } + } + + // Pattern 1 + for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) { + for ( const std::pair < const rte::FormalRTEElement < SymbolType, RankType >* const, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > & kv : substMapTree ) { + if ( dynamic_cast < const rte::FormalRTESymbolSubst < SymbolType, RankType > * const > ( kv.first ) == nullptr ) // not a SubstSymbol node + continue; + for ( const std::pair < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv2 : kv.second ) { + if ( kv2.second.count ( symb ) == 0 ) + continue; + + for ( const GlushkovFollow::TFollowTuple < SymbolType, RankType > & symbFollowTuple : followSet [ symb ] ) { + std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop, push; + + if ( ( size_t ) symb.getRank ( ) > 0 ) { + for ( const auto & e : symbFollowTuple ) + pop.insert ( pop.begin ( ), e ); + } + + push.push_back( kv2.second ); + + if ( common::GlobalData::verbose ) { + std::cerr << "Transition 1" << ( pop.empty() ? "a" : "b" ) << ": " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << + "\t" << pop << std::endl << + "\t ->" << std::endl << + "\t" << push << std::endl << std::endl; + } + + automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), pop, q, push ); + } + } + } } + // Final for ( const std::ranked_symbol < > & symb : firstSet ) { - std::vector < DefaultSymbolType > pop; - pop.push_back ( DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) ); - pop.push_back ( alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) ); + std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop; + pop.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); + pop.push_back ( BotS ); automaton.addTransition ( q, alphabet::EndSymbol::instance < DefaultSymbolType > ( ), pop, f, { } ); } + /* TRANSITIONS END */ return automaton; } -auto ToAutomatonGlushkovFormalRegExp = registration::OverloadRegister < ToPostfixPushdownAutomatonGlushkov, automaton::NPDA < >, rte::FormalRTE < > > ( ToPostfixPushdownAutomatonGlushkov::convert ); +auto ToPostfixPushdownAutomatonGlushkovFormalRTE = registration::OverloadRegister < ToPostfixPushdownAutomatonGlushkov, + automaton::NPDA < DefaultSymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < alib::Object, primitive::Unsigned > > >, DefaultStateType >, + rte::FormalRTE < > > ( ToPostfixPushdownAutomatonGlushkov::convert ); } /* namespace convert */ diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.h b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.h index d5ef30cf787f17d3efc248aeb8fa4c5f30dcdf4f..c4181477827bbff3d27786ed7e29fcf70b9085e4 100644 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.h +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkov.h @@ -1,7 +1,7 @@ /* * ToPostfixPushdownAutomatonGlushkov.h * - * Created on: 11. 4. 2016 + * Created on: 26. 7. 2017 * Author: Tomas Pecka */ @@ -11,12 +11,13 @@ #include <core/multipleDispatch.hpp> #include <map> -#include <automaton/FSM/NFA.h> #include <automaton/PDA/NPDA.h> + #include <rte/RTE.h> #include <rte/formal/FormalRTE.h> -// #include <rte/unbounded/UnboundedRegExp.h> +#include <container/ObjectsVariant.h> +#include <container/ObjectsSet.h> namespace rte { @@ -26,19 +27,31 @@ namespace convert { * Converts regular tree expression to real-time height-deterministic pda * Source: Master Thesis, Pecka Tomas, CTU FIT, 2016, chapter 4.2 */ -class ToPostfixPushdownAutomatonGlushkov : public std::SingleDispatch < ToPostfixPushdownAutomatonGlushkov, automaton::NPDA < >, const rte::RTEBase & > { +class ToPostfixPushdownAutomatonGlushkov : public std::SingleDispatch < ToPostfixPushdownAutomatonGlushkov, automaton::Automaton, const rte::RTEBase & > { +private: + // -------------------------------------------------------------------- + + template < class SymbolType, class RankType > + using TAlphabet = std::set < std::ranked_symbol < SymbolType, RankType > >; + + // -------------------------------------------------------------------- + + template < class SymbolType, class RankType > + static bool isSubstSymbolPresent ( const std::set < std::ranked_symbol < SymbolType, RankType > > & container, const TAlphabet < SymbolType, RankType > & substAlphabet ); public: /** * Performs conversion. * @param re Original regular tree expression. * @return rhNPDA equivalent to original regular expression. */ - static automaton::NPDA < > convert ( const rte::RTE & rte ); - static automaton::NPDA < > convert ( const rte::FormalRTE < > & rte ); + static automaton::Automaton convert ( const rte::RTE & rte ); + + template < class SymbolType, class RankType > + static automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > convert ( const rte::FormalRTE < > & rte ); }; } /* namespace convert */ } /* namespace rte */ -#endif /* TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_H_ */ +#endif /* TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_V3_H_ */ diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.cpp b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.cpp new file mode 100644 index 0000000000000000000000000000000000000000..386f93d39efc2496f0a349b3b6495f73e923587c --- /dev/null +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.cpp @@ -0,0 +1,143 @@ +/* + * ToPostfixPushdownAutomatonGlushkovNaive.h + * + * Created on: 11. 4. 2016 + * Author: Tomas Pecka + */ + +#include "ToPostfixPushdownAutomatonGlushkovNaive.h" + +#include "alphabet/BottomOfTheStackSymbol.h" +#include "alphabet/EndSymbol.h" + +#include <automaton/Automaton.h> + +#include "global/GlobalData.h" + +#include "../glushkov/GlushkovFollowNaive.h" +#include "../glushkov/GlushkovIndexate.h" +#include "../glushkov/GlushkovFirst.h" +#include <registration/AlgoRegistration.hpp> + +namespace rte { + +namespace convert { + +automaton::NPDA < > ToPostfixPushdownAutomatonGlushkovNaive::convert ( const rte::RTE & rte ) { + return dispatch ( rte.getData ( ) ); +} + +std::vector < DefaultSymbolType > phi ( const std::vector < std::ranked_symbol < > > & follow ) { + return std::transform < DefaultSymbolType > ( follow, []( const std::ranked_symbol < > & symbol ) { return DefaultSymbolType ( alphabet::RankedSymbol < > ( symbol ) ); } ); +} + +bool isSubstSymbolPresent ( const std::set < std::ranked_symbol < > > & container, const std::set < std::ranked_symbol < > > & substAlphabet ) { + std::vector < std::ranked_symbol < > > intersection; + std::set_intersection ( container.begin ( ), container.end ( ), substAlphabet.begin ( ), substAlphabet.end ( ), std::back_inserter ( intersection ) ); + return intersection.size ( ) > 0; +} + +automaton::NPDA < > ToPostfixPushdownAutomatonGlushkovNaive::convert ( const rte::FormalRTE < > & rte ) { + + // step 1; index RTE + rte::FormalRTE < > indexedRTE = rte::GlushkovIndexate::index ( rte ); + + // step 2; compute: + // - first set + const std::set < std::ranked_symbol < > > firstSet = rte::GlushkovFirst::first ( indexedRTE ); + + // - follow set for every element of (non-indexed) RTE alphabet element + std::map < std::ranked_symbol < >, std::set < std::vector < std::ranked_symbol < > > > > followSet; + + for ( const std::ranked_symbol < > & symbol : indexedRTE.getAlphabet ( ) ) + followSet.insert ( std::make_pair ( symbol, rte::GlushkovFollowNaive::follow ( indexedRTE, symbol ) ) ); + + /* check for exceptions -> there must be NO substitution symbol in first or follow sets */ + if ( isSubstSymbolPresent ( firstSet, rte.getSubstitutionAlphabet ( ) ) ) + throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in the first set" ); + + for ( const auto & kv : followSet ) + for ( const auto & followTuple : kv.second ) + if ( isSubstSymbolPresent ( std::set < std::ranked_symbol < > > ( followTuple.begin ( ), followTuple.end ( ) ), rte.getSubstitutionAlphabet ( ) ) ) + throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in a follow set" ); + + /* check end */ + + // step 3; create PDA (w/o transitions yet) and initialize input alphabet = (non-indexed) RTE alphabet and END symbol + DefaultStateType q = DefaultStateType ( 'q' ); + DefaultStateType f = DefaultStateType ( 'f' ); + automaton::NPDA < > automaton ( q, alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) ); + + automaton.addState ( f ); + automaton.addFinalState ( f ); + + for ( const std::ranked_symbol < > & symbol : rte.getAlphabet ( ) ) + automaton.addInputSymbol ( symbol.getSymbol ( ) ); + + automaton.addInputSymbol ( alphabet::EndSymbol::instance < DefaultSymbolType > ( ) ); + + // step 4; create pushdown store alphabet; it consists of elements of indexed RTE alphabet and BotS symbol + for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) + automaton.addPushdownStoreSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) ); + + /* DEBUG */ + if ( common::GlobalData::verbose ) { + std::cerr << "RTE:" << std::endl; + + for ( const auto & symbol : indexedRTE.getAlphabet ( ) ) + std::cerr << "\t" << symbol << std::endl; + + std::cerr << std::endl; + + std::cerr << "First(RTE):" << std::endl; + + for ( const auto & symbol : firstSet ) + std::cerr << "\t" << symbol << std::endl; + + std::cerr << std::endl; + + for ( const auto & kv : followSet ) { + std::cerr << "Follow(RTE, " << kv.first << "):" << std::endl; + + if ( kv.second.empty ( ) ) + std::cerr << "\t" << "{}" << std::endl; + + for ( const auto & follow : kv.second ) { + for ( const auto & symbol : follow ) + std::cerr << "\t" << symbol << std::endl; + + std::cerr << std::endl; + } + + std::cerr << std::endl; + } + } + /* DEBUG END */ + + for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) { + if ( symb.getRank ( ) == primitive::Unsigned ( 0 ) ) + automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), { }, q, { DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) } ); + else + for ( const std::vector < std::ranked_symbol < > > & follow : followSet[symb] ) { + std::vector < DefaultSymbolType > fstring = phi ( follow ); + std::reverse ( fstring.begin ( ), fstring.end ( ) ); + automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), fstring, q, { DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) } ); + } + + } + + for ( const std::ranked_symbol < > & symb : firstSet ) { + std::vector < DefaultSymbolType > pop; + pop.push_back ( DefaultSymbolType ( alphabet::RankedSymbol < > ( symb ) ) ); + pop.push_back ( alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) ); + automaton.addTransition ( q, alphabet::EndSymbol::instance < DefaultSymbolType > ( ), pop, f, { } ); + } + + return automaton; +} + +auto ToPostfixPushdownAutomatonGlushkovNaiveFormalRTE = registration::OverloadRegister < ToPostfixPushdownAutomatonGlushkovNaive, automaton::NPDA < >, rte::FormalRTE < > > ( ToPostfixPushdownAutomatonGlushkovNaive::convert ); + +} /* namespace convert */ + +} /* namespace rte */ diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.h b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.h new file mode 100644 index 0000000000000000000000000000000000000000..a673c3cd6e143ed8b2018d2f14964a4ef6c23530 --- /dev/null +++ b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovNaive.h @@ -0,0 +1,44 @@ +/* + * ToPostfixPushdownAutomatonGlushkovNaive.h + * + * Created on: 11. 4. 2016 + * Author: Tomas Pecka + */ + +#ifndef TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_NAIVE_H_ +#define TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_NAIVE_H_ + +#include <core/multipleDispatch.hpp> +#include <map> + +#include <automaton/FSM/NFA.h> +#include <automaton/PDA/NPDA.h> +#include <rte/RTE.h> +#include <rte/formal/FormalRTE.h> + +// #include <rte/unbounded/UnboundedRegExp.h> + +namespace rte { + +namespace convert { + +/** + * Converts regular tree expression to real-time height-deterministic pda + * Source: Master Thesis, Pecka Tomas, CTU FIT, 2016, chapter 4.2 + */ +class ToPostfixPushdownAutomatonGlushkovNaive : public std::SingleDispatch < ToPostfixPushdownAutomatonGlushkovNaive, automaton::NPDA < >, const rte::RTEBase & > { +public: + /** + * Performs conversion. + * @param re Original regular tree expression. + * @return rhNPDA equivalent to original regular expression. + */ + static automaton::NPDA < > convert ( const rte::RTE & rte ); + static automaton::NPDA < > convert ( const rte::FormalRTE < > & rte ); +}; + +} /* namespace convert */ + +} /* namespace rte */ + +#endif /* TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_NAIVE_H_ */ diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.cpp b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.cpp deleted file mode 100644 index b3cec97de896f0344ba4f7200cd3b28ec9935e5a..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * ToPostfixPushdownAutomatonGlushkovV3.cpp - * - * Created on: 26. 7. 2017 - * Author: Tomas Pecka - */ - -#include "ToPostfixPushdownAutomatonGlushkovV3.h" - -#include <automaton/Automaton.h> -#include <alphabet/BottomOfTheStackSymbol.h> -#include <alphabet/EndSymbol.h> - -#include <global/GlobalData.h> -#include <registration/AlgoRegistration.hpp> - -#include "../glushkov/GlushkovFollowV3.h" -#include "../glushkov/GlushkovIndexate.h" -#include "../glushkov/GlushkovFirst.h" -#include "../glushkov/GlushkovSubstitutionMap.h" - -namespace rte { - -namespace convert { - -automaton::Automaton ToPostfixPushdownAutomatonGlushkovV3::convert ( const rte::RTE & rte ) { - return dispatch ( rte.getData ( ) ); -} - -template < class SymbolType, class RankType > -bool ToPostfixPushdownAutomatonGlushkovV3::isSubstSymbolPresent ( const std::set < std::ranked_symbol < SymbolType, RankType > > & container, const TAlphabet < SymbolType, RankType > & substAlphabet ) { - std::vector < std::ranked_symbol < > > intersection; - std::set_intersection ( container.begin ( ), container.end ( ), substAlphabet.begin ( ), substAlphabet.end ( ), std::back_inserter ( intersection ) ); - return intersection.size ( ) > 0; -} - -template < class SymbolType, class RankType > -automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > -ToPostfixPushdownAutomatonGlushkovV3::convert ( const rte::FormalRTE < > & rte ) { - - // step 1; index RTE - rte::FormalRTE < > indexedRTE = rte::GlushkovIndexate::index ( rte ); - - // step 2; compute: - // - first set - const std::set < std::ranked_symbol < > > firstSet = rte::GlushkovFirst::first ( indexedRTE ); - - // - follow set for every element of (non-indexed) RTE alphabet element - const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > substMapTree = GlushkovSubstitutionMap::substMap ( indexedRTE ); - std::map < std::ranked_symbol < >, std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > > followSet; - - for ( const std::ranked_symbol < > & symbol : indexedRTE.getAlphabet ( ) ) - followSet.insert ( std::make_pair ( symbol, rte::GlushkovFollowV3::follow ( indexedRTE, symbol, substMapTree ) ) ); - - /* check for exceptions -> there must be NO substitution symbol in first set */ - if ( isSubstSymbolPresent ( firstSet, rte.getSubstitutionAlphabet ( ) ) ) - throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in the first set" ); - /* check end */ - - /* check for exceptions -> there must be NO substitution symbol in follow sets */ - for ( const std::pair < const std::ranked_symbol < SymbolType, RankType >, std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > > & kv : followSet ) - for ( const GlushkovFollowV3::TFollowTuple < SymbolType, RankType > & followTuple : kv.second ) // TFollowTuple = vector < set < ranked_symbol > > - for ( const std::set < std::ranked_symbol < SymbolType, RankType > > & followTupleElem : followTuple ) - if ( isSubstSymbolPresent ( followTupleElem, rte.getSubstitutionAlphabet ( ) ) ) - throw exception::CommonException ( "GlushkovRTE: Substitution symbol appeared in a follow set" ); - /* check end */ - - // step 3; create PDA (w/o transitions yet) and initialize input alphabet = (non-indexed) RTE alphabet and END symbol - DefaultStateType q = DefaultStateType ( 'q' ); - DefaultStateType f = DefaultStateType ( 'f' ); - - auto BotS = std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >::template from < alphabet::BottomOfTheStackSymbol > ( ); - automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > automaton ( q, BotS ); - - automaton.addState ( f ); - automaton.addFinalState ( f ); - - for ( const std::ranked_symbol < > & symbol : rte.getAlphabet ( ) ) - automaton.addInputSymbol ( symbol.getSymbol ( ) ); - - automaton.addInputSymbol ( alphabet::EndSymbol::instance < DefaultSymbolType > ( ) ); - - // step 4; create pushdown store alphabet; - - // simple - for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) - automaton.addPushdownStoreSymbol ( std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > ( { symb } ) ); - - // complex - for ( const std::pair < const rte::FormalRTEElement < SymbolType, RankType >* const, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > & kv : substMapTree ) { - if ( dynamic_cast < const rte::FormalRTESymbolSubst < SymbolType, RankType > * const > ( kv.first ) ) { - for ( const std::pair < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv2 : kv.second ) { - automaton.addPushdownStoreSymbol ( kv2.second ); - } - } - } - - /* DEBUG */ - if ( common::GlobalData::verbose ) { - std::cerr << "RTE:" << std::endl; - - for ( const auto & symbol : indexedRTE.getAlphabet ( ) ) - std::cerr << "\t" << symbol << std::endl; - - std::cerr << std::endl; - - std::cerr << "First(RTE):" << std::endl; - - for ( const auto & symbol : firstSet ) - std::cerr << "\t" << symbol << std::endl; - - std::cerr << std::endl; - - // std::map < std::ranked_symbol < >, std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > > followSet; - for ( const std::pair < const std::ranked_symbol < >, std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > >& kv : followSet ) { - std::cerr << "Follow(RTE, " << kv.first << "):" << std::endl; - - if ( kv.second.empty ( ) ) - std::cerr << "\t" << "{}" << std::endl; - - for ( const GlushkovFollowV3::TFollowTuple < SymbolType, RankType > & followTuple : kv.second ) { // TFollowTuple = vector < set < ranked_symbol > > - std::cerr << " \t - FollowTuple:" << std::endl; - for ( const std::set < std::ranked_symbol < > > & child : followTuple ) - std::cerr << "\t\t - " << child << std::endl; - - std::cerr << std::endl; - } - - std::cerr << std::endl; - } - - std::cerr << "---------------------------------------------------------" << std::endl; - std::cerr << "PDA:" << std::endl; - std::cerr << "pds symbols" << std::endl; - - for ( const auto & symb : automaton.getPushdownStoreAlphabet ( ) ) - std::cerr << "\t" << symb << std::endl; - std::cerr << std::endl; - } - /* DEBUG END */ - - - /* TRANSITIONS */ - // Pattern 3 and 2 - for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) { - if ( symb.getRank ( ) == primitive::Unsigned ( 0 ) ) { - std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > push; - push.push_back( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); - - if ( common::GlobalData::verbose ) { - std::cerr << "Transition 3: " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << - "\t" << "[]" << std::endl << - "\t ->" << std::endl << - "\t" << push << std::endl << std::endl; - } - automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), { }, q, push ); - } else { - for ( const GlushkovFollowV3::TFollowTuple < SymbolType, RankType > & followTuple : followSet [ symb ] ) { //tuple = vector < set < symb > > - std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop, push; - - /* - for ( const auto & e : symbFollowTuple ) - pop.push_back ( e ); - std::reverse ( pop.begin ( ), pop.end ( ) ); // <------------ WTF. CRASHES HERE // FIXME - */ - for ( const auto & e : followTuple ) - pop.insert ( pop.begin ( ), e ); - - push.push_back( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); - - if ( common::GlobalData::verbose ) { - std::cerr << "Transition 2: " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << - "\t" << pop << std::endl << - "\t ->" << std::endl << - "\t" << push << std::endl << std::endl; - } - automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), pop, q, push ); - } - } - } - - // Pattern 1 - for ( const std::ranked_symbol < > & symb : indexedRTE.getAlphabet ( ) ) { - for ( const std::pair < const rte::FormalRTEElement < SymbolType, RankType >* const, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > > & kv : substMapTree ) { - if ( dynamic_cast < const rte::FormalRTESymbolSubst < SymbolType, RankType > * const > ( kv.first ) == nullptr ) // not a SubstSymbol node - continue; - - for ( const std::pair < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv2 : kv.second ) { - if ( kv2.second.count ( symb ) == 0 ) - continue; - - for ( const GlushkovFollowV3::TFollowTuple < SymbolType, RankType > & symbFollowTuple : followSet [ symb ] ) { - std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop, push; - - if ( ( size_t ) symb.getRank ( ) > 0 ) { - for ( const auto & e : symbFollowTuple ) - pop.insert ( pop.begin ( ), e ); - } - - push.push_back( kv2.second ); - - if ( common::GlobalData::verbose ) { - std::cerr << "Transition 1" << ( pop.empty() ? "a" : "b" ) << ": " << rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ) << " | " << std::endl << - "\t" << pop << std::endl << - "\t ->" << std::endl << - "\t" << push << std::endl << std::endl; - } - - automaton.addTransition ( q, rte::GlushkovIndexate::getSymbolFromGlushkovPair ( symb ).getSymbol ( ), pop, q, push ); - } - } - } - } - - // Final - for ( const std::ranked_symbol < > & symb : firstSet ) { - std::vector < std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > > > pop; - pop.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > { symb } ); - pop.push_back ( BotS ); - automaton.addTransition ( q, alphabet::EndSymbol::instance < DefaultSymbolType > ( ), pop, f, { } ); - } - /* TRANSITIONS END */ - - return automaton; -} - -auto ToAutomatonGlushkovFormalRegExpV3 = registration::OverloadRegister < ToPostfixPushdownAutomatonGlushkovV3, - automaton::NPDA < DefaultSymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < alib::Object, primitive::Unsigned > > >, DefaultStateType >, - rte::FormalRTE < > > ( ToPostfixPushdownAutomatonGlushkovV3::convert ); - -} /* namespace convert */ - -} /* namespace rte */ diff --git a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.h b/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.h deleted file mode 100644 index f6f888faff4599166ba9b5061294a7130f6ab568..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/convert/ToPostfixPushdownAutomatonGlushkovV3.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * ToPostfixPushdownAutomatonGlushkovV3.h - * - * Created on: 26. 7. 2017 - * Author: Tomas Pecka - */ - -#ifndef TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_V3_H_ -#define TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_V3_H_ - -#include <core/multipleDispatch.hpp> -#include <map> - -#include <automaton/PDA/NPDA.h> - -#include <rte/RTE.h> -#include <rte/formal/FormalRTE.h> - -#include <container/ObjectsVariant.h> -#include <container/ObjectsSet.h> - -namespace rte { - -namespace convert { - -/** - * Converts regular tree expression to real-time height-deterministic pda - * Source: Master Thesis, Pecka Tomas, CTU FIT, 2016, chapter 4.2 - */ -class ToPostfixPushdownAutomatonGlushkovV3 : public std::SingleDispatch < ToPostfixPushdownAutomatonGlushkovV3, automaton::Automaton, const rte::RTEBase & > { -private: - // -------------------------------------------------------------------- - - template < class SymbolType, class RankType > - using TAlphabet = std::set < std::ranked_symbol < SymbolType, RankType > >; - - // -------------------------------------------------------------------- - - template < class SymbolType, class RankType > - static bool isSubstSymbolPresent ( const std::set < std::ranked_symbol < SymbolType, RankType > > & container, const TAlphabet < SymbolType, RankType > & substAlphabet ); -public: - /** - * Performs conversion. - * @param re Original regular tree expression. - * @return rhNPDA equivalent to original regular expression. - */ - static automaton::Automaton convert ( const rte::RTE & rte ); - - template < class SymbolType, class RankType > - static automaton::NPDA < SymbolType, DefaultEpsilonType, std::variant < alphabet::BottomOfTheStackSymbol, std::set < std::ranked_symbol < SymbolType, RankType > > >, DefaultStateType > convert ( const rte::FormalRTE < > & rte ); -}; - -} /* namespace convert */ - -} /* namespace rte */ - -#endif /* TO_POSTFIX_PUSHDOWN_AUTOMATON_GLUSHKOV_V3_H_ */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFollow.h b/alib2algo/src/rte/glushkov/GlushkovFollow.h index c03d5e5ff1b2886f2941be5dd2d0c2bfa500aef9..88a9f364e9f3a1e4dcd3884be4e8169f56daa61d 100644 --- a/alib2algo/src/rte/glushkov/GlushkovFollow.h +++ b/alib2algo/src/rte/glushkov/GlushkovFollow.h @@ -1,7 +1,7 @@ /* * GlushkovFollow.h * - * Created on: 14. 4. 2016 + * Created on: 26. 7. 2017 * Author: Tomas Pecka */ @@ -27,155 +27,86 @@ namespace rte { class GlushkovFollow { // -------------------------------------------------------------------- +public: template < class SymbolType, class RankType > - using TSubstMap = std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > >; + using TFollowTuple = std::vector < std::set < std::ranked_symbol < SymbolType, RankType > > >; template < class SymbolType, class RankType > using TAlphabet = std::set < std::ranked_symbol < SymbolType, RankType > >; - // -------------------------------------------------------------------- - +private: template < class SymbolType, class RankType > - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ); - - template < class SymbolType, class RankType > - static void preprocessSubMap ( const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ); + using TSubstMap = std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > >; - template < class T > - static std::vector < std::vector < T > > cartesian ( const std::vector < std::vector < T > > & input ); + // -------------------------------------------------------------------- - template < class T > - static void cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ); + template < class SymbolType, class RankType > + static std::set < TFollowTuple < SymbolType, RankType > > replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ); public: /** * @param re rte to probe * @param symbol FormalRTESymbol for which we need the follow(), i.e., Follow(RTE, symbol) + * @param substMapTree Tree substitution mapping from, rte::GlushkovSubstitutionMap::substMap * @return all symbols that can follow specific symbol in word */ template < class SymbolType, class RankType > - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > follow ( const rte::FormalRTE < SymbolType, RankType > & re, const std::ranked_symbol < SymbolType, RankType > & symbol ); + static std::set < TFollowTuple < SymbolType, RankType > > follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::map < const rte::FormalRTEElement < SymbolType, RankType > *, TSubstMap < SymbolType, RankType > > & substMapTree ); template < class SymbolType, class RankType > class Formal { public: - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEElement < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); - static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEElement < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); + }; }; template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol ) { - TSubstMap < SymbolType, RankType > subMap; - - /* Init substitution map, ie \forall a \in K: sub[a] = \emptyset */ - for ( const std::ranked_symbol < SymbolType, RankType > & ssymb : rte.getSubstitutionAlphabet ( ) ) - subMap.insert ( std::make_pair ( ssymb, TAlphabet < SymbolType, RankType > { } ) ); - - /* recursively compute follow */ - return rte.getRTE ( ).getStructure ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbol, rte.getSubstitutionAlphabet ( ), subMap ); +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::map < const rte::FormalRTEElement < SymbolType, RankType > *, TSubstMap < SymbolType, RankType > > & substMapTree ) { + return rte.getRTE ( ).getStructure ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbol, rte.getSubstitutionAlphabet ( ), substMapTree ); } // ----------------------------------------------------------------------------- -template < class T > -void GlushkovFollow::cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ) { - if ( depth == input.size ( ) ) - ret.push_back ( current ); - else - for ( size_t i = 0; i < input[depth].size ( ); i++ ) { - current[depth] = input[depth][i]; - cartesian_rec ( input, ret, current, depth + 1 ); - } -} - -template < class T > -std::vector < std::vector < T > > GlushkovFollow::cartesian ( const std::vector < std::vector < T > > & input ) { - std::vector < std::vector < T > > ret; - std::vector < T > current ( input.size ( ), T ( 0, 0 ) ); - - cartesian_rec ( input, ret, current, 0 ); - - return ret; -} - -/** - * Preprocessing: - * - Let k1, k2 be elements of alphabet K. - * - If k1 is an element of substMap[k2], then copy content of substMap[k1] into substMap[k2] - */ -template < class SymbolType, class RankType > -void GlushkovFollow::preprocessSubMap ( const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { - for ( bool change = true; change; change = false ) - for ( std::pair < const std::ranked_symbol < SymbolType, RankType >, TAlphabet < SymbolType, RankType > > & kv : subMap ) { - TAlphabet < SymbolType, RankType > & substSet = kv.second; - - for ( auto eIter = substSet.begin ( ); eIter != substSet.end ( ); ) { - if ( alphabetK.count ( * eIter ) == 0 ) { - ++eIter; - } else { - auto it = subMap.find ( * eIter ); - size_t oldSize = substSet.size ( ); - substSet.insert ( it->second.begin ( ), it->second.end ( ) ); - change = ( oldSize != substSet.size ( ) ); // something was added - eIter = substSet.erase ( eIter ); - } - } - } -} - template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ) { - TSubstMap < SymbolType, RankType > subMap ( subMap2 ); - preprocessSubMap ( alphabetK, subMap ); +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & children, const TSubstMap < SymbolType, RankType > & subMap ) { + TFollowTuple < SymbolType, RankType > follow; - std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > input; - - for ( const std::ranked_symbol < SymbolType, RankType > & e : follow ) { + for ( const std::ranked_symbol < SymbolType, RankType > & e : children ) { if ( alphabetK.count ( e ) > 0 ) - input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) ); + follow.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) ); else - input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > { e } ); + follow.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > { e } ); } - /* now do the cartesian product on "input" */ - std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > followSet = cartesian ( input ); - return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( followSet.begin ( ), followSet.end ( ) ); + return std::set < TFollowTuple < SymbolType, RankType > > { follow }; } // ----------------------------------------------------------------------------- template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { - std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp; +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { + std::set < TFollowTuple < SymbolType, RankType > > ret, tmp; - tmp = node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + tmp = node.getLeftElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); ret.insert ( tmp.begin ( ), tmp.end ( ) ); - tmp = node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + tmp = node.getRightElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); ret.insert ( tmp.begin ( ), tmp.end ( ) ); return ret; } template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { - - TSubstMap < SymbolType, RankType > subMap2 ( subMap ); - auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); - - itMap->second.clear ( ); - - for ( const auto & s : node.getRightElement ( ).template accept < TAlphabet < SymbolType, RankType >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) ) - itMap->second.insert ( s ); - +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { /* * E sub F * 1. if symbolF in F subtree, then Follow(F, symbolF); @@ -183,26 +114,20 @@ std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > Glushko */ if ( node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) ) - return node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap2 ); + return node.getLeftElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); else - return node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + return node.getRightElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); } template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { - - std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret; - - for ( const auto & s : node.getElement ( ).template accept < TAlphabet < SymbolType, RankType >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) ) - subMap[node.getSubstitutionSymbol ( ).getSymbol ( )].insert ( s ); - - return node.getElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { + return node.getElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); } template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { - std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp; + std::set < TFollowTuple < SymbolType, RankType > > ret, tmp; if ( symbolF == node.getSymbol ( ) ) { std::vector < std::ranked_symbol < SymbolType, RankType > > children; @@ -210,11 +135,11 @@ std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > Glushko for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & c : node.getElements ( ) ) children.push_back ( c->getSymbol ( ) ); - return replaceConstants ( alphabetK, children, subMap ); + return replaceConstants ( alphabetK, children, substMapTree.at( & node )); } for ( const auto & c : node.getElements ( ) ) { - tmp = c->template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + tmp = c->template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); ret.insert ( tmp.begin ( ), tmp.end ( ) ); } @@ -222,13 +147,13 @@ std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > Glushko } template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, TSubstMap < SymbolType, RankType > & /* subMap */ ) { - return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( ); +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbol */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & /* substMapTree */ ) { + return std::set < TFollowTuple < SymbolType, RankType > > ( ); } template < class SymbolType, class RankType > -std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, TSubstMap < SymbolType, RankType > & /* subMap */ ) { - return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( ); +std::set < GlushkovFollow::TFollowTuple < SymbolType, RankType > > GlushkovFollow::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbol */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & /* substMapTree */ ) { + return std::set < TFollowTuple < SymbolType, RankType > > ( ); } } /* namespace rte */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFollowNaive.h b/alib2algo/src/rte/glushkov/GlushkovFollowNaive.h new file mode 100644 index 0000000000000000000000000000000000000000..cfeb0dae9619b50e3c07688a011a7807cb094fb7 --- /dev/null +++ b/alib2algo/src/rte/glushkov/GlushkovFollowNaive.h @@ -0,0 +1,236 @@ +/* + * GlushkovFollowNaive.h + * + * Created on: 14. 4. 2016 + * Author: Tomas Pecka + */ + +#ifndef RTE_GLUSHKOV_FOLLOW_NAIVE_H_ +#define RTE_GLUSHKOV_FOLLOW_NAIVE_H_ + +#include <map> +#include <set> +#include <vector> + +#include <rte/formal/FormalRTE.h> +#include <rte/formal/FormalRTEElements.h> + +#include <alphabet/RankedSymbol.h> + +#include "GlushkovFirst.h" +#include "GlushkovPos.h" +#include <iterator> +#include <vector> + +namespace rte { + +class GlushkovFollowNaive { + + // -------------------------------------------------------------------- + + template < class SymbolType, class RankType > + using TSubstMap = std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > >; + + template < class SymbolType, class RankType > + using TAlphabet = std::set < std::ranked_symbol < SymbolType, RankType > >; + + // -------------------------------------------------------------------- + + template < class SymbolType, class RankType > + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ); + + template < class SymbolType, class RankType > + static void preprocessSubMap ( const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ); + + template < class T > + static std::vector < std::vector < T > > cartesian ( const std::vector < std::vector < T > > & input ); + + template < class T > + static void cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ); + +public: + /** + * @param re rte to probe + * @param symbol FormalRTESymbol for which we need the follow(), i.e., Follow(RTE, symbol) + * @return all symbols that can follow specific symbol in word + */ + template < class SymbolType, class RankType > + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > follow ( const rte::FormalRTE < SymbolType, RankType > & re, const std::ranked_symbol < SymbolType, RankType > & symbol ); + + template < class SymbolType, class RankType > + class Formal { + public: + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEElement < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subM ); + }; + +}; + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol ) { + TSubstMap < SymbolType, RankType > subMap; + + /* Init substitution map, ie \forall a \in K: sub[a] = \emptyset */ + for ( const std::ranked_symbol < SymbolType, RankType > & ssymb : rte.getSubstitutionAlphabet ( ) ) + subMap.insert ( std::make_pair ( ssymb, TAlphabet < SymbolType, RankType > { } ) ); + + /* recursively compute follow */ + return rte.getRTE ( ).getStructure ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbol, rte.getSubstitutionAlphabet ( ), subMap ); +} + +// ----------------------------------------------------------------------------- + +template < class T > +void GlushkovFollowNaive::cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ) { + if ( depth == input.size ( ) ) + ret.push_back ( current ); + else + for ( size_t i = 0; i < input[depth].size ( ); i++ ) { + current[depth] = input[depth][i]; + cartesian_rec ( input, ret, current, depth + 1 ); + } +} + +template < class T > +std::vector < std::vector < T > > GlushkovFollowNaive::cartesian ( const std::vector < std::vector < T > > & input ) { + std::vector < std::vector < T > > ret; + std::vector < T > current ( input.size ( ), T ( 0, 0 ) ); + + cartesian_rec ( input, ret, current, 0 ); + + return ret; +} + +/** + * Preprocessing: + * - Let k1, k2 be elements of alphabet K. + * - If k1 is an element of substMap[k2], then copy content of substMap[k1] into substMap[k2] + */ +template < class SymbolType, class RankType > +void GlushkovFollowNaive::preprocessSubMap ( const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { + for ( bool change = true; change; change = false ) + for ( std::pair < const std::ranked_symbol < SymbolType, RankType >, TAlphabet < SymbolType, RankType > > & kv : subMap ) { + TAlphabet < SymbolType, RankType > & substSet = kv.second; + + for ( auto eIter = substSet.begin ( ); eIter != substSet.end ( ); ) { + if ( alphabetK.count ( * eIter ) == 0 ) { + ++eIter; + } else { + auto it = subMap.find ( * eIter ); + size_t oldSize = substSet.size ( ); + substSet.insert ( it->second.begin ( ), it->second.end ( ) ); + change = ( oldSize != substSet.size ( ) ); // something was added + eIter = substSet.erase ( eIter ); + } + } + } +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ) { + TSubstMap < SymbolType, RankType > subMap ( subMap2 ); + preprocessSubMap ( alphabetK, subMap ); + + std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > input; + + for ( const std::ranked_symbol < SymbolType, RankType > & e : follow ) { + if ( alphabetK.count ( e ) > 0 ) + input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) ); + else + input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > { e } ); + } + + /* now do the cartesian product on "input" */ + std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > followSet = cartesian ( input ); + return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( followSet.begin ( ), followSet.end ( ) ); +} + +// ----------------------------------------------------------------------------- + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { + std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp; + + tmp = node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + tmp = node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + return ret; +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { + + TSubstMap < SymbolType, RankType > subMap2 ( subMap ); + auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); + + itMap->second.clear ( ); + + for ( const auto & s : node.getRightElement ( ).template accept < TAlphabet < SymbolType, RankType >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) ) + itMap->second.insert ( s ); + + /* + * E sub F + * 1. if symbolF in F subtree, then Follow(F, symbolF); + * 2. if symbolF in E subtree, then Follow(E, symbolF); + */ + + if ( node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) ) + return node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap2 ); + else + return node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { + + std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret; + + for ( const auto & s : node.getElement ( ).template accept < TAlphabet < SymbolType, RankType >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) ) + subMap[node.getSubstitutionSymbol ( ).getSymbol ( )].insert ( s ); + + return node.getElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, TSubstMap < SymbolType, RankType > & subMap ) { + + std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp; + + if ( symbolF == node.getSymbol ( ) ) { + std::vector < std::ranked_symbol < SymbolType, RankType > > children; + + for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & c : node.getElements ( ) ) + children.push_back ( c->getSymbol ( ) ); + + return replaceConstants ( alphabetK, children, subMap ); + } + + for ( const auto & c : node.getElements ( ) ) { + tmp = c->template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollowNaive::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + } + + return ret; +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, TSubstMap < SymbolType, RankType > & /* subMap */ ) { + return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( ); +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollowNaive::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, TSubstMap < SymbolType, RankType > & /* subMap */ ) { + return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( ); +} + +} /* namespace rte */ + +#endif /* RTE_GLUSHKOV_FOLLOW_NAIVE_H_ */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFollowV3.h b/alib2algo/src/rte/glushkov/GlushkovFollowV3.h deleted file mode 100644 index 4c33e1f33f271a5c96a9d2f21c57c3d44e21a1f2..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/glushkov/GlushkovFollowV3.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * GlushkovFollowV3.h - * - * Created on: 26. 7. 2017 - * Author: Tomas Pecka - */ - -#ifndef RTE_GLUSHKOV_FOLLOW_V3_H_ -#define RTE_GLUSHKOV_FOLLOW_V3_H_ - -#include <map> -#include <set> -#include <vector> - -#include <rte/formal/FormalRTE.h> -#include <rte/formal/FormalRTEElements.h> - -#include <alphabet/RankedSymbol.h> - -#include "GlushkovFirst.h" -#include "GlushkovPos.h" -#include <iterator> -#include <vector> - -namespace rte { - -class GlushkovFollowV3 { - - // -------------------------------------------------------------------- -public: - - template < class SymbolType, class RankType > - using TFollowTuple = std::vector < std::set < std::ranked_symbol < SymbolType, RankType > > >; - - template < class SymbolType, class RankType > - using TAlphabet = std::set < std::ranked_symbol < SymbolType, RankType > >; - -private: - template < class SymbolType, class RankType > - using TSubstMap = std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > >; - - // -------------------------------------------------------------------- - - template < class SymbolType, class RankType > - static std::set < TFollowTuple < SymbolType, RankType > > replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const TSubstMap < SymbolType, RankType > & subMap2 ); - -public: - /** - * @param re rte to probe - * @param symbol FormalRTESymbol for which we need the follow(), i.e., Follow(RTE, symbol) - * @param substMapTree Tree substitution mapping from, rte::GlushkovSubstitutionMap::substMap - * @return all symbols that can follow specific symbol in word - */ - template < class SymbolType, class RankType > - static std::set < TFollowTuple < SymbolType, RankType > > follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::map < const rte::FormalRTEElement < SymbolType, RankType > *, TSubstMap < SymbolType, RankType > > & substMapTree ); - - template < class SymbolType, class RankType > - class Formal { - public: - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEElement < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - static std::set < TFollowTuple < SymbolType, RankType > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ); - - }; - -}; - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::map < const rte::FormalRTEElement < SymbolType, RankType > *, TSubstMap < SymbolType, RankType > > & substMapTree ) { - return rte.getRTE ( ).getStructure ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbol, rte.getSubstitutionAlphabet ( ), substMapTree ); -} - -// ----------------------------------------------------------------------------- - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::replaceConstants ( const TAlphabet < SymbolType, RankType > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & children, const TSubstMap < SymbolType, RankType > & subMap ) { - TFollowTuple < SymbolType, RankType > follow; - - for ( const std::ranked_symbol < SymbolType, RankType > & e : children ) { - if ( alphabetK.count ( e ) > 0 ) - follow.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) ); - else - follow.push_back ( std::set < std::ranked_symbol < SymbolType, RankType > > { e } ); - } - - return std::set < TFollowTuple < SymbolType, RankType > > { follow }; -} - -// ----------------------------------------------------------------------------- - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { - std::set < TFollowTuple < SymbolType, RankType > > ret, tmp; - - tmp = node.getLeftElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - tmp = node.getRightElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - return ret; -} - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { - /* - * E sub F - * 1. if symbolF in F subtree, then Follow(F, symbolF); - * 2. if symbolF in E subtree, then Follow(E, symbolF); - */ - - if ( node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) ) - return node.getLeftElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); - else - return node.getRightElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); -} - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { - return node.getElement ( ).template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); -} - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const TAlphabet < SymbolType, RankType > & alphabetK, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & substMapTree ) { - - std::set < TFollowTuple < SymbolType, RankType > > ret, tmp; - - if ( symbolF == node.getSymbol ( ) ) { - std::vector < std::ranked_symbol < SymbolType, RankType > > children; - - for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & c : node.getElements ( ) ) - children.push_back ( c->getSymbol ( ) ); - - return replaceConstants ( alphabetK, children, substMapTree.at( & node )); - } - - for ( const auto & c : node.getElements ( ) ) { - tmp = c->template accept < std::set < TFollowTuple < SymbolType, RankType > >, GlushkovFollowV3::Formal < SymbolType, RankType > > ( symbolF, alphabetK, substMapTree ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - } - - return ret; -} - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbol */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & /* substMapTree */ ) { - return std::set < TFollowTuple < SymbolType, RankType > > ( ); -} - -template < class SymbolType, class RankType > -std::set < GlushkovFollowV3::TFollowTuple < SymbolType, RankType > > GlushkovFollowV3::Formal < SymbolType, RankType > ::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbol */, const TAlphabet < SymbolType, RankType > & /* alphabetK */, const std::map < const rte::FormalRTEElement < SymbolType, RankType >*, TSubstMap < SymbolType, RankType > > & /* substMapTree */ ) { - return std::set < TFollowTuple < SymbolType, RankType > > ( ); -} - -} /* namespace rte */ - -#endif /* RTE_GLUSHKOV_FOLLOW_V3_H_ */ diff --git a/tests.glushkovrte_v3.sh b/tests.glushkovrte_naive.sh similarity index 96% rename from tests.glushkovrte_v3.sh rename to tests.glushkovrte_naive.sh index 55736a0135932f855835c60e144288aa026d3656..3689c7fe0b0b73a3fc68184c942e47141d2e2919 100755 --- a/tests.glushkovrte_v3.sh +++ b/tests.glushkovrte_naive.sh @@ -158,7 +158,7 @@ function run { #echo $GEN_FILE #echo $AUTOMATON_FILE - ./aconversions2 -t pda -a glushkovrtev3 -i $RTE_FILE 2>/dev/null | ./adeterminize2 > $AUTOMATON_FILE + ./aconversions2 -t pda -a glushkovrtenaive -i $RTE_FILE 2>/dev/null | ./adeterminize2 > $AUTOMATON_FILE for i in `seq 1 $TESTCASE_ITERATIONS`; do runAcceptTest $GEN_FILE $AUTOMATON_FILE $RTE_FILE