diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.cpp b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp index febedb129d623b7a61369ae28fdc88f294a8dc9f..4d342a3ae50b481c49cc24ddabe7365f724917d7 100644 --- a/alib2algo/src/grammar/generate/RandomizeGrammar.cpp +++ b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp @@ -13,6 +13,9 @@ namespace grammar { namespace generate { auto RandomizeGrammarLeftRG = RandomizeGrammar::RegistratorWrapper < grammar::LeftRG < >, grammar::LeftRG < > > ( RandomizeGrammar::randomize ); +auto RandomizeGrammarLeftLG = RandomizeGrammar::RegistratorWrapper < grammar::LeftLG < >, grammar::LeftLG < > > ( RandomizeGrammar::randomize ); +auto RandomizeGrammarRightRG = RandomizeGrammar::RegistratorWrapper < grammar::RightRG < >, grammar::RightRG < > > ( RandomizeGrammar::randomize ); +auto RandomizeGrammarRightLG = RandomizeGrammar::RegistratorWrapper < grammar::RightLG < >, grammar::RightLG < > > ( RandomizeGrammar::randomize ); grammar::Grammar RandomizeGrammar::randomize ( const grammar::Grammar & grammar ) { return dispatch ( grammar.getData ( ) ); diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.h b/alib2algo/src/grammar/generate/RandomizeGrammar.h index e1c1818ca5e3f4abfef89affeddbedc9d2c81d81..4e65db928d15fe4e78f5fed3a5541aadb66a228f 100644 --- a/alib2algo/src/grammar/generate/RandomizeGrammar.h +++ b/alib2algo/src/grammar/generate/RandomizeGrammar.h @@ -11,7 +11,10 @@ #include <core/multipleDispatch.hpp> #include <grammar/Grammar.h> +#include <grammar/Regular/LeftLG.h> #include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> #include <common/Permutation.hpp> @@ -24,11 +27,17 @@ public: static grammar::Grammar randomize ( const grammar::Grammar & grammar ); template < class SymbolType > - static grammar::LeftRG < SymbolType > randomize( const grammar::LeftRG < SymbolType > & gram ); + static grammar::LeftRG < SymbolType > randomize ( const grammar::LeftRG < SymbolType > & gram ); + template < class SymbolType > + static grammar::LeftLG < SymbolType > randomize ( const grammar::LeftLG < SymbolType > & gram ); + template < class SymbolType > + static grammar::RightRG < SymbolType > randomize ( const grammar::RightRG < SymbolType > & gram ); + template < class SymbolType > + static grammar::RightLG < SymbolType > randomize ( const grammar::RightLG < SymbolType > & gram ); }; template < class SymbolType > -grammar::LeftRG < SymbolType > RandomizeGrammar::randomize(const grammar::LeftRG < SymbolType > & gram ) { +grammar::LeftRG < SymbolType > RandomizeGrammar::randomize ( const grammar::LeftRG < SymbolType > & gram ) { std::map < SymbolType, SymbolType > symbolPermutationMap = common::Permutation::permutationMap ( gram.getNonterminalAlphabet ( ) ); grammar::LeftRG < SymbolType > res ( symbolPermutationMap.find ( gram.getInitialSymbol ( ) )->second ); @@ -46,6 +55,63 @@ grammar::LeftRG < SymbolType > RandomizeGrammar::randomize(const grammar::LeftRG return res; } +template < class SymbolType > +grammar::LeftLG < SymbolType > RandomizeGrammar::randomize ( const grammar::LeftLG < SymbolType > & gram ) { + std::map < SymbolType, SymbolType > symbolPermutationMap = common::Permutation::permutationMap ( gram.getNonterminalAlphabet ( ) ); + + grammar::LeftLG < SymbolType > res ( symbolPermutationMap.find ( gram.getInitialSymbol ( ) )->second ); + + res.setNonterminalAlphabet ( gram.getNonterminalAlphabet ( ) ); + res.setTerminalAlphabet ( gram.getTerminalAlphabet ( ) ); + + for ( const std::pair < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > > > & rule : gram.getRules ( ) ) + for ( const std::variant < std::vector < SymbolType >, std::pair < SymbolType, std::vector < SymbolType > > > & rhs : rule.second ) + if ( rhs.template is < std::vector < SymbolType > > ( ) ) + res.addRule ( symbolPermutationMap.find ( rule.first )->second, rhs ); + else + res.addRule ( symbolPermutationMap.find ( rule.first )->second, std::make_pair ( symbolPermutationMap.find ( rhs.template get < std::pair < SymbolType, std::vector < SymbolType > > > ( ).first )->second, rhs.template get < std::pair < SymbolType, std::vector < SymbolType > > > ( ).second ) ); + + return res; +} + +template < class SymbolType > +grammar::RightRG < SymbolType > RandomizeGrammar::randomize ( const grammar::RightRG < SymbolType > & gram ) { + std::map < SymbolType, SymbolType > symbolPermutationMap = common::Permutation::permutationMap ( gram.getNonterminalAlphabet ( ) ); + + grammar::RightRG < SymbolType > res ( symbolPermutationMap.find ( gram.getInitialSymbol ( ) )->second ); + + res.setNonterminalAlphabet ( gram.getNonterminalAlphabet ( ) ); + res.setTerminalAlphabet ( gram.getTerminalAlphabet ( ) ); + + for ( const std::pair < SymbolType, std::set < std::variant < SymbolType, std::pair < SymbolType, SymbolType > > > > & rule : gram.getRules ( ) ) + for ( const std::variant < SymbolType, std::pair < SymbolType, SymbolType > > & rhs : rule.second ) + if ( rhs.template is < SymbolType > ( ) ) + res.addRule ( symbolPermutationMap.find ( rule.first )->second, rhs ); + else + res.addRule ( symbolPermutationMap.find ( rule.first )->second, std::make_pair ( rhs.template get < std::pair < SymbolType, SymbolType > > ( ).first, symbolPermutationMap.find ( rhs.template get < std::pair < SymbolType, SymbolType > > ( ).second )->second ) ); + + return res; +} + +template < class SymbolType > +grammar::RightLG < SymbolType > RandomizeGrammar::randomize ( const grammar::RightLG < SymbolType > & gram ) { + std::map < SymbolType, SymbolType > symbolPermutationMap = common::Permutation::permutationMap ( gram.getNonterminalAlphabet ( ) ); + + grammar::RightLG < SymbolType > res ( symbolPermutationMap.find ( gram.getInitialSymbol ( ) )->second ); + + res.setNonterminalAlphabet ( gram.getNonterminalAlphabet ( ) ); + res.setTerminalAlphabet ( gram.getTerminalAlphabet ( ) ); + + for ( const std::pair < SymbolType, std::set < std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > > > & rule : gram.getRules ( ) ) + for ( const std::variant < std::vector < SymbolType >, std::pair < std::vector < SymbolType >, SymbolType > > & rhs : rule.second ) + if ( rhs.template is < std::vector < SymbolType > > ( ) ) + res.addRule ( symbolPermutationMap.find ( rule.first )->second, rhs ); + else + res.addRule ( symbolPermutationMap.find ( rule.first )->second, std::make_pair ( rhs.template get < std::pair < std::vector < SymbolType >, SymbolType > > ( ).first, symbolPermutationMap.find ( rhs.template get < std::pair < std::vector < SymbolType >, SymbolType > > ( ).second )->second ) ); + + return res; +} + } /* namespace generate */ } /* namespace grammar */