From 67814972a8804646c99a78d1ee9869f8f77395ed Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 9 May 2019 00:03:10 +0200 Subject: [PATCH] fix MultiInitialState(Epsilon)NFA --- .../FSM/MultiInitialStateEpsilonNFA.h | 56 ++++++++++++------- .../src/automaton/FSM/MultiInitialStateNFA.h | 19 +------ 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h index 8cc26fcf57..2aa8b6e86a 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateEpsilonNFA.h @@ -182,17 +182,6 @@ public: this->template accessComponent < InitialStates > ( ).remove ( state ); } - /** - * Setter of the initial state. - * - * \param state new initial state of the automaton - * - * \returns true if the initial state was indeed changed - */ - bool setInitialState ( StateType state ) { - return this->template accessComponent < InitialStates > ( ).set ( std::move ( state ) ); - } - /** * Getter of states. * @@ -393,6 +382,21 @@ public: */ bool addTransition ( StateType from, StateType to ); + /** + * \brief Removes a transition to the automaton. + * + * \details The transition is in a form A \times a -> B, where A, B \in Q and a \in T \cup \{\epsilon\} + * + * \param current the source state (A) + * \param input the input symbol or epsilon (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added + */ + bool removeTransition ( StateType from, ext::variant < EpsilonType, SymbolType > input, StateType to ); + /** * \brief Removes a transition from the automaton. * @@ -664,21 +668,30 @@ bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::addTran return addTransition ( std::move ( from ), std::move ( inputVariant ), std::move ( to ) ); } +template<class SymbolType, class EpsilonType, class StateType > +bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::removeTransition ( StateType from, ext::variant < EpsilonType, SymbolType > input, StateType to ) { + 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; + + transitions.erase ( iter ); + return true; +} + template<class SymbolType, class EpsilonType, class StateType > bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::removeTransition ( const StateType & from, const SymbolType & input, const StateType & to ) { - ext::variant < EpsilonType, SymbolType > inputVariant ( input ); - ext::pair < StateType, ext::variant < EpsilonType, SymbolType > > key = ext::make_pair ( from, inputVariant ); + ext::variant < EpsilonType, SymbolType > inputVariant ( std::move ( input ) ); - return transitions[key].erase ( to ); + return addTransition ( std::move ( from ), std::move ( inputVariant ), std::move ( to ) ); } template<class SymbolType, class EpsilonType, class StateType > bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::removeTransition ( const StateType & from, const StateType & to ) { auto inputVariant = ext::variant < EpsilonType, SymbolType >::template from < EpsilonType > ( ); - ext::pair < StateType, ext::variant < EpsilonType, SymbolType > > key = ext::make_pair ( from, inputVariant ); - - return transitions[key].erase ( to ); + return addTransition ( std::move ( from ), std::move ( inputVariant ), std::move ( to ) ); } template<class SymbolType, class EpsilonType, class StateType > @@ -808,11 +821,14 @@ bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::isEpsil template<class SymbolType, class EpsilonType, class StateType > bool MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType >::isDeterministic ( ) const { - for ( const std::pair < const ext::pair < StateType, ext::variant < EpsilonType, SymbolType > >, StateType > & transition : transitions ) - if ( transition.second.size ( ) > 1 ) + if ( transitions.empty ( ) ) + return true; + + for ( auto iter = transitions.begin ( ); std::next ( iter ) != transitions.end ( ); ++ iter ) + if ( iter->first == std::next ( iter )->first ) return false; - return isEpsilonFree ( ); + return isEpsilonFree ( ) && getInitialStates ( ).size ( ) == 1; } template<class SymbolType, class EpsilonType, class StateType > diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h index fe872870bf..c105ccf8d2 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h @@ -399,13 +399,6 @@ public: */ bool isTotal ( ) const; - /** - * \brief Computes number of transitions in the automaton - * - * \return number of transitions in the automaton - */ - unsigned transitionsSize ( ) const; - /** * The actual compare method * @@ -572,17 +565,7 @@ bool MultiInitialStateNFA < SymbolType, StateType >::isDeterministic ( ) const { template < class SymbolType, class StateType > bool MultiInitialStateNFA < SymbolType, StateType >::isTotal ( ) const { - return isDeterministic ( ) && transitionsSize ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( ); -} - -template < class SymbolType, class StateType > -unsigned MultiInitialStateNFA < SymbolType, StateType >::transitionsSize ( ) const { - int res = 0; - - for ( const auto & transition : transitions ) - res += transition.second.size ( ); - - return res; + return isDeterministic ( ) && transitions.size ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( ); } template < class SymbolType, class StateType > -- GitLab