Skip to content
Snippets Groups Projects
Commit 1bc767d1 authored by Tomáš Pecka's avatar Tomáš Pecka
Browse files

Refactor dead and unreachable states remover

parent b95a59f1
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......@@ -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;
}
......@@ -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_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment