From 73a424c2ceb2d5b90c03044aa8eff1ff091cd26e Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 6 Sep 2018 12:40:54 +0200 Subject: [PATCH] template automaton to regexp --- .../automaton/convert/ToRegExpAlgebraic.cpp | 100 --------------- .../src/automaton/convert/ToRegExpAlgebraic.h | 116 ++++++++++++++++-- 2 files changed, 109 insertions(+), 107 deletions(-) diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp index 512c6e3947..1f636ccf2c 100644 --- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp @@ -6,112 +6,12 @@ */ #include "ToRegExpAlgebraic.h" - -#include <automaton/FSM/DFA.h> -#include <automaton/FSM/NFA.h> -#include <automaton/FSM/MultiInitialStateNFA.h> -#include <automaton/FSM/EpsilonNFA.h> - -#include <equations/RightRegularEquationSolver.h> -#include <regexp/unbounded/UnboundedRegExpElements.h> #include <registration/AlgoRegistration.hpp> namespace automaton { namespace convert { -regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::EpsilonNFA < > & automaton ) { - equations::RightRegularEquationSolver < DefaultSymbolType, DefaultSymbolType > solver; - - // initialize equations - solver.setVariableSymbols ( automaton.getStates ( ) ); - - for( const auto & q : automaton.getStates( ) ) { - if( automaton.getFinalStates( ).count( q ) > 0 ) - solver.addEquation( DefaultSymbolType( q ), regexp::UnboundedRegExpEpsilon < DefaultSymbolType > { } ); - } - - for( const auto & p : automaton.getSymbolTransitions() ) { - for( const auto & q : p.second ) { - solver.addEquation( DefaultSymbolType( p.first.first ), DefaultSymbolType( q ), regexp::UnboundedRegExpSymbol < DefaultSymbolType > { p.first.second } ); - } - } - - for( const auto & p : automaton.getEpsilonTransitions() ) { - for( const auto & q : p.second ) { - solver.addEquation( DefaultSymbolType( p.first ), DefaultSymbolType( q ), regexp::UnboundedRegExpEpsilon < DefaultSymbolType > { } ); - } - } - - return solver.solve( DefaultSymbolType( automaton.getInitialState() ) ); -} - -regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::MultiInitialStateNFA < > & automaton ) { - equations::RightRegularEquationSolver < DefaultSymbolType, DefaultSymbolType > solver; - - // initialize equations - solver.setVariableSymbols ( automaton.getStates ( ) ); - - for( const auto & q : automaton.getStates( ) ) { - if( automaton.getFinalStates( ).count( q ) > 0 ) - solver.addEquation( DefaultSymbolType( q ), regexp::UnboundedRegExpEpsilon < DefaultSymbolType > { } ); - } - - for( const auto & p : automaton.getTransitions() ) { - for( const auto & q : p.second ) { - solver.addEquation( DefaultSymbolType( p.first.first ), DefaultSymbolType( q ), regexp::UnboundedRegExpSymbol < DefaultSymbolType > { p.first.second } ); - } - } - - regexp::UnboundedRegExpAlternation < DefaultSymbolType > alternation; - for(const auto& initialSymbol : automaton.getInitialStates() ) { - // set symbol for which the solver will solve equation system - DefaultSymbolType tmp { initialSymbol }; - - alternation.appendElement( solver.solve( tmp ).getRegExp().getStructure() ); - } - - return regexp::UnboundedRegExp < > { regexp::UnboundedRegExpStructure < DefaultSymbolType > ( alternation ) }; -} - -regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::NFA < > & automaton ) { - equations::RightRegularEquationSolver < DefaultSymbolType, DefaultSymbolType > solver; - - // initialize equations - solver.setVariableSymbols ( automaton.getStates ( ) ); - - for( const auto & q : automaton.getStates( ) ) { - if( automaton.getFinalStates( ).count( q ) > 0 ) - solver.addEquation( DefaultSymbolType( q ), regexp::UnboundedRegExpEpsilon < DefaultSymbolType > { } ); - } - - for( const auto & p : automaton.getTransitions() ) { - for( const auto & q : p.second ) { - solver.addEquation( DefaultSymbolType( p.first.first ), DefaultSymbolType( q ), regexp::UnboundedRegExpSymbol < DefaultSymbolType > { p.first.second } ); - } - } - - return solver.solve( DefaultSymbolType( automaton.getInitialState() ) ); -} - -regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::DFA < > & automaton ) { - equations::RightRegularEquationSolver < DefaultSymbolType, DefaultSymbolType > solver; - - // initialize equations - solver.setVariableSymbols ( automaton.getStates ( ) ); - - for( const auto & q : automaton.getStates( ) ) { - if( automaton.getFinalStates( ).count( q ) > 0 ) - solver.addEquation( DefaultSymbolType( q ), regexp::UnboundedRegExpEpsilon < DefaultSymbolType > { } ); - } - - for( const auto & p : automaton.getTransitions() ) { - solver.addEquation( DefaultSymbolType( p.first.first ), DefaultSymbolType( p.second ), regexp::UnboundedRegExpSymbol < DefaultSymbolType > { p.first.second } ); - } - - return solver.solve( DefaultSymbolType( automaton.getInitialState() ) ); -} - auto ToRegExpAlgebraicEpsilonNFA = registration::AbstractRegister < ToRegExpAlgebraic, regexp::UnboundedRegExp < >, const automaton::EpsilonNFA < > & > ( ToRegExpAlgebraic::convert ); auto ToRegExpAlgebraicMultiInitialStateNFA = registration::AbstractRegister < ToRegExpAlgebraic, regexp::UnboundedRegExp < >, const automaton::MultiInitialStateNFA < > & > ( ToRegExpAlgebraic::convert ); auto ToRegExpAlgebraicNFA = registration::AbstractRegister < ToRegExpAlgebraic, regexp::UnboundedRegExp < >, const automaton::NFA < > & > ( ToRegExpAlgebraic::convert ); diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h index b1d8af0f8c..add4fe116e 100644 --- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h +++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h @@ -25,10 +25,14 @@ #define AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_ #include <regexp/unbounded/UnboundedRegExp.h> -#include <automaton/FSM/EpsilonNFA.h> -#include <automaton/FSM/MultiInitialStateNFA.h> -#include <automaton/FSM/NFA.h> + #include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/MultiInitialStateNFA.h> +#include <automaton/FSM/EpsilonNFA.h> + +#include <equations/RightRegularEquationSolver.h> +#include <regexp/unbounded/UnboundedRegExpElements.h> namespace automaton { @@ -49,24 +53,122 @@ public: * @param automaton The automaton that is to be converted to the regular expression. * @return regular expression equivalent to the input @p automaton. */ - static regexp::UnboundedRegExp < > convert(const automaton::EpsilonNFA < > & automaton); + template < class SymbolType, class EpsilonType, class StateType > + static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton ); /** * \overload */ - static regexp::UnboundedRegExp < > convert(const automaton::MultiInitialStateNFA < > & automaton); + template < class SymbolType, class StateType > + static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton ); /** * \overload */ - static regexp::UnboundedRegExp < > convert(const automaton::NFA < > & automaton); + template < class SymbolType, class StateType > + static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::NFA < SymbolType, StateType > & automaton ); /** * \overload */ - static regexp::UnboundedRegExp < > convert(const automaton::DFA < > & automaton); + template < class SymbolType, class StateType > + static regexp::UnboundedRegExp < SymbolType > convert ( const automaton::DFA < SymbolType, StateType > & automaton ); }; +template < class SymbolType, class EpsilonType, class StateType > +regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton ) { + equations::RightRegularEquationSolver < SymbolType, StateType > solver; + + // initialize equations + solver.setVariableSymbols ( automaton.getStates ( ) ); + + for ( const StateType & q : automaton.getStates ( ) ) { + if ( automaton.getFinalStates ( ).count ( q ) > 0 ) + solver.addEquation ( q, regexp::UnboundedRegExpEpsilon < SymbolType > { } ); + } + + for ( const auto & p : automaton.getSymbolTransitions ( ) ) { + for ( const StateType & q : p.second ) { + solver.addEquation ( p.first.first, q, regexp::UnboundedRegExpSymbol < SymbolType > { p.first.second } ); + } + } + + for( const auto & p : automaton.getEpsilonTransitions ( ) ) { + for ( const StateType & q : p.second ) { + solver.addEquation ( p.first, q, regexp::UnboundedRegExpEpsilon < SymbolType > { } ); + } + } + + return solver.solve ( automaton.getInitialState ( ) ); +} + +template < class SymbolType, class StateType > +regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton ) { + equations::RightRegularEquationSolver < SymbolType, StateType > solver; + + // initialize equations + solver.setVariableSymbols ( automaton.getStates ( ) ); + + for ( const StateType & q : automaton.getStates ( ) ) { + if( automaton.getFinalStates ( ).count ( q ) > 0 ) + 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 } ); + } + } + + regexp::UnboundedRegExpAlternation < SymbolType > alternation; + for ( const StateType & initialSymbol : automaton.getInitialStates ( ) ) { + // set symbol for which the solver will solve equation system + alternation.appendElement ( solver.solve ( initialSymbol ).getRegExp ( ).getStructure ( ) ); + } + + 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, SymbolType > solver; + + // initialize equations + solver.setVariableSymbols ( automaton.getStates ( ) ); + + for ( const StateType & q : automaton.getStates ( ) ) { + if ( automaton.getFinalStates ( ).count ( q ) > 0 ) + 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 } ); + } + } + + return solver.solve ( automaton.getInitialState ( ) ); +} + +template < class SymbolType, class StateType > +regexp::UnboundedRegExp < SymbolType > ToRegExpAlgebraic::convert ( const automaton::DFA < SymbolType, StateType > & automaton ) { + equations::RightRegularEquationSolver < SymbolType, SymbolType > solver; + + // initialize equations + solver.setVariableSymbols ( automaton.getStates ( ) ); + + for ( const StateType & q : automaton.getStates( ) ) { + if ( automaton.getFinalStates ( ).count ( q ) > 0 ) + 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 } ); + } + + return solver.solve ( automaton.getInitialState( ) ); +} + } /* namespace convert */ } /* namespace automaton */ -- GitLab