From fffba43fef85314986b2814ba126bf632df31ffe Mon Sep 17 00:00:00 2001
From: Tomas Pecka <peckato1@fit.cvut.cz>
Date: Thu, 4 Aug 2016 20:19:17 +0200
Subject: [PATCH] GlushkovRTE: Simplify subMap processing.

---
 .../src/rte/glushkov/GlushkovTraversal.cpp    | 90 ++++++++-----------
 1 file changed, 37 insertions(+), 53 deletions(-)

diff --git a/alib2algo/src/rte/glushkov/GlushkovTraversal.cpp b/alib2algo/src/rte/glushkov/GlushkovTraversal.cpp
index c74ab85e85..884aca2807 100644
--- a/alib2algo/src/rte/glushkov/GlushkovTraversal.cpp
+++ b/alib2algo/src/rte/glushkov/GlushkovTraversal.cpp
@@ -204,76 +204,60 @@ void preprocessSubMap ( const std::set < alphabet::RankedSymbol > & alphabetK, s
 	while ( change ) {
 		change = false;
 
-		for ( auto & kv : subMap ) {
-			std::set < alphabet::RankedSymbol > & value = kv.second;
+		for ( std::pair < const alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > & kv : subMap ) {
+			std::set < alphabet::RankedSymbol > & substSet = kv.second;
 
-			for ( const auto & v : value ) {
-				if ( alphabetK.find ( v ) == alphabetK.end ( ) ) continue;
+			for ( const auto & e : substSet ) {
+				if ( alphabetK.count ( e ) == 0 ) continue;
 
-				// std::cerr << "Gonna replace in submap: " << kv.first << ": " << v->getSymbol() << std::endl;
-
-				auto it = subMap.find ( v );
-				size_t vsize = value.size ( );
-				value.insert ( it->second.begin ( ), it->second.end ( ) );
-				change = ( vsize != value.size ( ) );
-				value.erase ( v );
-
-				/*
-				 * for(const auto& x : it->second)
-				 *  std::cerr << "\t" << x->getSymbol() << std::endl;
-				 */
+				auto it = subMap.find ( e );
+				size_t oldSize = substSet.size ( );
+				substSet.insert ( it->second.begin ( ), it->second.end ( ) );
+				change = ( oldSize != substSet.size ( ) ); // something was added
+				substSet.erase ( e );
 			}
 		}
 	}
 }
 
-std::set < std::vector < alphabet::RankedSymbol > > replaceConstants ( const std::set < alphabet::RankedSymbol > & alphabetK, const std::vector < alphabet::RankedSymbol > & f, const std::map < alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > & subMap2 ) {
-	std::set < std::vector < alphabet::RankedSymbol > > ret;
-
-	if ( f.size ( ) == 0 ) return ret;
+template < class T >
+void cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ) {
+	if ( depth == input.size ( ) )
+		ret.push_back ( current );
+	else
+		for ( size_t i = 0; i < input[depth].size ( ); i++ ) {
+			current[depth] = input[depth][i];
+			cartesian_rec ( input, ret, current, depth + 1 );
+		}
 
-	std::map < alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > subMap ( subMap2 );
-	preprocessSubMap ( alphabetK, subMap );
+}
 
-	auto subIt = subMap.find ( f[0] );
+template < class T >
+std::vector < std::vector < T > > cartesian ( const std::vector < std::vector < T > > & input ) {
+	std::vector < std::vector < T > > ret;
+	std::vector < T > current ( input.size ( ), alphabet::RankedSymbol ( 0, 0 ) );
 
-	if ( subIt == subMap.end ( ) ) {
-		std::vector < alphabet::RankedSymbol > v;
-		v.push_back ( f[0] );
-		ret.insert ( v );
-	} else {
-		for ( const auto & subSymbol : subIt->second ) {
-			std::vector < alphabet::RankedSymbol > v;
-			v.push_back ( subSymbol );
-			ret.insert ( v );
-		}
-	}
+	cartesian_rec ( input, ret, current, 0 );
 
-	for ( size_t i = 1; i < f.size ( ); i++ ) {
-		std::set < std::vector < alphabet::RankedSymbol > > tmp;
+	return ret;
+}
 
-		subIt = subMap.find ( f[i] );
+std::set < std::vector < alphabet::RankedSymbol > > replaceConstants ( const std::set < alphabet::RankedSymbol > & alphabetK, const std::vector < alphabet::RankedSymbol > & follow, const std::map < alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > & subMap2 ) {
+	std::map < alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > subMap ( subMap2 );
+	preprocessSubMap ( alphabetK, subMap );
 
-		if ( subIt == subMap.end ( ) )
-			for ( const auto & r : ret ) {
-				std::vector < alphabet::RankedSymbol > v = r;
-				v.push_back ( f[i] );
-				tmp.insert ( v );
-			}
+	std::vector < std::vector < alphabet::RankedSymbol > > input;
 
+	for ( const alphabet::RankedSymbol & e : follow ) {
+		if ( alphabetK.count ( e ) > 0 )
+			input.push_back ( std::vector < alphabet::RankedSymbol > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) );
 		else
-
-			for ( const auto & r : ret )
-				for ( const auto & subSymbol : subIt->second ) {
-					std::vector < alphabet::RankedSymbol > v = r;
-					v.push_back ( subSymbol );
-					tmp.insert ( v );
-				}
-
-		ret = tmp;
+			input.push_back ( std::vector < alphabet::RankedSymbol > { e } );
 	}
 
-	return ret;
+	 /* now do the cartesian product on "input" */
+	std::vector < std::vector < alphabet::RankedSymbol > > followSet = cartesian ( input );
+	return std::set < std::vector < alphabet::RankedSymbol > > ( followSet.begin ( ), followSet.end ( ) );
 }
 
 std::set < std::vector < alphabet::RankedSymbol > > GlushkovTraversal::follow ( const rte::FormalRTESymbolAlphabet & node, const alphabet::RankedSymbol & symbolF, const std::set < alphabet::RankedSymbol > & alphabetK, std::map < alphabet::RankedSymbol, std::set < alphabet::RankedSymbol > > & subMap ) {
-- 
GitLab