diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h index 619b3bf2cd4ef71326af565170985a3bae15311a..149ce8b2159262afdcc4acc877413b6835d93dae 100644 --- a/alib2algo/src/automaton/convert/ToGrammarRightRG.h +++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h @@ -28,6 +28,7 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> +#include <automaton/Automaton.h> #include <common/createUnique.hpp> @@ -43,52 +44,21 @@ public: /** * Performs the conversion of the finite automaton to right regular grammar. * - * \tparam SymbolType the type of input/terminal symbols of automaton and the resulting grammar - * \tparam StateType the type of states of the automaton and nonterminal symbols of the resulting grammar + * \tparam T the converted automaton * * \param automaton a finite automaton to convert * * \return right regular grammar equivalent to the source @p automaton. */ - template < class SymbolType, class StateType > - static grammar::RightRG < SymbolType, StateType > convert ( const automaton::NFA < SymbolType, StateType > & automaton ); - - /** - * \overload - */ - template < class SymbolType, class StateType > - static grammar::RightRG < SymbolType, StateType > convert ( const automaton::DFA < SymbolType, StateType > & automaton ); + template < class T > + static ext::require < isDFA < T > || isNFA < T >, grammar::RightRG < typename automaton::SymbolTypeOfAutomaton < T >, typename automaton::StateTypeOfAutomaton < T > > > convert ( const T & automaton ); }; +template < class T > +ext::require < isDFA < T > || isNFA < T >, grammar::RightRG < typename automaton::SymbolTypeOfAutomaton < T >, typename automaton::StateTypeOfAutomaton < T > > > ToGrammarRightRG::convert ( const T & automaton ) { + using SymbolType = automaton::SymbolTypeOfAutomaton < T >; + using StateType = automaton::StateTypeOfAutomaton < T >; -template < class SymbolType, class StateType > -grammar::RightRG < SymbolType, StateType > ToGrammarRightRG::convert ( const automaton::NFA < SymbolType, StateType > & automaton ) { - // step 3 - set start symbol of G - grammar::RightRG < SymbolType, StateType > grammar ( automaton.getInitialState ( ) ); - - grammar.setTerminalAlphabet ( automaton.getInputAlphabet ( ) ); - grammar.setNonterminalAlphabet ( automaton.getStates ( ) ); - - // step 2 - create set of P in G - for(const auto& transition : automaton.getTransitions()) { - const auto & from = transition.first.first; - const auto & input = transition.first.second; - const auto & to = transition.second; - - grammar.addRule ( from, ext::make_pair ( input, to ) ); // 2a - if(automaton.getFinalStates().count(to)) // 2b - grammar.addRule(transition.first.first, transition.first.second ); - } - - // step 4 - if(automaton.getFinalStates().count(automaton.getInitialState())) - grammar.setGeneratesEpsilon(true); // okay this feature makes the algorithm a bit different but at the same time it simplifies the code :)) - - return grammar; -} - -template < class SymbolType, class StateType > -grammar::RightRG < SymbolType, StateType > ToGrammarRightRG::convert ( const automaton::DFA < SymbolType, StateType > & automaton ) { // step 3 - set start symbol of G grammar::RightRG < SymbolType, StateType > grammar ( automaton.getInitialState ( ) ); diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h index bdbed7fa2d5ff4222236c3e3a4747d64a0523452..7bba1a43939ec802bea7b7f0458388a68fd94bf6 100644 --- a/alib2algo/src/automaton/convert/ToRegExp.h +++ b/alib2algo/src/automaton/convert/ToRegExp.h @@ -24,12 +24,7 @@ #ifndef _AUTOMATON_TO_REGEXP_H__ #define _AUTOMATON_TO_REGEXP_H__ -#include <automaton/FSM/DFA.h> -#include <automaton/FSM/NFA.h> -#include <automaton/FSM/EpsilonNFA.h> -#include <automaton/FSM/ExtendedNFA.h> -#include <regexp/unbounded/UnboundedRegExp.h> - +#include <automaton/Automaton.h> #include "ToRegExpStateElimination.h" namespace automaton { @@ -45,74 +40,17 @@ class ToRegExp { public: /** * Performs the conversion (@sa ToRegExpStateElimination::convert). - * @tparam SymbolType Type for symbols. - * @tparam EpsilonType Type for the epsilon symbol. - * @tparam StateType Type for states. + * @tparam T Type of converted automaton. * @param automaton the automaton to convert * @return regular expression equivalent to the input @p automaton */ - template < class SymbolType, class EpsilonType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::NFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::DFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton); - - /** - * @overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < > convert(const automaton::CompactNFA < SymbolType, StateType > & automaton); + template < class T > + static regexp::UnboundedRegExp < typename automaton::SymbolTypeOfAutomaton < T > > convert ( const T & automaton); }; -template < class SymbolType, class EpsilonType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::NFA < SymbolType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::DFA < SymbolType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < > ToRegExp::convert(const automaton::CompactNFA < SymbolType, StateType > & automaton) { - return ToRegExpStateElimination::convert(automaton); +template < class T > +regexp::UnboundedRegExp < typename automaton::SymbolTypeOfAutomaton < T > > ToRegExp::convert ( const T & automaton ) { + return ToRegExpStateElimination::convert ( automaton ); } } /* namespace convert */ diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h index a4d507c6b158b0bec6dc48dd27df729a95ab495d..151b14d975d1c1e5c65c1bd0f76a7738488303e4 100644 --- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h @@ -30,6 +30,7 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/MultiInitialStateNFA.h> #include <automaton/FSM/EpsilonNFA.h> +#include <automaton/Automaton.h> #include <equations/RightRegularEquationSolver.h> #include <regexp/unbounded/UnboundedRegExpElements.h> @@ -65,14 +66,8 @@ public: /** * \overload */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::NFA < SymbolType, StateType > & automaton ); - - /** - * \overload - */ - template < class SymbolType, class StateType > - static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::DFA < SymbolType, StateType > & automaton ); + template < class T > + static ext::require < isDFA < T > || isNFA < T >, regexp::UnboundedRegExp < typename automaton::SymbolTypeOfAutomaton < T > > > convert ( const T & automaton ); }; template < class SymbolType, class EpsilonType, class StateType > @@ -114,24 +109,11 @@ regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automa return regexp::UnboundedRegExp < SymbolType > { regexp::UnboundedRegExpStructure < SymbolType > ( alternation ) }; } -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automaton::NFA < SymbolType, StateType > & automaton ) { - equations::RightRegularEquationSolver < SymbolType, StateType > solver; - - // initialize equations - solver.setVariableSymbols ( automaton.getStates ( ) ); - - for ( const StateType & q : automaton.getFinalStates ( ) ) - solver.addEquation ( q, regexp::UnboundedRegExpEpsilon < SymbolType > { } ); - - for ( const auto & p : automaton.getTransitions ( ) ) - solver.addEquation ( p.first.first, p.second, regexp::UnboundedRegExpSymbol < SymbolType > { p.first.second } ); +template < class T > +ext::require < isDFA < T > || isNFA < T >, regexp::UnboundedRegExp < typename automaton::SymbolTypeOfAutomaton < T > > > ToRegExpAlgebraic::convert ( const T & automaton ) { + using SymbolType = automaton::SymbolTypeOfAutomaton < T >; + using StateType = automaton::StateTypeOfAutomaton < T >; - return solver.solve ( automaton.getInitialState ( ) ); -} - -template < class SymbolType, class StateType > -regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automaton::DFA < SymbolType, StateType > & automaton ) { equations::RightRegularEquationSolver < SymbolType, StateType > solver; // initialize equations @@ -143,7 +125,7 @@ regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automa for ( const auto & p : automaton.getTransitions ( ) ) solver.addEquation ( p.first.first, p.second, regexp::UnboundedRegExpSymbol < SymbolType > { p.first.second } ); - return solver.solve ( automaton.getInitialState( ) ); + return solver.solve ( automaton.getInitialState ( ) ); } } /* namespace convert */ diff --git a/alib2algo/src/automaton/properties/InfiniteLanguage.h b/alib2algo/src/automaton/properties/InfiniteLanguage.h index 21372c4b85e7700f9ad65ac6ec9e16ba2087e4ae..aa5ad86e01c5a21482bc171a97a62158cd04246e 100644 --- a/alib2algo/src/automaton/properties/InfiniteLanguage.h +++ b/alib2algo/src/automaton/properties/InfiniteLanguage.h @@ -29,8 +29,10 @@ #include <automaton/FSM/NFA.h> #include <automaton/FSM/DFA.h> +#include <automaton/Automaton.h> #include <automaton/properties/UsefulStates.h> + namespace automaton { namespace properties { @@ -41,26 +43,22 @@ namespace properties { class InfiniteLanguage { public: /** + * Detects whether the language accepted by the automaton is finite or infinite. + * + * @T the type of tested automaton + * * @param fsm automaton + * * @return boolean indicating infinitness of the language */ - template < class SymbolType, class StateType > - static bool infinite ( const automaton::DFA < SymbolType, StateType > & fsm ); - - /** - * @override - */ - template < class SymbolType, class StateType > - static bool infinite ( const automaton::NFA < SymbolType, StateType > & fsm ); + template < class T > + static ext::require < isDFA < T > || isNFA < T >, bool > infinite ( const T & fsm ); }; -template < class SymbolType, class StateType > -bool InfiniteLanguage::infinite ( const automaton::DFA < SymbolType, StateType > & fsm ) { - return infinite ( automaton::NFA < SymbolType, StateType > ( fsm ) ); -} +template < class T > +ext::require < isDFA < T > || isNFA < T >, bool > InfiniteLanguage::infinite ( const T & fsm ) { + using StateType = automaton::StateTypeOfAutomaton < T >; -template < class SymbolType, class StateType > -bool InfiniteLanguage::infinite ( const automaton::NFA < SymbolType, StateType > & fsm ) { const ext::set < StateType > usefulStates = automaton::properties::UsefulStates::usefulStates ( fsm ); std::queue < StateType > q; diff --git a/alib2algo/src/automaton/properties/ReachableStates.h b/alib2algo/src/automaton/properties/ReachableStates.h index b68c7c5bbf9d4bd3fb12fcc85a796095111fc875..7f0a7f1835baaa94503d89268c9db03f4aa9496a 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.h +++ b/alib2algo/src/automaton/properties/ReachableStates.h @@ -110,7 +110,7 @@ ext::set < typename automaton::StateTypeOfAutomaton < T > > ReachableStates::rea // 1a ext::deque<ext::set<StateType>> Qi; Qi.push_back( ext::set<StateType>( ) ); - Qi.at( 0 ) = {fsm.getInitialState( )}; + Qi.at( 0 ).insert ( fsm.getInitialState( ) ); int i = 1;