/* * RandomizeAutomaton.h * * Created on: 9. 2. 2017 * Author: Jan Travnicek */ #ifndef AUTOMATON_RANDOMIZE_H_ #define AUTOMATON_RANDOMIZE_H_ #include <core/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> #include <automaton/FSM/MultiInitialStateNFA.h> #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> #include <algorithm> #include <foreach> namespace automaton { namespace generate { class RandomizeAutomaton : public std::SingleDispatch < RandomizeAutomaton, automaton::Automaton, const automaton::AutomatonBase & > { 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 automaton::Automaton randomize ( const automaton::Automaton & automaton ); template < class SymbolType, class EpsilonType, class StateType > static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > randomize( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); template < class SymbolType, class StateType > static automaton::MultiInitialStateNFA < SymbolType, StateType > randomize( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ); template < class SymbolType, class StateType > static automaton::NFA < SymbolType, StateType > randomize( const automaton::NFA < SymbolType, StateType > & fsm ); template < class SymbolType, class StateType > static automaton::DFA < SymbolType, StateType > randomize( const automaton::DFA < SymbolType, StateType > & fsm ); }; template < class SymbolType, class StateType > automaton::DFA < SymbolType, StateType > RandomizeAutomaton::randomize(const automaton::DFA < SymbolType, StateType > & origFSM) { std::map < StateType, StateType > statePermutationMap = permutationMap ( origFSM.getStates ( ) ); automaton::DFA < SymbolType, StateType > res ( statePermutationMap.find ( origFSM.getInitialState ( ) )->second ); res.setStates ( origFSM.getStates ( ) ); res.setInputAlphabet ( origFSM.getInputAlphabet ( ) ); for ( const StateType & finalState : origFSM.getFinalStates ( ) ) res.addFinalState ( statePermutationMap.find ( finalState )->second ); for ( const std::pair < std::pair < StateType, SymbolType >, SymbolType > & transition : origFSM.getTransitions ( ) ) res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( transition.second )->second ); return res; } template < class SymbolType, class StateType > automaton::MultiInitialStateNFA < SymbolType, StateType > RandomizeAutomaton::randomize(const automaton::MultiInitialStateNFA < SymbolType, StateType > & origFSM) { std::map < StateType, StateType > statePermutationMap = permutationMap ( origFSM.getStates ( ) ); automaton::MultiInitialStateNFA < SymbolType, StateType > res; res.setStates ( origFSM.getStates ( ) ); res.setInputAlphabet ( origFSM.getInputAlphabet ( ) ); for ( const StateType & initialState : origFSM.getInitialStates ( ) ) res.addInitialState ( statePermutationMap.find ( initialState )->second ); for ( const StateType & finalState : origFSM.getFinalStates ( ) ) res.addFinalState ( statePermutationMap.find ( finalState )->second ); for ( const std::pair < std::pair < StateType, SymbolType >, std::set < SymbolType > > & transition : origFSM.getTransitions ( ) ) for ( const StateType & target : transition.second ) res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( target )->second ); return res; } template < class SymbolType, class StateType > automaton::NFA < SymbolType, StateType > RandomizeAutomaton::randomize(const automaton::NFA < SymbolType, StateType > & origFSM) { std::map < StateType, StateType > statePermutationMap = permutationMap ( origFSM.getStates ( ) ); automaton::NFA < SymbolType, StateType > res ( statePermutationMap.find ( origFSM.getInitialState ( ) )->second ); res.setStates ( origFSM.getStates ( ) ); res.setInputAlphabet ( origFSM.getInputAlphabet ( ) ); for ( const StateType & finalState : origFSM.getFinalStates ( ) ) res.addFinalState ( statePermutationMap.find ( finalState )->second ); for ( const std::pair < std::pair < StateType, SymbolType >, std::set < SymbolType > > & transition : origFSM.getTransitions ( ) ) for ( const StateType & target : transition.second ) res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( target )->second ); return res; } template < class SymbolType, class EpsilonType, class StateType > automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > RandomizeAutomaton::randomize( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & origFSM ) { std::map < StateType, StateType > statePermutationMap = permutationMap ( origFSM.getStates ( ) ); automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res ( statePermutationMap.find ( origFSM.getInitialState ( ) )->second ); res.setStates ( origFSM.getStates ( ) ); res.setInputAlphabet ( origFSM.getInputAlphabet ( ) ); for ( const StateType & finalState : origFSM.getFinalStates ( ) ) res.addFinalState ( statePermutationMap.find ( finalState )->second ); for ( const std::pair < std::pair < StateType, std::variant < EpsilonType, SymbolType > >, std::set < SymbolType > > & transition : origFSM.getTransitions ( ) ) for ( const StateType & target : transition.second ) res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( target )->second ); return res; } } /* namespace generate */ } /* namespace automaton */ #endif /* AUTOMATON_RANDOMIZE_H_ */