Skip to content
Snippets Groups Projects
TrimFSM.cpp 4.61 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * TrimFSM.cpp
     *
     *  Created on: 23. 3. 2014
     *	  Author: Tomas Pecka
     */
    
    #include "TrimFSM.h"
    
    #include <exception/AlibException.h>
    #include <automaton/FSM/ExtendedNFA.h>
    #include <automaton/FSM/CompactNFA.h>
    #include <automaton/FSM/EpsilonNFA.h>
    #include <automaton/FSM/NFA.h>
    #include <automaton/FSM/DFA.h>
    
    
    #include "../../automaton/AutomatonPropertiesFSM.h"
    
    
    namespace trim {
    
    template<class T>
    T TrimFSM::removeUselessStates( const T & fsm ) {
    
    	// 1.
    	std::set<automaton::State> Qu = automaton::AutomatonPropertiesFSM::getUsefullStates( fsm );
    
    
    	// 2.
    	T M;
    
    	for( const auto & q : Qu )
    		M.addState( q );
    
    	for( const auto & a : fsm.getInputAlphabet( ) )
    		M.addInputSymbol( a );
    
    	for( const auto & t : fsm.getTransitions( ) )
    		for( const auto & to : t.second )
    			if( /* TODO test this Qu.count(t.first.first) ) && */ Qu.count(to) )
    				M.addTransition( t.first.first, t.first.second, to );
    
    	for( const auto & q : fsm.getInitialStates( ) )
    		M.addInitialState( q );
    
    	for( const auto & q : fsm.getFinalStates( ) )
    		M.addFinalState( q );
    
    	return M;
    }
    
    template automaton::EpsilonNFA TrimFSM::removeUselessStates( const automaton::EpsilonNFA & fsm );
    template automaton::NFA TrimFSM::removeUselessStates( const automaton::NFA & fsm );
    template automaton::CompactNFA TrimFSM::removeUselessStates( const automaton::CompactNFA & fsm );
    template automaton::ExtendedNFA TrimFSM::removeUselessStates( const automaton::ExtendedNFA & fsm );
    
    template<>
    automaton::DFA TrimFSM::removeUselessStates( const automaton::DFA & fsm ) {
    
    	// 1.
    	std::set<automaton::State> Qu = automaton::AutomatonPropertiesFSM::getUsefullStates( fsm );
    
    
    	// 2.
    	automaton::DFA M ( fsm.getInitialState () );
    
    	for( const auto & q : Qu )
    		M.addState( q );
    
    	for( const auto & a : fsm.getInputAlphabet( ) )
    		M.addInputSymbol( a );
    
    	for( const auto & t : fsm.getTransitions( ) )
    		if( /* TODO test this Qu.count( t.first.first ) && */ Qu.count( t.second ) )
    			M.addTransition( t.first.first, t.first.second, t.second );
    
    	for( const auto & q : fsm.getFinalStates( ) )
    		M.addFinalState( q );
    
    	return M;
    }
    
    template<class T>
    T TrimFSM::removeUnreachableStates( const T & fsm ) {
    	// 1a
    
    	std::set<automaton::State> Qa = automaton::AutomatonPropertiesFSM::getUnreachableStates( fsm );
    
    
    	// 2
    	T M;
    
    	for( const auto & q : Qa )
    		M.addState( q );
    
    	for( const auto & a : fsm.getInputAlphabet( ) )
    		M.addInputSymbol( a );
    
    	for( const auto & transition : fsm.getTransitions( ) )
    		if( Qa.count( transition.first.first ) )
    			for(const auto& to : transition.second )
    				M.addTransition( transition.first.first, transition.first.second, to );
    
    	for( const auto & q : fsm.getInitialStates( ) )
    		M.addInitialState( q );
    
    	std::set<automaton::State> intersect;
    	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
    	for( auto const & state : intersect )
    		M.addFinalState( state );
    
    	return M;
    }
    
    template automaton::EpsilonNFA TrimFSM::removeUnreachableStates( const automaton::EpsilonNFA & fsm );
    template automaton::NFA TrimFSM::removeUnreachableStates( const automaton::NFA & fsm );
    template automaton::CompactNFA TrimFSM::removeUnreachableStates( const automaton::CompactNFA & fsm );
    template automaton::ExtendedNFA TrimFSM::removeUnreachableStates( const automaton::ExtendedNFA & fsm );
    
    template<>
    automaton::DFA TrimFSM::removeUnreachableStates( const automaton::DFA & fsm ) {
    	// 1a
    
    	std::set<automaton::State> Qa = automaton::AutomatonPropertiesFSM::getUnreachableStates( fsm );
    
    
    	// 2
    	automaton::DFA M(fsm.getInitialState() );
    
    	for( const auto & q : Qa )
    		M.addState( q );
    
    	for( const auto & a : fsm.getInputAlphabet( ) )
    		M.addInputSymbol( a );
    
    	for( const auto & transition : fsm.getTransitions( ) )
    		if( Qa.count( transition.first.first ) )
    			M.addTransition( transition.first.first, transition.first.second, transition.second );
    
    	std::set<automaton::State> intersect;
    	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
    	for( auto const & state : intersect )
    		M.addFinalState( state );
    
    	return M;
    }
    
    template<class T>
    T TrimFSM::trim( const T & fsm ) {
    	return removeUnreachableStates(removeUselessStates(fsm));
    }
    
    template automaton::EpsilonNFA TrimFSM::trim( const automaton::EpsilonNFA & fsm );
    template automaton::NFA TrimFSM::trim( const automaton::NFA & fsm );
    template automaton::CompactNFA TrimFSM::trim( const automaton::CompactNFA & fsm );
    template automaton::ExtendedNFA TrimFSM::trim( const automaton::ExtendedNFA & fsm );
    template automaton::DFA TrimFSM::trim( const automaton::DFA & fsm );
    
    }