diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h index 8144e092f4cf87f09784e37fc6709da2b8f76e75..a4d507c6b158b0bec6dc48dd27df729a95ab495d 100644 --- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h @@ -105,8 +105,7 @@ regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automa solver.addEquation ( q, regexp::UnboundedRegExpEpsilon < SymbolType > { } ); for ( const auto & p : automaton.getTransitions ( ) ) - for ( const StateType & q : p.second ) - solver.addEquation ( p.first.first, q, regexp::UnboundedRegExpSymbol < SymbolType > { p.first.second } ); + solver.addEquation ( p.first.first, p.second, regexp::UnboundedRegExpSymbol < SymbolType > { p.first.second } ); regexp::UnboundedRegExpAlternation < SymbolType > alternation; for ( const StateType & initialSymbol : automaton.getInitialStates ( ) ) diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.hxx index 29b98a5507ae3d9d2585c89f5c0c2f3bb1e622b5..e1f3e1980f21707d2f6dd156911d41e5162d1009 100644 --- a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.hxx +++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.hxx @@ -37,10 +37,10 @@ automaton::DFA < SymbolType, ext::set < StateType > > Determinize::determinize ( ext::set < StateType > dfaState; for ( StateType nfaState : state ) { - auto iter = nfa.getTransitions ( ).find ( ext::make_pair ( std::move ( nfaState ), input ) ); + auto range = nfa.getTransitions ( ).equal_range ( ext::make_pair ( std::move ( nfaState ), input ) ); - if ( iter != nfa.getTransitions ( ).end ( ) ) - dfaState.insert ( iter->second.begin ( ), iter->second.end ( ) ); + for ( auto & transition : range ) + dfaState.insert ( transition.second ); } // 4 diff --git a/alib2algo/src/automaton/generate/RandomizeAutomaton.h b/alib2algo/src/automaton/generate/RandomizeAutomaton.h index d57f6a5014c035307f4d08c4c99af26380d71ca1..3c67eed54ed1ba678334c39d3e2330f0014c3d41 100644 --- a/alib2algo/src/automaton/generate/RandomizeAutomaton.h +++ b/alib2algo/src/automaton/generate/RandomizeAutomaton.h @@ -104,9 +104,8 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > RandomizeAutomaton::ra for ( const StateType & finalState : origFSM.getFinalStates ( ) ) res.addFinalState ( statePermutationMap.find ( finalState )->second ); - for ( const std::pair < std::pair < StateType, SymbolType >, ext::set < StateType > > & transition : origFSM.getTransitions ( ) ) - for ( const StateType & target : transition.second ) - res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( target )->second ); + for ( const std::pair < std::pair < StateType, SymbolType >, StateType > & transition : origFSM.getTransitions ( ) ) + res.addTransition ( statePermutationMap.find ( transition.first.first )->second, transition.first.second, statePermutationMap.find ( transition.second )->second ); return res; } diff --git a/alib2algo/src/automaton/properties/ReachableStates.h b/alib2algo/src/automaton/properties/ReachableStates.h index e497ebefea98bbb4dd124d4c69c25a4262b3ef3c..364991c5f880c5ef83f8c2976e883bf507d5a65d 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.h +++ b/alib2algo/src/automaton/properties/ReachableStates.h @@ -174,7 +174,7 @@ ext::set<StateType> ReachableStates::reachableStates( const automaton::MultiInit 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; diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h index 6eea5391e522b3481e5806a8cee0cfc646ae7b1f..dc19c2c7d7f22e3287cac9caaac70ad62409a256 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -112,12 +112,10 @@ automaton::NFA < SymbolType, StateType > SingleInitialState::convert(const autom // step 2 for ( const auto & q : automaton.getInitialStates ( ) ) for(const auto & kv : automaton.getTransitionsFromState ( q ) ) - for ( const StateType & to : kv.second ) - res.addTransition ( q0, kv.first.second, to ); + res.addTransition ( q0, kv.first.second, kv.second ); for ( const auto & t : automaton.getTransitions ( ) ) - for ( const auto & q : t.second ) - res.addTransition ( t.first.first, t.first.second, q ); + res.addTransition ( t.first.first, t.first.second, t.second ); // step 4, 5 ext::set < StateType > intersection; diff --git a/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h index eabda3151e8be5d10709e69df5e1b7423acb7828..15cf65b91551321536163926eeaa23d0ce3b63f6 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h +++ b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h @@ -110,8 +110,7 @@ automaton::EpsilonNFA < SymbolType, DefaultEpsilonType, StateType > SingleInitia res.addTransition ( q0, q ); for ( const auto & t : automaton.getTransitions ( ) ) - for ( const auto & q : t.second ) - res.addTransition ( t.first.first, t.first.second, q ); + res.addTransition ( t.first.first, t.first.second, t.second ); // step 4, 5 res.setFinalStates ( automaton.getFinalStates ( ) ); diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index 3befead556ef00901cb048fc696536bc75119351..fc3f1f35a3119349fbd9e52442d816ada90295c9 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h @@ -220,8 +220,7 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov 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 ); + 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( ) ) ); diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h index 196df9979f9b03fa9d14c500900bfd230097eac9..56ef22b9a51720d48996a31f40caee0604a73843 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h @@ -222,9 +222,8 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UselessStatesRemover:: } for( const auto & t : fsm.getTransitions( ) ) - for( const auto & to : t.second ) - if( Qu.count(to) ) - M.addTransition( t.first.first, t.first.second, to ); + if( Qu.count ( t.second ) ) + M.addTransition( t.first.first, t.first.second, t.second ); for( const auto & q : fsm.getFinalStates( ) ) M.addFinalState( q ); diff --git a/alib2algo/src/automaton/transform/AutomataLeftQuotientCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataLeftQuotientCartesianProduct.h index ae61c00efd4417437e31953b8711c76f141c838a..06b0a92f6998f3a09c9f0ecfc63e258ba8dd83c8 100644 --- a/alib2algo/src/automaton/transform/AutomataLeftQuotientCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataLeftQuotientCartesianProduct.h @@ -94,7 +94,8 @@ automaton::MultiInitialStateNFA < SymbolType, ext::pair < StateType1, StateType2 res.setStates ( Q ); for ( std::pair < ext::pair < ext::pair < StateType1, StateType2 >, SymbolType >, ext::set < ext::pair < StateType1, StateType2 > > > transitions : ext::make_mover ( delta ) ) { - res.addTransitions ( transitions.first.first, transitions.first.second, transitions.second ); + for ( ext::pair < StateType1, StateType2 > to : ext::make_mover ( transitions.second ) ) + res.addTransition ( transitions.first.first, transitions.first.second, to ); } res.setInitialStates ( Q0 ); diff --git a/alib2algo/src/automaton/transform/Reverse.h b/alib2algo/src/automaton/transform/Reverse.h index 532cb2de17496fe74b8ac00577964597e838cb0c..eded7b44fc4af63ad7769aa4b872eb3aacf20bf0 100644 --- a/alib2algo/src/automaton/transform/Reverse.h +++ b/alib2algo/src/automaton/transform/Reverse.h @@ -101,8 +101,7 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > Reverse::convert(const res.setInputAlphabet(automaton.getInputAlphabet()); for(const auto& t : automaton.getTransitions()) - for(const auto& q : t.second) - res.addTransition(q, t.first.second, t.first.first); + res.addTransition ( t.second, t.first.second, t.first.first); return res; } diff --git a/alib2aux/src/convert/DotConverter.h b/alib2aux/src/convert/DotConverter.h index b5ec4af8baf1994b8011b298bf2f9d037191eded..774d1bde6b7185a19bba06aad6048ef270732e3c 100644 --- a/alib2aux/src/convert/DotConverter.h +++ b/alib2aux/src/convert/DotConverter.h @@ -822,22 +822,20 @@ void DotConverter::transitions(const automaton::MultiInitialStateNFA < SymbolTyp for (const auto& transition : fsm.getTransitions()) { std::string symbol = replace ( factory::StringDataFactory::toString ( transition.first.second ), "\"", "\\\"" ); - for(const StateType& to : transition.second) { - std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); - ext::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); + std::pair<int, int> key(states.find(transition.first.first)->second, states.find(transition.second)->second); + ext::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); - if (mapit == transitions.end()) { - transitions.insert(std::make_pair(key, symbol)); - } else { - mapit->second += ","; + if (mapit == transitions.end()) { + transitions.insert(std::make_pair(key, symbol)); + } else { + mapit->second += ","; - size_t pos = mapit->second.find_last_of("\n"); - if(pos == std::string::npos) pos = 0; - if(mapit->second.size() - pos > 100) mapit->second += "\n"; - else mapit->second += " "; + size_t pos = mapit->second.find_last_of("\n"); + if(pos == std::string::npos) pos = 0; + if(mapit->second.size() - pos > 100) mapit->second += "\n"; + else mapit->second += " "; - mapit->second += symbol; - } + mapit->second += symbol; } } diff --git a/alib2aux/src/convert/GasTexConverter.h b/alib2aux/src/convert/GasTexConverter.h index 57d3324fab99640e0b21b6d70b1d113ea722a9d6..65854d9dcdb003b305305e1d1f252312a7e61a6e 100644 --- a/alib2aux/src/convert/GasTexConverter.h +++ b/alib2aux/src/convert/GasTexConverter.h @@ -908,17 +908,15 @@ template<class SymbolType, class StateType> void GasTexConverter::transitions(const automaton::MultiInitialStateNFA < SymbolType, StateType >& fsm, std::ostream& out) { ext::map<std::pair<std::string, std::string>, std::string> transitionMap; for (const auto& transition : fsm.getTransitions()) { - for(const auto& to : transition.second) { - std::pair<std::string, std::string> key(replace ( factory::StringDataFactory::toString ( transition.first.first ), "\"", "\\\"" ), replace ( factory::StringDataFactory::toString ( to ), "\"", "\\\"" ) ); + std::pair<std::string, std::string> key(replace ( factory::StringDataFactory::toString ( transition.first.first ), "\"", "\\\"" ), replace ( factory::StringDataFactory::toString ( transition.second ), "\"", "\\\"" ) ); - std::string symbol = replace ( factory::StringDataFactory::toString ( transition.first.second ), "\"", "\\\"" ); + std::string symbol = replace ( factory::StringDataFactory::toString ( transition.first.second ), "\"", "\\\"" ); - auto mapIterator = transitionMap.find(key); - if (mapIterator == transitionMap.end()) { - transitionMap.insert(make_pair(key, symbol)); - } else { - mapIterator->second += ", " + symbol; - } + auto mapIterator = transitionMap.find(key); + if (mapIterator == transitionMap.end()) { + transitionMap.insert(make_pair(key, symbol)); + } else { + mapIterator->second += ", " + symbol; } } printTransitionMap(transitionMap, out); diff --git a/alib2aux/src/convert/TikZConverter.h b/alib2aux/src/convert/TikZConverter.h index bb13e2937f4806aa19e27fa5c73fdcf6c20e52d9..4b0254b768d44a91051b52d276f5c62a6ac18025 100644 --- a/alib2aux/src/convert/TikZConverter.h +++ b/alib2aux/src/convert/TikZConverter.h @@ -775,26 +775,24 @@ void TikZConverter::transitions ( const automaton::MultiInitialStateNFA < Symbol for ( const auto & transition : fsm.getTransitions ( ) ) { std::string symbol = replace ( factory::StringDataFactory::toString ( transition.first.second ), "\"", "\\\"" ); - for ( const StateType & to : transition.second ) { - std::pair < int, int > key ( states.find ( transition.first.first )->second, states.find ( to )->second ); - ext::map < std::pair < int, int >, std::string >::iterator mapit = transitions.find ( key ); + std::pair < int, int > key ( states.find ( transition.first.first )->second, states.find ( transition.second )->second ); + ext::map < std::pair < int, int >, std::string >::iterator mapit = transitions.find ( key ); - if ( mapit == transitions.end ( ) ) { - transitions.insert ( std::make_pair ( key, symbol ) ); - } else { - mapit->second += ","; + if ( mapit == transitions.end ( ) ) { + transitions.insert ( std::make_pair ( key, symbol ) ); + } else { + mapit->second += ","; - size_t pos = mapit->second.find_last_of ( "\n" ); + size_t pos = mapit->second.find_last_of ( "\n" ); - if ( pos == std::string::npos ) pos = 0; + if ( pos == std::string::npos ) pos = 0; - if ( mapit->second.size ( ) - pos > 100 ) - mapit->second += "\n"; - else - mapit->second += " "; + if ( mapit->second.size ( ) - pos > 100 ) + mapit->second += "\n"; + else + mapit->second += " "; - mapit->second += symbol; - } + mapit->second += symbol; } } diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h index 5c01a3e8ccd7735ccc1fd2050f3192de8ec852fa..a6d71301f7131f35e3d3da470b1f72c71ef6107a 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.h +++ b/alib2data/src/automaton/FSM/CompactNFA.h @@ -475,7 +475,7 @@ CompactNFA < SymbolType, StateType >::CompactNFA ( const EpsilonNFA < SymbolType template < class SymbolType, class StateType > CompactNFA < SymbolType, StateType >::CompactNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ) : CompactNFA ( other.getStates ( ) + ext::set < StateType > { common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ) }, other.getInputAlphabet ( ), common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ), other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) - transitions.insert ( ext::make_pair ( transition.first.first, ext::vector < SymbolType > { transition.first.second } ), transition.second ); + transitions [ ext::make_pair ( transition.first.first, ext::vector < SymbolType > { transition.first.second } ) ].insert ( transition.second ); transitions.insert ( ext::make_pair ( this->getInitialState ( ), ext::vector < SymbolType > { } ), other.getInitialStates ( ) ); } diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h index 47dbf65d0380b6a4e8c8545f36bef41916c0368b..044887ac99ab431f7acc5a030ad241db4e0d23d7 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.h +++ b/alib2data/src/automaton/FSM/EpsilonNFA.h @@ -547,8 +547,7 @@ EpsilonNFA < SymbolType, EpsilonType, StateType >::EpsilonNFA ( StateType initia template<class SymbolType, class EpsilonType, class StateType > EpsilonNFA < SymbolType, EpsilonType, StateType >::EpsilonNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ) : EpsilonNFA ( other.getStates ( ) + ext::set < StateType > { common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ) }, other.getInputAlphabet ( ), common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ), other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) - for ( const auto & toState : transition.second ) - transitions.insert ( ext::make_pair ( transition.first.first, ext::variant < EpsilonType, SymbolType > ( transition.first.second ) ), toState ); + transitions.insert ( ext::make_pair ( transition.first.first, ext::variant < EpsilonType, SymbolType > ( transition.first.second ) ), transition.second ); for ( const auto & initialState : other.getInitialStates ( ) ) transitions.insert ( ext::make_pair ( getInitialState ( ), ext::variant < EpsilonType, SymbolType >::template from < EpsilonType > ( ) ), initialState ); diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h index 23dbea22f762d35e45d04270d927063a1dc96261..dc0127df227e6d2fe0efe00dd7c04347a2435b9c 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.h +++ b/alib2data/src/automaton/FSM/ExtendedNFA.h @@ -500,7 +500,7 @@ template<class SymbolType, class StateType > ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ) : ExtendedNFA ( other.getStates ( ) + ext::set < StateType > { common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ) }, other.getInputAlphabet ( ), common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), other.getStates ( ) ), other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) { ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = ext::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) ); - transitions[key] = transition.second; + transitions[key].insert ( transition.second ); } ext::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = ext::make_pair ( this->getInitialState ( ), regexp::UnboundedRegExpStructure < SymbolType > ( ) ); diff --git a/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h index 3bfa3cbe2a9257d37ac40b23147cbdcaa2ffaf08..915871184cda91ca0db4035a9cead0a528005371 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h @@ -616,7 +616,7 @@ template<class SymbolType, class EpsilonType, class StateType > MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::MultiInitialStateEpsilonNFA ( const MultiInitialStateNFA < SymbolType, StateType > & other ) : MultiInitialStateEpsilonNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialStates ( ), other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) { ext::pair < StateType, ext::variant < EpsilonType, SymbolType > > key = ext::make_pair ( transition.first.first, ext::variant < EpsilonType, SymbolType > ( transition.first.second ) ); - transitions[key] = transition.second; + transitions[key].insert ( transition.second ); } } diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h index 16cf9c9972189f3f8a39e1fbcaee6cbf4dfa0b26..b221c01923e138dace65f02861c0dcf92510c58d 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h @@ -27,7 +27,7 @@ #include <ostream> #include <sstream> -#include <alib/map> +#include <alib/multimap> #include <alib/set> #include <alib/compare> @@ -73,7 +73,7 @@ class MultiInitialStateNFA final : public ext::CompareOperators < MultiInitialSt /** * Transition function as mapping from a state times an input symbol on the left hand side to a set of states. */ - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > transitions; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > transitions; public: /** @@ -327,19 +327,6 @@ public: */ bool addTransition ( StateType current, SymbolType input, StateType next ); - /** - * \brief Add a transitions to the automaton. - * - * \details The transition is in a form A \times a -> P(Q), where A \in Q, a \in T, P(Q) is a powerset of states. - * - * \param current the source state (A) - * \param input the input symbol (a) - * \param next the target states (P(Q)) - * - * \throws AutomatonException when transitions contain states or symbols not present in the automaton components - */ - void addTransitions ( StateType current, SymbolType input, ext::set < StateType > next ); - /** * \brief Removes a transition from the automaton. * @@ -358,14 +345,14 @@ public: * * \returns transition function of the automaton */ - const ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > & getTransitions ( ) const &; + const ext::multimap < ext::pair < StateType, SymbolType >, StateType > & getTransitions ( ) const &; /** * Get the transition function of the automaton in its natural form. * * \returns transition function of the automaton */ - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > && getTransitions ( ) &&; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > && getTransitions ( ) &&; /** * Get a subset of the transition function of the automaton, with the source state fixed in the transitions natural representation. @@ -374,7 +361,7 @@ public: * * \returns a subset of the transition function of the automaton with the source state fixed */ - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getTransitionsFromState ( const StateType & from ) const; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > getTransitionsFromState ( const StateType & from ) const; /** * Get a subset of the transition function of the automaton, with the target state fixed in the transitions natural representation. @@ -383,7 +370,7 @@ public: * * \returns a subset of the transition function of the automaton with the target state fixed */ - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > getTransitionsToState ( const StateType & from ) const; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > getTransitionsToState ( const StateType & from ) const; /** * \brief Determines whether the automaton is deterministic. @@ -460,13 +447,13 @@ MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( ) : Multi template < class SymbolType, class StateType > MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( const DFA < SymbolType, StateType > & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) - transitions[transition.first].insert ( transition.second ); + transitions.insert ( transition ); } template < class SymbolType, class StateType > MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( const NFA < SymbolType, StateType > & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) { for ( const auto & transition : other.getTransitions ( ) ) - transitions[transition.first].insert ( transition.second ); + transitions.insert ( transition ); } template < class SymbolType, class StateType > @@ -480,68 +467,63 @@ bool MultiInitialStateNFA < SymbolType, StateType >::addTransition ( StateType f if ( !getStates ( ).count ( to ) ) throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist." ); - ext::pair < StateType, SymbolType > key = ext::make_pair ( std::move ( from ), std::move ( input ) ); - - return transitions[std::move ( key )].insert ( std::move ( to ) ).second; -} - -template < class SymbolType, class StateType > -void MultiInitialStateNFA < SymbolType, StateType >::addTransitions ( StateType from, SymbolType input, ext::set < StateType > to ) { - if ( !getStates ( ).count ( from ) ) - throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist." ); - - if ( !getInputAlphabet ( ).count ( input ) ) - throw AutomatonException ( "Input symbol \"" + ext::to_string ( input ) + "\" doesn't exist." ); - - if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) - throw AutomatonException ( "Some target states don't exist." ); + auto upper_bound = transitions.upper_bound ( ext::tie ( from, input ) ); + auto lower_bound = transitions.lower_bound ( ext::tie ( from, input ) ); + auto iter = std::lower_bound ( lower_bound, upper_bound, to, [ ] ( const auto & transition, const auto & target ) { return transition.second < target; } ); + if ( iter != upper_bound && to >= iter->second ) + return false; ext::pair < StateType, SymbolType > key = ext::make_pair ( std::move ( from ), std::move ( input ) ); - - transitions [ std::move ( key ) ].insert ( ext::make_mover ( to ).begin ( ), ext::make_mover ( to ).end ( ) ); + transitions.insert ( iter, std::make_pair ( std::move ( key ), std::move ( to ) ) ); + return true; } template < class SymbolType, class StateType > bool MultiInitialStateNFA < SymbolType, StateType >::removeTransition ( const StateType & from, const SymbolType & input, const StateType & to ) { - ext::pair < StateType, SymbolType > key = ext::make_pair ( from, input ); + auto upper_bound = transitions.upper_bound ( ext::tie ( from, input ) ); + auto lower_bound = transitions.lower_bound ( ext::tie ( from, input ) ); + auto iter = std::find_if ( lower_bound, upper_bound, [ & ] ( const auto & transition ) { return transition.second == to; } ); + if ( iter == upper_bound ) + return false; - return transitions[key].erase ( to ); + transitions.erase ( iter ); + return true; } template < class SymbolType, class StateType > -const ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > & MultiInitialStateNFA < SymbolType, StateType >::getTransitions ( ) const & { +const ext::multimap < ext::pair < StateType, SymbolType >, StateType > & MultiInitialStateNFA < SymbolType, StateType >::getTransitions ( ) const & { return transitions; } template < class SymbolType, class StateType > -ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > && MultiInitialStateNFA < SymbolType, StateType >::getTransitions ( ) && { +ext::multimap < ext::pair < StateType, SymbolType >, StateType > && MultiInitialStateNFA < SymbolType, StateType >::getTransitions ( ) && { return std::move ( transitions ); } template < class SymbolType, class StateType > -ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > MultiInitialStateNFA < SymbolType, StateType >::getTransitionsFromState ( const StateType & from ) const { +ext::multimap < ext::pair < StateType, SymbolType >, StateType > MultiInitialStateNFA < SymbolType, StateType >::getTransitionsFromState ( const StateType & from ) const { if ( !getStates ( ).count ( from ) ) throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" ); - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > transitionsFromState; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > transitionsFromState; - for ( const std::pair < const ext::pair < StateType, SymbolType >, ext::set < StateType > > & transition : transitions ) + for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : transitions ) if ( transition.first.first == from ) - transitionsFromState[transition.first].insert ( transition.second.begin ( ), transition.second.end ( ) ); + transitionsFromState.insert ( transition ); return transitionsFromState; } template < class SymbolType, class StateType > -ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > MultiInitialStateNFA < SymbolType, StateType >::getTransitionsToState ( const StateType & to ) const { +ext::multimap < ext::pair < StateType, SymbolType >, StateType > MultiInitialStateNFA < SymbolType, StateType >::getTransitionsToState ( const StateType & to ) const { if ( !getStates ( ).count ( to ) ) throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist" ); - ext::map < ext::pair < StateType, SymbolType >, ext::set < StateType > > transitionsToState; + ext::multimap < ext::pair < StateType, SymbolType >, StateType > transitionsToState; - for ( const std::pair < const ext::pair < StateType, SymbolType >, ext::set < StateType > > & transition : transitions ) - if ( transition.second.find ( to ) != transition.second.end ( ) ) - transitionsToState[transition.first].insert ( to ); + for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : transitions ) + if ( transition.second == to ) + transitionsToState.insert ( transition ); return transitionsToState; } @@ -609,7 +591,7 @@ public: * \returns true if the symbol is used, false othervise */ static bool used ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) { - for ( const std::pair < const ext::pair < StateType, SymbolType >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) + for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) ) if ( transition.first.second == symbol ) return true; @@ -662,8 +644,8 @@ public: if ( automaton.getFinalStates ( ).count ( state ) ) return true; - for ( const std::pair < const ext::pair < StateType, SymbolType >, ext::set < StateType > > & transition : automaton.getTransitions ( ) ) - if ( ( transition.first.first == state ) || ( transition.second.find ( state ) != transition.second.end ( ) ) ) + for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) ) + if ( transition.first.first == state || transition.second == state ) return true; return false; @@ -792,12 +774,12 @@ struct normalize < automaton::MultiInitialStateNFA < SymbolType, StateType > > { automaton::MultiInitialStateNFA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( initialStates ), std::move ( finalStates ) ); - for ( std::pair < ext::pair < StateType, SymbolType >, ext::set < StateType > > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) { + for ( std::pair < ext::pair < StateType, SymbolType >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) { DefaultStateType from = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.first.first ) ); DefaultSymbolType input = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( transition.first.second ) ); - ext::set < DefaultStateType > targets = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.second ) ); + DefaultStateType target = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) ); - res.addTransitions ( std::move ( from ), std::move ( input ), std::move ( targets ) ); + res.addTransition ( std::move ( from ), std::move ( input ), std::move ( target ) ); } return res; diff --git a/alib2data/src/automaton/xml/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/xml/FSM/MultiInitialStateNFA.h index 4564ebb5de943faf860f933acf64d664fad9a6e1..b57278571ad242cc0a9d2649f1d2e3ea8b9d8c69 100644 --- a/alib2data/src/automaton/xml/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/xml/FSM/MultiInitialStateNFA.h @@ -139,16 +139,15 @@ template < class SymbolType, class StateType > void xmlApi < automaton::MultiInitialStateNFA < SymbolType, StateType > >::composeTransitions ( ext::deque < sax::Token > & out, const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton ) { out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT ); - for ( const auto & transition : automaton.getTransitions ( ) ) - for ( const auto & targetState : transition.second ) { - out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT ); + for ( const auto & transition : automaton.getTransitions ( ) ) { + out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT ); - automaton::AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first ); - automaton::AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second ); - automaton::AutomatonToXMLComposer::composeTransitionTo ( out, targetState ); + automaton::AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first ); + automaton::AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second ); + automaton::AutomatonToXMLComposer::composeTransitionTo ( out, transition.second ); - out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT ); - } + out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT ); + } out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT ); } diff --git a/alib2elgo/src/automaton/properties/efficient/ReachableStates.h b/alib2elgo/src/automaton/properties/efficient/ReachableStates.h index 880ffd63fed6922bdf0658356aff7e28f8aee2ea..ee9f5573f1f90c2eaea7b57c9d17b42dc748cf0a 100644 --- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.h +++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.h @@ -71,7 +71,7 @@ template < class SymbolType, class StateType > ext::set<StateType> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ) { ext::map<StateType, ext::set<StateType>> transitions; for(const auto& transition : fsm.getTransitions()) - transitions[transition.first.first].insert(transition.second.begin(), transition.second.end()); + transitions[transition.first.first].insert(transition.second); ext::deque<StateType> queue ( fsm.getInitialStates( ).begin(), fsm.getInitialStates().end() ); ext::set<StateType> visited = fsm.getInitialStates( ); diff --git a/alib2elgo/src/automaton/properties/efficient/UsefulStates.h b/alib2elgo/src/automaton/properties/efficient/UsefulStates.h index 73507583b89e270b6be8795a4bbbec6745466333..7300ed46ff5ee0d59f9c2c4ae6966e873d5e6757 100644 --- a/alib2elgo/src/automaton/properties/efficient/UsefulStates.h +++ b/alib2elgo/src/automaton/properties/efficient/UsefulStates.h @@ -33,12 +33,10 @@ public: */ template < class T > static ext::set < typename automaton::StateTypeOfAutomaton < T > > usefulStates( const T & fsm ); - template < class SymbolType, class EpsilonType, class StateType > - static ext::set<StateType> usefulStates( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); template < class SymbolType, class StateType > - static ext::set<StateType> usefulStates( const automaton::NFA < SymbolType, StateType > & fsm ); + static ext::set<StateType> usefulStates( const automaton::CompactNFA < SymbolType, StateType > & fsm ); template < class SymbolType, class StateType > - static ext::set<StateType> usefulStates( const automaton::DFA < SymbolType, StateType > & fsm ); + static ext::set<StateType> usefulStates( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ); }; template < class T > @@ -47,30 +45,7 @@ ext::set < typename automaton::StateTypeOfAutomaton < T > > UsefulStates::useful ext::map<StateType, ext::set<StateType>> reversedTransitions; for(const auto& transition : fsm.getTransitions()) - for(const StateType& to : transition.second) - reversedTransitions[to].insert(transition.first.first); - - ext::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() ); - ext::set<StateType> visited = fsm.getFinalStates( ); - - while( !queue.empty() ) { - const ext::set<StateType>& to = reversedTransitions[queue.front()]; - queue.pop_front(); - - for(const StateType& process : to) - if(visited.insert(process).second) { - queue.push_back(std::move(const_cast<StateType&>(process))); - } - } - - return visited; -} - -template < class SymbolType, class EpsilonType, class StateType > -ext::set<StateType> UsefulStates::usefulStates( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ) { - ext::map<StateType, ext::set<StateType>> reversedTransitions; - for(const auto& transition : fsm.getTransitions()) - reversedTransitions[transition.second].insert(transition.first.first); + reversedTransitions [ transition.second ].insert(transition.first.first); ext::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() ); ext::set<StateType> visited = fsm.getFinalStates( ); @@ -89,10 +64,11 @@ ext::set<StateType> UsefulStates::usefulStates( const automaton::EpsilonNFA < Sy } template < class SymbolType, class StateType > -ext::set<StateType> UsefulStates::usefulStates( const automaton::NFA < SymbolType, StateType > & fsm ) { +ext::set<StateType> UsefulStates::usefulStates( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ) { ext::map<StateType, ext::set<StateType>> reversedTransitions; for(const auto& transition : fsm.getTransitions()) - reversedTransitions[transition.second].insert(transition.first.first); + for(const StateType& to : transition.second) + reversedTransitions[to].insert(transition.first.first); ext::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() ); ext::set<StateType> visited = fsm.getFinalStates( ); @@ -111,10 +87,11 @@ ext::set<StateType> UsefulStates::usefulStates( const automaton::NFA < SymbolTyp } template < class SymbolType, class StateType > -ext::set<StateType> UsefulStates::usefulStates( const automaton::DFA < SymbolType, StateType > & fsm ) { +ext::set<StateType> UsefulStates::usefulStates( const automaton::CompactNFA < SymbolType, StateType > & fsm ) { ext::map<StateType, ext::set<StateType>> reversedTransitions; for(const auto& transition : fsm.getTransitions()) - reversedTransitions[transition.second].insert(transition.first.first); + for(const StateType& to : transition.second) + reversedTransitions[to].insert(transition.first.first); ext::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() ); ext::set<StateType> visited = fsm.getFinalStates( ); diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h index 6c30a67bb33ffcdc06bcaf1d1d0a9471a69825b3..f0f1105138a84034c5e510af34490efcfd967206 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h +++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h @@ -169,8 +169,7 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov 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 ); + 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( ) ) ); diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h index 88ba699037f7982d448531054dcbd595e47fd78c..9947bbf81d9dc974b8991fabaeffffd4da56ec7c 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h +++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h @@ -34,12 +34,10 @@ public: */ template < class T > static T remove( const T & automaton ); - template < class SymbolType, class EpsilonType, class StateType > - static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > remove( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm ); template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, StateType > remove( const automaton::NFA < SymbolType, StateType > & fsm ); + static automaton::CompactNFA < SymbolType, StateType > remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ); template < class SymbolType, class StateType > - static automaton::DFA < SymbolType, StateType > remove( const automaton::DFA < SymbolType, StateType > & fsm ); + static automaton::ExtendedNFA < SymbolType, StateType > remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ); template < class SymbolType, class StateType > static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ); }; @@ -61,35 +59,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::efficient::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 ); @@ -104,12 +73,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::CompactNFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::CompactNFA < SymbolType, StateType > & fsm ) { // 1. ext::set<StateType> Qu = automaton::properties::efficient::UsefulStates::usefulStates( fsm ); // 2. - automaton::NFA < SymbolType, StateType > M ( fsm.getInitialState () ); + automaton::CompactNFA < SymbolType, StateType > M ( fsm.getInitialState () ); for( const auto & a : fsm.getInputAlphabet( ) ) M.addInputSymbol( a ); @@ -122,8 +91,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 ); @@ -132,12 +102,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::ExtendedNFA < SymbolType, StateType > UselessStatesRemover::remove( const automaton::ExtendedNFA < SymbolType, StateType > & fsm ) { // 1. ext::set<StateType> Qu = automaton::properties::efficient::UsefulStates::usefulStates( fsm ); // 2. - automaton::DFA < SymbolType, StateType > M ( fsm.getInitialState () ); + automaton::ExtendedNFA < SymbolType, StateType > M ( fsm.getInitialState () ); for( const auto & a : fsm.getInputAlphabet( ) ) M.addInputSymbol( a ); @@ -150,8 +120,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 ); @@ -183,9 +154,8 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UselessStatesRemover:: } for( const auto & t : fsm.getTransitions( ) ) - for( const auto & to : t.second ) - if( Qu.count(to) ) - M.addTransition( t.first.first, t.first.second, to ); + if( Qu.count(t.second) ) + M.addTransition( t.first.first, t.first.second, t.second ); for( const auto & q : fsm.getFinalStates( ) ) M.addFinalState( q ); diff --git a/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h b/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h index c20df2e09bed978735e1d60d4423472226896283..0dfc89c3b44d5c6fea42a5058d7dc5028680cf09 100644 --- a/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h +++ b/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h @@ -142,17 +142,17 @@ void stringApi < automaton::MultiInitialStateNFA < SymbolType, StateType > >::co template < class SymbolType, class StateType > void stringApi < automaton::MultiInitialStateNFA < SymbolType, StateType > >::composeTransitionsFromState(std::ostream& output, const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton, const StateType & from) { - ext::map<ext::pair<StateType, SymbolType>, ext::set<StateType> > symbolTransitionsFromState = automaton.getTransitionsFromState(from); + ext::multimap<ext::pair<StateType, SymbolType>, StateType > symbolTransitionsFromState = automaton.getTransitionsFromState(from); for(const SymbolType& inputSymbol : automaton.getInputAlphabet()) { - const typename ext::map<ext::pair<StateType, SymbolType>, ext::set<StateType> >::iterator toStates = symbolTransitionsFromState.find(ext::make_pair(from, inputSymbol)); - if(toStates == symbolTransitionsFromState.end() || toStates->second.size() == 0) { + const auto toStates = symbolTransitionsFromState.equal_range(ext::make_pair(from, inputSymbol)); + if ( toStates.empty ( ) ) { output << " -"; } else { bool sign = false; - for(const StateType& to : toStates->second) { + for(const auto & transition : toStates ) { output << (sign ? "|" : " "); - core::stringApi<StateType>::compose(output, to); + core::stringApi<StateType>::compose(output, transition.second); sign = true; } }