diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.cpp b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..febedb129d623b7a61369ae28fdc88f294a8dc9f --- /dev/null +++ b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp @@ -0,0 +1,23 @@ +/* + * RandomizeGrammar.cpp + * + * Created on: 9. 2. 2017 + * Author: Jan Travnicek + */ + +#include "RandomizeGrammar.h" +#include <grammar/Grammar.h> + +namespace grammar { + +namespace generate { + +auto RandomizeGrammarLeftRG = RandomizeGrammar::RegistratorWrapper < grammar::LeftRG < >, grammar::LeftRG < > > ( RandomizeGrammar::randomize ); + +grammar::Grammar RandomizeGrammar::randomize ( const grammar::Grammar & grammar ) { + return dispatch ( grammar.getData ( ) ); +} + +} /* namespace generate */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.h b/alib2algo/src/grammar/generate/RandomizeGrammar.h new file mode 100644 index 0000000000000000000000000000000000000000..e02737598af7f5021c78aff570bbf4baabbfcc5f --- /dev/null +++ b/alib2algo/src/grammar/generate/RandomizeGrammar.h @@ -0,0 +1,71 @@ +/* + * RandomizeGrammar.h + * + * Created on: 9. 2. 2017 + * Author: Jan Travnicek + */ + +#ifndef GRAMMAR_RANDOMIZE_H_ +#define GRAMMAR_RANDOMIZE_H_ + +#include <core/multipleDispatch.hpp> + +#include <grammar/Grammar.h> +#include <grammar/Regular/LeftRG.h> + +#include <algorithm> +#include <foreach> + +namespace grammar { + +namespace generate { + +class RandomizeGrammar : public std::SingleDispatch < RandomizeGrammar, grammar::Grammar, const grammar::GrammarBase & > { + + template < class T > + static std::map < T, T > permutationMap ( const std::set < T > & data ) { + std::vector < T > dataVector ( data.begin ( ), data.end ( ) ); + + std::shuffle ( dataVector.begin ( ), dataVector.end ( ), std::random_devices::semirandom ); + std::map < T, T > permutation; + for ( const std::tuple < const T &, const T & > & fromToPair : std::make_tuple_foreach ( data, dataVector ) ) { + permutation.insert ( std::make_pair ( std::get < 0 > ( fromToPair ), std::get < 1 > ( fromToPair ) ) ); + } + + if(common::GlobalData::verbose) + std::clog << "permutation map: " << permutation << std::endl; + + return permutation; + } + +public: + static grammar::Grammar randomize ( const grammar::Grammar & grammar ); + + template < class SymbolType > + static grammar::LeftRG < SymbolType > randomize( const grammar::LeftRG < SymbolType > & gram ); +}; + +template < class SymbolType > +grammar::LeftRG < SymbolType > RandomizeGrammar::randomize(const grammar::LeftRG < SymbolType > & gram ) { + std::map < SymbolType, SymbolType > symbolPermutationMap = permutationMap ( gram.getNonterminalAlphabet ( ) ); + + grammar::LeftRG < 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 ( symbolPermutationMap.find ( rhs.template get < std::pair < SymbolType, SymbolType > > ( ).first )->second, rhs.template get < std::pair < SymbolType, SymbolType > > ( ).second ) ); + + return res; +} + +} /* namespace generate */ + +} /* namespace grammar */ + +#endif /* GRAMMAR_RANDOMIZE_H_ */ diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp index eef364eb3908d4000a8919cb07b66d6f9754bfcb..fe65ef0fd8da680dd1f26dad303b68730a486023 100644 --- a/arand2/src/arand.cpp +++ b/arand2/src/arand.cpp @@ -20,6 +20,7 @@ #include "string/generate/RandomSubstringFactory.h" #include "tree/generate/RandomTreeFactory.h" #include <automaton/generate/RandomizeAutomaton.h> +#include <grammar/generate/RandomizeGrammar.h> int main ( int argc, char * argv[] ) { try { @@ -32,6 +33,7 @@ int main ( int argc, char * argv[] ) { allowed.push_back ( "FSM" ); allowed.push_back ( "RFSM" ); allowed.push_back ( "CFG" ); + allowed.push_back ( "RCFG" ); allowed.push_back ( "RE" ); allowed.push_back ( "ST" ); allowed.push_back ( "SST" ); @@ -144,6 +146,17 @@ int main ( int argc, char * argv[] ) { measurements::end ( ); measurements::start ( "Output write", measurements::Type::AUXILIARY ); + alib::XmlDataFactory::toStdout ( res ); + } else if ( type.getValue ( ) == "RCFG" ) { + grammar::Grammar baseGrammar = alib::XmlDataFactory::fromTokens < grammar::Grammar > ( sax::FromXMLParserHelper::parseInput ( input ) ); + + measurements::start ( "Algorithm", measurements::Type::MAIN ); + + grammar::Grammar res = grammar::generate::RandomizeGrammar::randomize ( baseGrammar ); + + measurements::end ( ); + measurements::start ( "Output write", measurements::Type::AUXILIARY ); + alib::XmlDataFactory::toStdout ( res ); } else if ( type.getValue ( ) == "RE" ) { measurements::start ( "Algorithm", measurements::Type::MAIN );