diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index 687deced223d6008b8c7b836180269a9e05a30d3..7a07174427df0b3f43205dbefdfe8c7d7c9375c5 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h @@ -52,60 +52,47 @@ namespace simplify { class UnreachableStatesRemover { public: /** - * Removes unreachable states from an automaton. + * Removes unreachable states from a finite automaton. * * @tparam T type of a finite automaton * - * @param automaton automaton to trim + * @param fsm automaton to remove unreachable states from * - * @return @p automaton without unreachable states + * @return @p fsm without unreachable states */ template < class T > - static T remove( const T & fsm ); + static ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isCompactNFA < T > || isExtendedNFA < T >, T > remove ( const T & fsm ); /** - * @overload - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - */ - template < class SymbolType, class StateType > - static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ); - - /** - * Removes unreachable states from a deterministic finite tree automaton. - * * @overload * * @tparam SymbolType Type for input symbols. - * @tparam RankType Type for rank (arity) in ranked alphabet. * @tparam StateType Type for states. * - * @param dfta automaton to trim + * @param fsm automaton to remove unreachable states from * - * @return @p autoamton without unreachable states + * @return @p fsm without unreachable states */ template < class SymbolType, class StateType > - static automaton::DFTA < SymbolType, StateType > remove( const automaton::DFTA < SymbolType, StateType > & fta ); + static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ); /** - * Removes unreachable states from a deterministic finite tree automaton. + * Removes unreachable states from a finite tree automaton. * * @overload * - * @tparam SymbolType Type for input symbols. - * @tparam RankType Type for rank (arity) in ranked alphabet. - * @tparam StateType Type for states. + * @tparam T type of a finite tree automaton * - * @param dfta automaton to trim + * @param fta automaton to remove unreachable states from * - * @return @p autoamton without unreachable states + * @return @p fta without unreachable states */ - template < class SymbolType, class StateType > - static automaton::NFTA < SymbolType, StateType > remove( const automaton::NFTA < SymbolType, StateType > & fta ); + template < class T > + static ext::require < isDFTA < T > || isNFTA < T >, T > remove ( const T & fta ); }; template < class T > -T UnreachableStatesRemover::remove ( const T & fsm ) { +ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isCompactNFA < T > || isExtendedNFA < T >, T > UnreachableStatesRemover::remove ( const T & fsm ) { using StateType = typename T::StateType; // 1a @@ -114,20 +101,16 @@ 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 ); + M.setStates( Qa ); + M.setInputAlphabet( fsm.getInputAlphabet( ) ); for( const auto & transition : fsm.getTransitions( ) ) if( Qa.count( transition.first.first ) ) M.addTransition( transition.first.first, transition.first.second, transition.second ); - 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 ); + ext::set<StateType> finalStates; + std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) ); + M.setFinalStates( finalStates ); return M; } @@ -140,74 +123,41 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov // 2 automaton::MultiInitialStateNFA < SymbolType, StateType > M; - for( const auto & q : Qa ) - M.addState( q ); - + M.setStates( Qa ); M.setInitialStates( fsm.getInitialStates() ); - - for( const auto & a : fsm.getInputAlphabet( ) ) - M.addInputSymbol( a ); + M.setInputAlphabet( fsm.getInputAlphabet( ) ); for( const auto & transition : fsm.getTransitions( ) ) if( Qa.count( transition.first.first ) ) M.addTransition( transition.first.first, transition.first.second, transition.second ); - 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 ); + ext::set<StateType> finalStates; + std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) ); + M.setFinalStates( finalStates ); return M; } -template < class SymbolType, class StateType > -automaton::DFTA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::DFTA < SymbolType, StateType > & fta ) { - // 1a - ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fta ); - - // 2 - automaton::DFTA < SymbolType, StateType > M; - - for( const auto & q : Qa ) - M.addState( q ); - - for( const auto & a : fta.getInputAlphabet( ) ) - M.addInputSymbol( a ); - - for( const auto & transition : fta.getTransitions( ) ) - if( std::all_of ( transition.first.second.begin ( ), transition.first.second.end ( ), [ & ] ( const StateType & state ) { return Qa.count ( state ); } ) ) - M.addTransition ( transition.first.first, transition.first.second, transition.second ); - - ext::set<StateType> intersect; - std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) ); - for( auto const & state : intersect ) - M.addFinalState( state ); - - return M; -} +template < class T > +ext::require < isDFTA < T > || isNFTA < T >, T > UnreachableStatesRemover::remove( const T & fta ) { + using StateType = typename T::StateType; -template < class SymbolType, class StateType > -automaton::NFTA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::NFTA < SymbolType, StateType > & fta ) { // 1a ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fta ); // 2 - automaton::NFTA < SymbolType, StateType > M; - - for( const auto & q : Qa ) - M.addState( q ); + T M; - for( const auto & a : fta.getInputAlphabet( ) ) - M.addInputSymbol( a ); + M.setStates( Qa ); + M.setInputAlphabet( fta.getInputAlphabet( ) ); for( const auto & transition : fta.getTransitions( ) ) if( std::all_of ( transition.first.second.begin ( ), transition.first.second.end ( ), [ & ] ( const StateType & state ) { return Qa.count ( state ); } ) ) M.addTransition ( transition.first.first, transition.first.second, transition.second ); - ext::set<StateType> intersect; - std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) ); - for( auto const & state : intersect ) - M.addFinalState( state ); + ext::set<StateType> finalStates; + std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) ); + M.setFinalStates( std::move ( finalStates ) ); return M; }