From 0cbe5736d08a9729f7acfc7ee59792ed36032936 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sat, 30 Mar 2019 09:31:48 +0100 Subject: [PATCH] redesign templating of some automata algorithms --- .../automaton/properties/ReachableStates.h | 54 +++-------------- .../src/automaton/properties/UsefulStates.h | 38 ------------ .../simplify/UnreachableStatesRemover.h | 53 ++++------------- .../automaton/simplify/UselessStatesRemover.h | 59 ++++--------------- 4 files changed, 29 insertions(+), 175 deletions(-) diff --git a/alib2algo/src/automaton/properties/ReachableStates.h b/alib2algo/src/automaton/properties/ReachableStates.h index cac879d6dc..e497ebefea 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.h +++ b/alib2algo/src/automaton/properties/ReachableStates.h @@ -74,20 +74,6 @@ public: template < class SymbolType, class StateType > static ext::set<StateType> reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ); - /** - * Finds all reachable states of a nondeterministic finite automaton. - * Using closure implementation of the BFS algorithm. - * - * @overload - * - * @tparam SymbolType Type for the input symbols. - * @tparam StateType Type for the states. - * @param fsm nondeterministic finite automaton - * @return set of reachable states from the initial state of @p fsm - */ - template < class SymbolType, class EpsilonType, class StateType > - static ext::set<StateType> reachableStates( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); - /** * Finds all reachable states of a nondeterministic finite automaton. * Using closure implementation of the BFS algorithm. @@ -100,7 +86,7 @@ public: * @return set of reachable states from the initial state of @p fsm */ template < class SymbolType, class StateType > - static ext::set<StateType> reachableStates( const automaton::NFA < SymbolType, StateType > & fsm ); + static ext::set<StateType> reachableStates( const automaton::CompactNFA < SymbolType, StateType > & fsm ); /** * Finds all reachable states of a deterministic finite automaton. @@ -114,7 +100,7 @@ public: * @return set of reachable states from the initial state of @p fsm */ template < class SymbolType, class StateType > - static ext::set<StateType> reachableStates( const automaton::DFA < SymbolType, StateType > & fsm ); + static ext::set<StateType> reachableStates( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ); /** * Finds all reachable states of a deterministic tree automaton. @@ -162,7 +148,7 @@ ext::set < typename automaton::StateTypeOfAutomaton < T > > ReachableStates::rea for( const auto & p : Qi.at( i - 1 ) ) for( const auto & transition : fsm.getTransitionsFromState( p ) ) - Qi.at( i ).insert( transition.second.begin(), transition.second.end() ); + Qi.at( i ).insert( transition.second ); if( Qi.at( i ) == Qi.at( i - 1 ) ) break; @@ -199,34 +185,8 @@ ext::set<StateType> ReachableStates::reachableStates( const automaton::MultiInit return Qi.at( i ); } -template < class SymbolType, class EpsilonType, class StateType > -ext::set<StateType> ReachableStates::reachableStates( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ) { - // 1a - ext::deque<ext::set<StateType>> Qi; - Qi.push_back( ext::set<StateType>( ) ); - Qi.at( 0 ). insert( fsm.getInitialState( ) ); - - int i = 1; - - // 1bc - while( true ) { - Qi.push_back( Qi.at( i - 1 ) ); - - for( const auto & p : Qi.at( i - 1 ) ) - for( const auto & transition : fsm.getTransitionsFromState( p ) ) - Qi.at( i ).insert( transition.second ); - - if( Qi.at( i ) == Qi.at( i - 1 ) ) - break; - - i = i + 1; - } - - return Qi.at( i ); -} - template < class SymbolType, class StateType > -ext::set<StateType> ReachableStates::reachableStates( const automaton::NFA < SymbolType, StateType > & fsm ) { +ext::set<StateType> ReachableStates::reachableStates( const automaton::CompactNFA < SymbolType, StateType > & fsm ) { // 1a ext::deque<ext::set<StateType>> Qi; Qi.push_back( ext::set<StateType>( ) ); @@ -240,7 +200,7 @@ ext::set<StateType> ReachableStates::reachableStates( const automaton::NFA < Sym for( const auto & p : Qi.at( i - 1 ) ) for( const auto & transition : fsm.getTransitionsFromState( p ) ) - Qi.at( i ).insert( transition.second ); + Qi.at( i ).insert( transition.second.begin(), transition.second.end() ); if( Qi.at( i ) == Qi.at( i - 1 ) ) break; @@ -252,7 +212,7 @@ ext::set<StateType> ReachableStates::reachableStates( const automaton::NFA < Sym } template < class SymbolType, class StateType > -ext::set<StateType> ReachableStates::reachableStates( const automaton::DFA < SymbolType, StateType > & fsm ) { +ext::set<StateType> ReachableStates::reachableStates( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ) { // 1a ext::deque<ext::set<StateType>> Qi; Qi.push_back( ext::set<StateType>( ) ); @@ -266,7 +226,7 @@ ext::set<StateType> ReachableStates::reachableStates( const automaton::DFA < Sym for( const auto & p : Qi.at( i - 1 ) ) for( const auto & transition : fsm.getTransitionsFromState( p ) ) - Qi.at( i ).insert( transition.second ); + Qi.at( i ).insert( transition.second.begin(), transition.second.end() ); if( Qi.at( i ) == Qi.at( i - 1 ) ) break; diff --git a/alib2algo/src/automaton/properties/UsefulStates.h b/alib2algo/src/automaton/properties/UsefulStates.h index e5632916ee..b9ce79c6b9 100644 --- a/alib2algo/src/automaton/properties/UsefulStates.h +++ b/alib2algo/src/automaton/properties/UsefulStates.h @@ -60,20 +60,6 @@ public: template < class T > static ext::set < typename automaton::StateTypeOfAutomaton < T > > usefulStates( const T & fsm ); - /** - * Finds all useful states of a deterministic finite automaton. - * Using closure implementation of the BFS algorithm. - * - * @overload - * - * @tparam SymbolType Type for the input symbols. - * @tparam StateType Type for the states. - * @param fsm automaton - * @return set of useful states of @p fsm - */ - template < class SymbolType, class StateType > - static ext::set<StateType> usefulStates( const automaton::DFA < SymbolType, StateType > & fsm ); - /** * Finds all useful states of a deterministic finite tree automaton. * Using closure implementation of the BFS algorithm. @@ -131,30 +117,6 @@ ext::set < typename automaton::StateTypeOfAutomaton < T > > UsefulStates::useful return Qi.at( i ); } -template < class SymbolType, class StateType > -ext::set<StateType> UsefulStates::usefulStates( const automaton::DFA < SymbolType, StateType > & fsm ) { - // 1a - ext::deque<ext::set<StateType>> Qi; - Qi.push_back( ext::set<StateType>( ) ); - Qi.at( 0 ) = fsm.getFinalStates( ); - - int i = 1; - - // 1bc - while( true ) { - Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi - for( const auto & p : Qi.at( i - 1 ) ) - for( const auto & t : fsm.getTransitionsToState( p ) ) - Qi.at( i ).insert( t.first.first ); - - if( Qi.at( i ) == Qi.at( i - 1 ) ) - break; - - i = i + 1; - } - return Qi.at( i ); -} - template < class SymbolType, class RankType, class StateType > ext::set<StateType> UsefulStates::usefulStates( const automaton::DFTA < SymbolType, RankType, StateType > & fta ) { // 1a diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index f68721155d..3befead556 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h @@ -63,21 +63,13 @@ public: template < class T > static T remove( const T & automaton ); - /** - * @overload - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - */ - template < class SymbolType, class EpsilonType, class StateType > - static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > remove( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); - /** * @overload * @tparam SymbolType Type for input symbols. * @tparam StateType Type for states. */ template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, StateType > remove( const automaton::NFA < SymbolType, StateType > & fsm ); + static automaton::ExtendedNFA < SymbolType, StateType > remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ); /** * @overload @@ -85,7 +77,7 @@ public: * @tparam StateType Type for states. */ template < class SymbolType, class StateType > - static automaton::DFA < SymbolType, StateType > remove( const automaton::DFA < SymbolType, StateType > & fsm ); + static automaton::CompactNFA < SymbolType, StateType > remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ); /** * @overload @@ -138,33 +130,6 @@ T UnreachableStatesRemover::remove ( const T & fsm ) { // 2 T 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 ) ) - for(const auto& to : transition.second ) - M.addTransition( transition.first.first, transition.first.second, to ); - - ext::set<StateType> 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 SymbolType, class EpsilonType, class StateType > -automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > UnreachableStatesRemover::remove( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ) { - // 1a - ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fsm ); - - // 2 - automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > M(fsm.getInitialState() ); - for( const auto & q : Qa ) M.addState( q ); @@ -184,12 +149,12 @@ automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > UnreachableStatesRe } template < class SymbolType, class StateType > -automaton::NFA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::NFA < SymbolType, StateType > & fsm ) { +automaton::ExtendedNFA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ) { // 1a ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fsm ); // 2 - automaton::NFA < SymbolType, StateType > M(fsm.getInitialState() ); + automaton::ExtendedNFA < SymbolType, StateType > M(fsm.getInitialState() ); for( const auto & q : Qa ) M.addState( q ); @@ -199,7 +164,8 @@ automaton::NFA < SymbolType, StateType > UnreachableStatesRemover::remove( const for( const auto & transition : fsm.getTransitions( ) ) if( Qa.count( transition.first.first ) ) - M.addTransition( transition.first.first, transition.first.second, transition.second ); + for(const auto& to : transition.second ) + M.addTransition( transition.first.first, transition.first.second, to ); ext::set<StateType> intersect; std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) ); @@ -210,12 +176,12 @@ automaton::NFA < SymbolType, StateType > UnreachableStatesRemover::remove( const } template < class SymbolType, class StateType > -automaton::DFA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::DFA < SymbolType, StateType > & fsm ) { +automaton::CompactNFA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ) { // 1a ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fsm ); // 2 - automaton::DFA < SymbolType, StateType > M(fsm.getInitialState() ); + automaton::CompactNFA < SymbolType, StateType > M(fsm.getInitialState() ); for( const auto & q : Qa ) M.addState( q ); @@ -225,7 +191,8 @@ automaton::DFA < SymbolType, StateType > UnreachableStatesRemover::remove( const for( const auto & transition : fsm.getTransitions( ) ) if( Qa.count( transition.first.first ) ) - M.addTransition( transition.first.first, transition.first.second, transition.second ); + for(const auto& to : transition.second ) + M.addTransition( transition.first.first, transition.first.second, to ); ext::set<StateType> intersect; std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) ); diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h index b6810fd5e1..196df9979f 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h @@ -59,21 +59,13 @@ public: template < class T > static T remove( const T & automaton ); - /** - * @overload - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - */ - template < class SymbolType, class EpsilonType, class StateType > - static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > remove( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); - /** * @overload * @tparam SymbolType Type for input symbols. * @tparam StateType Type for states. */ template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, StateType > remove( const automaton::NFA < SymbolType, StateType > & fsm ); + static automaton::ExtendedNFA < SymbolType, StateType > remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ); /** * @overload @@ -81,7 +73,7 @@ public: * @tparam StateType Type for states. */ template < class SymbolType, class StateType > - static automaton::DFA < SymbolType, StateType > remove( const automaton::DFA < SymbolType, StateType > & fsm ); + static automaton::CompactNFA < SymbolType, StateType > remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ); /** * @overload @@ -135,35 +127,6 @@ T UselessStatesRemover::remove( const T & fsm ) { return M; } - for( const auto & q : Qu ) - M.addState( q ); - - for( const auto & t : fsm.getTransitions( ) ) - for( const auto & to : t.second ) - if( /* this part is not needed Qu.count(t.first.first) ) && */ Qu.count(to) ) - M.addTransition( t.first.first, t.first.second, to ); - - for( const auto & q : fsm.getFinalStates( ) ) - M.addFinalState( q ); - - return M; -} - -template < class SymbolType, class EpsilonType, class StateType > -automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > UselessStatesRemover::remove( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ) { - // 1. - ext::set<StateType> Qu = automaton::properties::UsefulStates::usefulStates( fsm ); - - // 2. - automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > M ( fsm.getInitialState () ); - - for( const auto & a : fsm.getInputAlphabet( ) ) - M.addInputSymbol( a ); - - if(Qu.size() == 0) { - return M; - } - for( const auto & q : Qu ) M.addState( q ); @@ -178,12 +141,12 @@ automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > UselessStatesRemove } template < class SymbolType, class StateType > -automaton::NFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::NFA < SymbolType, StateType > & fsm ) { +automaton::ExtendedNFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ) { // 1. ext::set<StateType> Qu = automaton::properties::UsefulStates::usefulStates( fsm ); // 2. - automaton::NFA < SymbolType, StateType > M ( fsm.getInitialState () ); + automaton::ExtendedNFA < SymbolType, StateType > M ( fsm.getInitialState () ); for( const auto & a : fsm.getInputAlphabet( ) ) M.addInputSymbol( a ); @@ -196,8 +159,9 @@ automaton::NFA < SymbolType, StateType > UselessStatesRemover::remove( const aut M.addState( q ); for( const auto & t : fsm.getTransitions( ) ) - if( /* this part is not needed Qu.count( t.first.first ) && */ Qu.count( t.second ) ) - M.addTransition( t.first.first, t.first.second, t.second ); + for( const auto & to : t.second ) + if( /* this part is not needed Qu.count(t.first.first) ) && */ Qu.count(to) ) + M.addTransition( t.first.first, t.first.second, to ); for( const auto & q : fsm.getFinalStates( ) ) M.addFinalState( q ); @@ -206,12 +170,12 @@ automaton::NFA < SymbolType, StateType > UselessStatesRemover::remove( const aut } template < class SymbolType, class StateType > -automaton::DFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::DFA < SymbolType, StateType > & fsm ) { +automaton::CompactNFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ) { // 1. ext::set<StateType> Qu = automaton::properties::UsefulStates::usefulStates( fsm ); // 2. - automaton::DFA < SymbolType, StateType > M ( fsm.getInitialState () ); + automaton::CompactNFA < SymbolType, StateType > M ( fsm.getInitialState () ); for( const auto & a : fsm.getInputAlphabet( ) ) M.addInputSymbol( a ); @@ -224,8 +188,9 @@ automaton::DFA < SymbolType, StateType > UselessStatesRemover::remove( const aut M.addState( q ); for( const auto & t : fsm.getTransitions( ) ) - if( /* this part is not needed Qu.count( t.first.first ) && */ Qu.count( t.second ) ) - M.addTransition( t.first.first, t.first.second, t.second ); + for( const auto & to : t.second ) + if( /* this part is not needed Qu.count(t.first.first) ) && */ Qu.count(to) ) + M.addTransition( t.first.first, t.first.second, to ); for( const auto & q : fsm.getFinalStates( ) ) M.addFinalState( q ); -- GitLab