diff --git a/alib2algo/src/rte/glushkov/GlushkovFirst.cpp b/alib2algo/src/rte/glushkov/GlushkovFirst.cpp deleted file mode 100644 index 6648a418ca575ac6e4ed54d85e9449c6a49607da..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/glushkov/GlushkovFirst.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * GlushkovFirst.cpp - * - * Created on: 14. 4. 2016 - * Author: Tomas Pecka - */ - -#include "GlushkovFirst.h" - -namespace rte { - -std::set < std::ranked_symbol < > > GlushkovFirst::first ( const rte::FormalRTE < > & rte ) { - return rte.getRTE ( ).getStructure ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node ) { - std::set < std::ranked_symbol < > > ret, tmp; - - tmp = node.getLeftElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - tmp = node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - return ret; -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node ) { - std::set < std::ranked_symbol < > > ret, tmp; - - tmp = node.getLeftElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - // First::Formal() returns a set. hence only one occurrence. - auto it = std::find_if ( ret.begin ( ), ret.end ( ), [node] ( const std::ranked_symbol < > & a ) { - return a == node.getSubstitutionSymbol ( ).getSymbol ( ); - } ); - - if ( it != ret.end ( ) ) { - ret.erase ( it ); - tmp = node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - } - - return ret; -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node ) { - std::set < std::ranked_symbol < > > ret; - - ret = node.getElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ); - ret.insert ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); - return ret; -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node ) { - return std::set < std::ranked_symbol < > > { node.getSymbol ( ) }; -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node ) { - return std::set < std::ranked_symbol < > > { node.getSymbol ( ) }; -} - -std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */ ) { - return std::set < std::ranked_symbol < > > ( ); -} - -} /* namespace rte */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFirst.h b/alib2algo/src/rte/glushkov/GlushkovFirst.h index b9c31490d5a4d0883fc50e0a08920c66ff8236b3..5c344b4aaa19b7759b51f6bf89b9370e840d6e9a 100644 --- a/alib2algo/src/rte/glushkov/GlushkovFirst.h +++ b/alib2algo/src/rte/glushkov/GlushkovFirst.h @@ -23,19 +23,84 @@ public: * @param re rte to probe * @return all rteSymbols which can be root of the tree. */ - static std::set < std::ranked_symbol < > > first ( const rte::FormalRTE < > & re ); + template < class SymbolType, class RankType > + static std::set < std::ranked_symbol < SymbolType, RankType > > first ( const rte::FormalRTE < SymbolType, RankType > & re ); + template < class SymbolType, class RankType > class Formal { public: - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node ); - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node ); - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node ); - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node ); - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node ); - static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node ); + static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node ); }; }; +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::first ( const rte::FormalRTE < SymbolType, RankType > & rte ) { + return rte.getRTE ( ).getStructure ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node ) { + std::set < std::ranked_symbol < SymbolType, RankType > > ret, tmp; + + tmp = node.getLeftElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + tmp = node.getRightElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + return ret; +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node ) { + std::set < std::ranked_symbol < SymbolType, RankType > > ret, tmp; + + tmp = node.getLeftElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + // First returns a set. hence only one occurrence. + auto it = std::find_if ( ret.begin ( ), ret.end ( ), [node] ( const std::ranked_symbol < SymbolType, RankType > & a ) { + return a == node.getSubstitutionSymbol ( ).getSymbol ( ); + } ); + + if ( it != ret.end ( ) ) { + ret.erase ( it ); + tmp = node.getRightElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + } + + return ret; +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node ) { + std::set < std::ranked_symbol < SymbolType, RankType > > ret; + + ret = node.getElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ); + ret.insert ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); + return ret; +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node ) { + return std::set < std::ranked_symbol < SymbolType, RankType > > { node.getSymbol ( ) }; +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node ) { + return std::set < std::ranked_symbol < SymbolType, RankType > > { node.getSymbol ( ) }; +} + +template < class SymbolType, class RankType > +std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */ ) { + return std::set < std::ranked_symbol < SymbolType, RankType > > ( ); +} + } /* namespace rte */ #endif /* RTE_GLUSHKOV_FIRST_H_ */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFollow.cpp b/alib2algo/src/rte/glushkov/GlushkovFollow.cpp deleted file mode 100644 index 37a8cea54feb423899e17d4ab68fa64c7ed4bded..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/glushkov/GlushkovFollow.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * GlushkovFollow.cpp - * - * Created on: 14. 4. 2016 - * Author: Tomas Pecka - */ - -#include "GlushkovFollow.h" -#include "GlushkovFirst.h" -#include "GlushkovPos.h" -#include <iterator> -#include <vector> - -namespace rte { - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::follow ( const rte::FormalRTE < > & rte, const std::ranked_symbol < > & symbol ) { - std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap; - - /* Init substitution map, ie \forall a \in K: sub[a] = \emptyset */ - for ( const std::ranked_symbol < > & ssymb : rte.getSubstitutionAlphabet ( ) ) - subMap.insert ( std::make_pair ( ssymb, std::set < std::ranked_symbol < > > { } ) ); - - /* recursively compute follow */ - return rte.getRTE ( ).getStructure ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbol, rte.getSubstitutionAlphabet ( ), subMap ); -} - -// ----------------------------------------------------------------------------- - -template < class T > -void 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 > > cartesian ( const std::vector < std::vector < T > > & input ) { - std::vector < std::vector < T > > ret; - std::vector < T > current ( input.size ( ), std::ranked_symbol < > ( 0, 0 ) ); - - cartesian_rec ( input, ret, current, 0 ); - - return ret; -} - -void preprocessSubMap ( const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) { - for ( bool change = true; change; change = false ) - for ( std::pair < const std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv : subMap ) { - std::set < std::ranked_symbol < > > & substSet = kv.second; - - for ( const auto & e : substSet ) { - if ( alphabetK.count ( e ) == 0 ) continue; - - auto it = subMap.find ( e ); - size_t oldSize = substSet.size ( ); - substSet.insert ( it->second.begin ( ), it->second.end ( ) ); - change = ( oldSize != substSet.size ( ) ); // something was added - substSet.erase ( e ); - } - } -} - -std::set < std::vector < std::ranked_symbol < > > > replaceConstants ( const std::set < std::ranked_symbol < > > & alphabetK, const std::vector < std::ranked_symbol < > > & follow, const std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap2 ) { - std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap ( subMap2 ); - preprocessSubMap ( alphabetK, subMap ); - - std::vector < std::vector < std::ranked_symbol < > > > input; - - for ( const std::ranked_symbol < > & e : follow ) { - if ( alphabetK.count ( e ) > 0 ) - input.push_back ( std::vector < std::ranked_symbol < > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) ); - else - input.push_back ( std::vector < std::ranked_symbol < > > { e } ); - } - - /* now do the cartesian product on "input" */ - std::vector < std::vector < std::ranked_symbol < > > > followSet = cartesian ( input ); - return std::set < std::vector < std::ranked_symbol < > > > ( followSet.begin ( ), followSet.end ( ) ); -} - -// ----------------------------------------------------------------------------- - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) { - std::set < std::vector < std::ranked_symbol < > > > ret, tmp; - - tmp = node.getLeftElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - tmp = node.getRightElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - return ret; -} - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) { - - std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap2 ( subMap ); - auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); - - itMap->second.clear ( ); - - for ( const auto & s : node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ) ) - 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 ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) ) - return node.getLeftElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap2 ); - else - return node.getRightElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap ); -} - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) { - - std::set < std::vector < std::ranked_symbol < > > > ret; - - for ( const auto & s : node.getElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ) ) - subMap[node.getSubstitutionSymbol ( ).getSymbol ( )].insert ( s ); - - return node.getElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap ); -} - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) { - - std::set < std::vector < std::ranked_symbol < > > > ret, tmp; - - if ( symbolF == node.getSymbol ( ) ) { - std::vector < std::ranked_symbol < > > children; - - for ( const std::smart_ptr < const rte::FormalRTESymbol < alphabet::Symbol, primitive::Unsigned > > & c : node.getElements ( ) ) - children.push_back ( c->getSymbol ( ) ); - - return replaceConstants ( alphabetK, children, subMap ); - } - - for ( const auto & c : node.getElements ( ) ) { - tmp = c->accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - } - - return ret; -} - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */, const std::set < std::ranked_symbol < > > & /* alphabetK */, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & /* subMap */ ) { - return std::set < std::vector < std::ranked_symbol < > > > ( ); -} - -std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */, const std::set < std::ranked_symbol < > > & /* alphabetK */, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & /* subMap */ ) { - return std::set < std::vector < std::ranked_symbol < > > > ( ); -} - -} /* namespace rte */ diff --git a/alib2algo/src/rte/glushkov/GlushkovFollow.h b/alib2algo/src/rte/glushkov/GlushkovFollow.h index 0de211129a8a65811780871f77dccdd8fe2908b6..a1a072a764823ebc66478c60499ce279919bc5eb 100644 --- a/alib2algo/src/rte/glushkov/GlushkovFollow.h +++ b/alib2algo/src/rte/glushkov/GlushkovFollow.h @@ -17,29 +17,198 @@ #include <alphabet/RankedSymbol.h> +#include "GlushkovFirst.h" +#include "GlushkovPos.h" +#include <iterator> +#include <vector> + namespace rte { class GlushkovFollow { + template < class SymbolType, class RankType > + static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > replaceConstants ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap2 ); + template < class SymbolType, class RankType > + static void preprocessSubMap ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 */ - static std::set < std::vector < std::ranked_symbol < > > > follow ( const rte::FormalRTE < > & re, const std::ranked_symbol < > & symbol ); + 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 < > > > visit ( const rte::FormalRTEElement < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); - static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM ); + 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM ); }; }; +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 ) { + std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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, std::set < std::ranked_symbol < 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 ); +} + +// ----------------------------------------------------------------------------- + +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; +} + +template < class SymbolType, class RankType > +void GlushkovFollow::preprocessSubMap ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) { + for ( bool change = true; change; change = false ) + for ( std::pair < const std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & kv : subMap ) { + std::set < std::ranked_symbol < SymbolType, RankType > > & substSet = kv.second; + + for ( const auto & e : substSet ) { + if ( alphabetK.count ( e ) == 0 ) continue; + + auto it = subMap.find ( e ); + size_t oldSize = substSet.size ( ); + substSet.insert ( it->second.begin ( ), it->second.end ( ) ); + change = ( oldSize != substSet.size ( ) ); // something was added + substSet.erase ( e ); + } + } +} + +template < class SymbolType, class RankType > +std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::replaceConstants ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap2 ) { + std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 > > >, GlushkovFollow::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 > > >, GlushkovFollow::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 > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) { + + std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > subMap2 ( subMap ); + auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) ); + + itMap->second.clear ( ); + + for ( const auto & s : node.getRightElement ( ).template accept < std::set < std::ranked_symbol < 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 > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap2 ); + else + return node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap ); +} + +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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) { + + std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret; + + for ( const auto & s : node.getElement ( ).template accept < std::set < std::ranked_symbol < 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 ); +} + +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 std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 > > >, GlushkovFollow::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 > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const std::set < std::ranked_symbol < SymbolType, RankType > > & /* alphabetK */, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < 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 > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const std::set < std::ranked_symbol < SymbolType, RankType > > & /* alphabetK */, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & /* subMap */ ) { + return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( ); +} + } /* namespace rte */ #endif /* RTE_GLUSHKOV_FOLLOW_H_ */ diff --git a/alib2algo/src/rte/glushkov/GlushkovPos.cpp b/alib2algo/src/rte/glushkov/GlushkovPos.cpp deleted file mode 100644 index c1ef63729b961f30335094ccbed5dca54e8f3913..0000000000000000000000000000000000000000 --- a/alib2algo/src/rte/glushkov/GlushkovPos.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * GlushkovPos.cpp - * - * Created on: 14. 4. 2016 - * Author: Tomas Pecka - */ - -#include "GlushkovPos.h" -#include <rte/formal/FormalRTEElements.h> - -namespace rte { - -bool GlushkovPos::pos ( const std::ranked_symbol < > & symbol, const rte::FormalRTE < > & rte ) { - return rte.getRTE ( ).getStructure ( ).accept < bool, GlushkovPos::Formal > ( symbol ); -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) { - return node.getLeftElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) || node.getRightElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ); -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) { - return node.getLeftElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) || node.getRightElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ); -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) { - return node.getElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ); -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) { - if ( symbolF == node.getSymbol ( ) ) return true; - - for ( const std::smart_ptr < const rte::FormalRTESymbol < alphabet::Symbol, primitive::Unsigned > > & element : node.getElements ( ) ) - if ( element->accept < bool, GlushkovPos::Formal > ( symbolF ) ) - return true; - - return false; -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) { - return symbolF == node.getSymbol ( ); -} - -bool GlushkovPos::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */ ) { - return false; -} - -} /* namespace rte */ diff --git a/alib2algo/src/rte/glushkov/GlushkovPos.h b/alib2algo/src/rte/glushkov/GlushkovPos.h index 5ca719fac7a3ec678da0fab57d4c3faa2d902109..99fbea1f2555c718539cf4bf446b61c526f729c7 100644 --- a/alib2algo/src/rte/glushkov/GlushkovPos.h +++ b/alib2algo/src/rte/glushkov/GlushkovPos.h @@ -10,6 +10,7 @@ #include <rte/formal/FormalRTE.h> #include <rte/RTEFeatures.h> +#include <rte/formal/FormalRTEElements.h> #include <alphabet/RankedSymbol.h> @@ -20,19 +21,62 @@ public: /** * @return bool true if symbol pointer is in this subtree */ - static bool pos ( const std::ranked_symbol < > & symbol, const rte::FormalRTE < > & node ); + template < class SymbolType, class RankType > + static bool pos ( const std::ranked_symbol < SymbolType, RankType > & symbol, const rte::FormalRTE < SymbolType, RankType > & node ); + template < class SymbolType, class RankType > class Formal { public: - static bool visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); - static bool visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); - static bool visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); - static bool visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); - static bool visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); - static bool visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch ); + static bool visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); + static bool visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); + static bool visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); + static bool visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); + static bool visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); + static bool visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch ); }; }; +template < class SymbolType, class RankType > +bool GlushkovPos::pos ( const std::ranked_symbol < SymbolType, RankType > & symbol, const rte::FormalRTE < SymbolType, RankType > & rte ) { + return rte.getRTE ( ).getStructure ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbol ); +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) { + return node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) || node.getRightElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ); +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) { + return node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) || node.getRightElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ); +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) { + return node.getElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ); +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) { + if ( symbolF == node.getSymbol ( ) ) return true; + + for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & element : node.getElements ( ) ) + if ( element->template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) ) + return true; + + return false; +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) { + return symbolF == node.getSymbol ( ); +} + +template < class SymbolType, class RankType > +bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */ ) { + return false; +} + } /* namespace rte */ #endif /* RTE_GLUSHKOV_POS_H_ */