From 19387c37450e9fc42b8cc86e9e737b0de14a5bd2 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 17 Sep 2019 08:47:33 +0200 Subject: [PATCH] remove duplicate code in single initial state algo --- .../automaton/simplify/SingleInitialState.h | 138 +++++------------- 1 file changed, 40 insertions(+), 98 deletions(-) diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h index 8c2f55b8ff..dc1516a74d 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -49,133 +49,75 @@ namespace simplify { * @sa automaton::simplify::SingleInitialStateEpsilonTransition */ class SingleInitialState { + template < class T > + struct NFATra { + using type = automaton::NFA < typename T::SymbolType, typename T::StateType >; + }; + + template < class T > + struct EpsilonNFATra { + using type = automaton::EpsilonNFA < typename T::SymbolType, typename T::StateType >; + }; + + template < class T > + using ConvertedAutomaton = typename ext::casional < + ext::boolean < isMultiInitialStateNFA < T > >, NFATra < T >, + ext::boolean < isMultiInitialStateEpsilonNFA < T > >, EpsilonNFATra < T > + >::type::type; + public: /** * Converts multi-initial state automaton to a single-initial state automaton. - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. + * + * @tparam T type of the converted automaton. + * * @param automaton automaton to convert + * * @return an automaton equivalent to @p with only one initial state */ - template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, StateType > convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static automaton::EpsilonNFA < SymbolType, StateType > convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static automaton::DFA < SymbolType, StateType > convert(const automaton::DFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, StateType > convert(const automaton::NFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static automaton::EpsilonNFA < SymbolType, StateType > convert(const automaton::EpsilonNFA < SymbolType, StateType > & automaton); + template < class T > + static ext::require < isMultiInitialStateNFA < T > || isMultiInitialStateEpsilonNFA < T >, SingleInitialState::ConvertedAutomaton < T > > convert ( const T & fsm ); /** * @overload */ - template < class SymbolType, class StateType > - static automaton::ExtendedNFA < SymbolType, StateType > convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static automaton::CompactNFA < SymbolType, StateType > convert(const automaton::CompactNFA < SymbolType, StateType > & automaton); + template < class T > + static ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isExtendedNFA < T > || isCompactNFA < T >, T > convert ( const T & fsm ); }; -template < class SymbolType, class StateType > -automaton::NFA < SymbolType, StateType > SingleInitialState::convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton) { - // step 1, 3 - StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); - - automaton::NFA < SymbolType, StateType > res ( q0 ); - res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); - - for( const StateType & q : automaton.getStates ( ) ) - res.addState( q ); - - // step 2 - for ( const auto & q : automaton.getInitialStates ( ) ) - for(const auto & kv : automaton.getTransitionsFromState ( q ) ) - res.addTransition ( q0, kv.first.second, kv.second ); - - for ( const auto & t : automaton.getTransitions ( ) ) - res.addTransition ( t.first.first, t.first.second, t.second ); - - res.setFinalStates ( automaton.getFinalStates ( ) ); - - // step 4, 5 - if ( ! ext::excludes ( automaton.getFinalStates ( ).begin ( ), automaton.getFinalStates ( ).end ( ), automaton.getInitialStates ( ).begin ( ), automaton.getInitialStates ( ).end ( ) ) ) - res.addFinalState ( q0 ); - - return res; -} +template < class T > +ext::require < isMultiInitialStateNFA < T > || isMultiInitialStateEpsilonNFA < T >, SingleInitialState::ConvertedAutomaton < T > > SingleInitialState::convert ( const T & fsm ) { + using StateType = typename T::StateType; -template < class SymbolType, class StateType > -automaton::EpsilonNFA < SymbolType, StateType > SingleInitialState::convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, StateType > & automaton) { // step 1, 3 - StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); + StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), fsm.getStates ( ) ); - automaton::EpsilonNFA < SymbolType, StateType > res ( q0 ); - res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); + SingleInitialState::ConvertedAutomaton < T > res ( q0 ); + res.setInputAlphabet ( fsm.getInputAlphabet ( ) ); - for( const StateType & q : automaton.getStates ( ) ) - res.addState( q ); + for( const StateType & q : fsm.getStates ( ) ) + res.addState ( q ); // step 2 - for ( const auto & q : automaton.getInitialStates ( ) ) - for(const auto & kv : automaton.getTransitionsFromState ( q ) ) + for ( const auto & q : fsm.getInitialStates ( ) ) + for(const auto & kv : fsm.getTransitionsFromState ( q ) ) res.addTransition ( q0, kv.first.second, kv.second ); - for ( const auto & t : automaton.getTransitions ( ) ) + for ( const auto & t : fsm.getTransitions ( ) ) res.addTransition ( t.first.first, t.first.second, t.second ); - res.setFinalStates ( automaton.getFinalStates ( ) ); + res.setFinalStates ( fsm.getFinalStates ( ) ); // step 4, 5 - if ( ! ext::excludes ( automaton.getFinalStates ( ).begin ( ), automaton.getFinalStates ( ).end ( ), automaton.getInitialStates ( ).begin ( ), automaton.getInitialStates ( ).end ( ) ) ) + if ( ! ext::excludes ( fsm.getFinalStates ( ).begin ( ), fsm.getFinalStates ( ).end ( ), fsm.getInitialStates ( ).begin ( ), fsm.getInitialStates ( ).end ( ) ) ) res.addFinalState ( q0 ); return res; } -template < class SymbolType, class StateType > -automaton::DFA < SymbolType, StateType > SingleInitialState::convert(const automaton::DFA < SymbolType, StateType > & automaton) { - return automaton; -} - -template < class SymbolType, class StateType > -automaton::EpsilonNFA < SymbolType, StateType > SingleInitialState::convert(const automaton::EpsilonNFA < SymbolType, StateType > & automaton) { - return automaton; -} - -template < class SymbolType, class StateType > -automaton::NFA < SymbolType, StateType > SingleInitialState::convert(const automaton::NFA < SymbolType, StateType > & automaton) { - return automaton; -} - -template < class SymbolType, class StateType > -automaton::CompactNFA < SymbolType, StateType > SingleInitialState::convert(const automaton::CompactNFA < SymbolType, StateType > & automaton) { - return automaton; -} - -template < class SymbolType, class StateType > -automaton::ExtendedNFA < SymbolType, StateType > SingleInitialState::convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton) { - return automaton; +template < class T > +ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isExtendedNFA < T > || isCompactNFA < T >, T > SingleInitialState::convert ( const T & fsm ) { + return fsm; } } /* namespace simplify */ -- GitLab