From 1bc767d1f4265941b01eb2bd3001a4e71b684bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Sun, 23 Mar 2014 10:53:12 +0100 Subject: [PATCH] Refactor dead and unreachable states remover --- atrim/src/automaton/DeadStateRemover.cpp | 32 +++++---- .../src/automaton/UnreachableStateRemover.cpp | 68 ++++++++++--------- atrim/src/automaton/UnreachableStateRemover.h | 6 +- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/atrim/src/automaton/DeadStateRemover.cpp b/atrim/src/automaton/DeadStateRemover.cpp index 7045561e12..76e785484c 100644 --- a/atrim/src/automaton/DeadStateRemover.cpp +++ b/atrim/src/automaton/DeadStateRemover.cpp @@ -12,13 +12,14 @@ using namespace std; FSM DeadStateRemover::remove( const FSM & fsm ) { + // 1a deque<set<State>> Qi; Qi.push_back( set<State>( ) ); + Qi.at( 0 ) = fsm.getFinalStates( ); int i = 1; - for( const auto & f : fsm.getFinalStates( ) ) - Qi.at( 0 ).insert( f ); + // 1bc while( true ) { Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi @@ -29,30 +30,33 @@ FSM DeadStateRemover::remove( const FSM & fsm ) if( Qi.at( i ) == Qi.at( i - 1 ) ) break; - i += 1; + i = i + 1; } + const set<State> Qu = Qi.at( i ); + // 2. - FSM ret; + FSM M; - for( const auto & q : Qi.at( i ) ) - ret.addState( q ); + for( const auto & q : Qu ) + M.addState( q ); + + for( const auto & a : fsm.getInputAlphabet( ) ) + M.addInputSymbol( a ); for( const auto & t : fsm.getTransitions( ) ) { - if( isInSet( t.getFrom( ), ret.getStates( ) ) && isInSet( t.getTo( ), ret.getStates( ) ) ) + if( isInSet( t.getFrom( ), Qu ) && isInSet( t.getTo( ), Qu ) ) { - if( ! isInSet( t.getInput( ), ret.getInputAlphabet( ) ) ) - ret.addInputSymbol( t.getInput( ) ); - - ret.addTransition( t ); + M.addTransition( t ); } } for( const auto & q : fsm.getInitialStates( ) ) - ret.addInitialState( q ); + M.addInitialState( q ); + for( const auto & q : fsm.getFinalStates( ) ) - ret.addFinalState( q ); + M.addFinalState( q ); - return ret; + return M; } diff --git a/atrim/src/automaton/UnreachableStateRemover.cpp b/atrim/src/automaton/UnreachableStateRemover.cpp index 38ddc2eaf4..868857ee47 100644 --- a/atrim/src/automaton/UnreachableStateRemover.cpp +++ b/atrim/src/automaton/UnreachableStateRemover.cpp @@ -16,52 +16,54 @@ FSM UnreachableStateRemover::remove( const FSM & fsm ) if( fsm.getInitialStates( ).size( ) != 1 ) throw AlibException( "NFA must have exactly one initial state." ); - set<State> reachableStates = findReachableStates( fsm ); + // 1a + deque<set<State>> Qi; + Qi.push_back( set<State>( ) ); + Qi.at( 0 ).insert( * fsm.getInitialStates( ).begin( ) ); - FSM ret; + int i = 1; - for( auto const & q : reachableStates ) - ret.addState( q ); - - for( auto const & t : fsm.getTransitions( ) ) + // 1bc + while( true ) { - if( isInSet( t.getFrom( ), reachableStates ) ) + Qi.push_back( Qi.at( i - 1 ) ); + + for( const auto & p : Qi.at( i - 1 ) ) { - if( ! isInSet( t.getInput( ), ret.getInputAlphabet( ) ) ) - ret.addInputSymbol( t.getInput( ) ); - ret.addTransition( t ); + for( const auto & transition : fsm.getTransitionsFromState( p ) ) + { + Qi.at( i ).insert( transition.getTo( ) ); + } } - } + if( Qi.at( i ) == Qi.at( i - 1 ) ) + break; - for( auto const & state : fsm.getInitialStates( ) ) - ret.addInitialState( state ); + i = i + 1; + } + const set<State> Qa = Qi.at( i ); - set<State> intersect; - const set<State> & F = fsm.getFinalStates( ); - set_intersection( F.begin(), F.end(), reachableStates.begin(), reachableStates.end(), inserter( intersect, intersect.begin() ) ); - for( auto const & state : intersect ) - ret.addFinalState( state ); + // 2 - return ret; -} + FSM M; -set<State> UnreachableStateRemover::findReachableStates( const FSM & fsm ) -{ - set<State> qprev, qcurr; - qcurr.insert( * fsm.getInitialStates().begin() ); + for( const auto & q : Qa ) + M.addState( q ); + for( const auto & a : fsm.getInputAlphabet( ) ) + M.addInputSymbol( a ); - do - { - qprev = qcurr; + for( const auto & transition : fsm.getTransitions( ) ) + if( isInSet( transition.getFrom( ), Qa ) ) + M.addTransition( transition ); - for( auto const & p : qprev ) - for( auto const & transition : fsm.getTransitionsFromState( p ) ) - qcurr.insert( transition.getTo() ); - } - while( qcurr != qprev ); + M.addInitialState( * fsm.getInitialStates( ).begin( ) ); + + set<State> intersect; + set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), inserter( intersect, intersect.begin( ) ) ); + for( auto const & state : intersect ) + M.addFinalState( state ); - return qcurr; + return M; } diff --git a/atrim/src/automaton/UnreachableStateRemover.h b/atrim/src/automaton/UnreachableStateRemover.h index 5e5929e7b7..c650afdaf1 100644 --- a/atrim/src/automaton/UnreachableStateRemover.h +++ b/atrim/src/automaton/UnreachableStateRemover.h @@ -12,8 +12,7 @@ #include <AlibException.h> #include <algorithm> -#include <iterator> -#include <map> +#include <deque> #include <set> #define isInSet(x,set) ( (set).find((x)) != (set).end()) @@ -25,9 +24,6 @@ class UnreachableStateRemover { public: static automaton::FSM remove( const automaton::FSM & fsm ); - -private: - static std::set<automaton::State> findReachableStates( const automaton::FSM & fsm ); }; #endif /* UNREACHABLE_H_ */ -- GitLab