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