Skip to content
Snippets Groups Projects
RandomizeAutomaton.h 6.19 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * 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_ */