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