From a3140204b29f1966dd333ace15a85bb3b3824b81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Tr=C3=A1vn=C3=AD=C4=8Dek?= <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 21 Jul 2021 20:22:03 +0200
Subject: [PATCH] algo: avoid unnecessary set constructions/copies

---
 .../simplify/UnreachableStatesRemover.h       |  4 +--
 .../src/equations/RegularEquationSolver.h     |  3 +-
 .../simplify/UnreachableSymbolsRemover.h      | 29 +++++++++----------
 .../efficient/UnreachableStatesRemover.h      | 10 +++----
 4 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
index 6961387e11..d4bd6ff39d 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
@@ -123,7 +123,7 @@ T UnreachableStatesRemover::remove ( const T & fsm ) {
 
 	ext::set<StateType> finalStates;
 	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) );
-	M.setFinalStates( finalStates );
+	M.setFinalStates ( std::move ( finalStates ) );
 
 	return M;
 }
@@ -146,7 +146,7 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov
 
 	ext::set<StateType> finalStates;
 	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) );
-	M.setFinalStates( finalStates );
+	M.setFinalStates( std::move ( finalStates ) );
 
 	return M;
 }
diff --git a/alib2algo/src/equations/RegularEquationSolver.h b/alib2algo/src/equations/RegularEquationSolver.h
index dc35dec92a..182ee14b70 100644
--- a/alib2algo/src/equations/RegularEquationSolver.h
+++ b/alib2algo/src/equations/RegularEquationSolver.h
@@ -109,8 +109,7 @@ void RegularEquationSolver < TerminalSymbolType, VariableSymbolType >::setVariab
 	ext::set < VariableSymbolType > removed;
 	ext::set < VariableSymbolType > added;
 
-	std::set_difference ( nonterminalSymbols.begin ( ), nonterminalSymbols.end ( ), newSymbols.begin ( ), newSymbols.end ( ), std::inserter ( removed, removed.end ( ) ) );
-	std::set_difference ( newSymbols.begin ( ), newSymbols.end ( ), nonterminalSymbols.begin ( ), nonterminalSymbols.end ( ), std::inserter ( added, added.end ( ) ) );
+	ext::set_symmetric_difference ( nonterminalSymbols.begin ( ), nonterminalSymbols.end ( ), newSymbols.begin ( ), newSymbols.end ( ), std::inserter ( removed, removed.end ( ) ), std::inserter ( added, added.end ( ) ) );
 
 	for ( const VariableSymbolType & symbol : removed ) {
 		removeVariableSymbol ( symbol );
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
index e55ecfff58..93a1aa9706 100644
--- a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
@@ -54,29 +54,26 @@ T UnreachableSymbolsRemover::remove( const T & grammar) {
 
 	T ret ( grammar.getInitialSymbol ( ) );
 
-	ext::set < ext::variant < TerminalSymbolType, NonterminalSymbolType > > newNonTerminals;
-	ext::set < ext::variant < TerminalSymbolType, NonterminalSymbolType > > newTerminals;
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), ext::callback_iterator ( [ & ] ( const auto & symbol ) {
+		ret.addNonterminalSymbol ( symbol.template get < NonterminalSymbolType > ( ) );
+	} ) );
 
-	set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) );
-	for( const auto & symbol : newNonTerminals )
-		ret.addNonterminalSymbol( symbol.template get < NonterminalSymbolType > ( ) );
-
-	set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) );
-	for( const auto & symbol : newTerminals )
-		ret.addTerminalSymbol( symbol.template get < TerminalSymbolType > ( ) );
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), ext::callback_iterator ( [ & ] ( const auto & symbol ) {
+		ret.addTerminalSymbol ( symbol.template get < TerminalSymbolType > ( ) );
+	} ) );
 
 	auto rawRules = grammar::RawRules::getRawRules ( grammar );
 
-	auto testCallback = [ & ] ( const ext::variant < TerminalSymbolType, NonterminalSymbolType > & symb ) -> bool {
-		return Vt.count( symb );
+	auto testCallback = [ & ] ( const ext::variant < TerminalSymbolType, NonterminalSymbolType > & symb ) {
+		return Vt.contains ( symb );
 	};
 
 	// A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P
-	for( const auto & rule : rawRules ) {
-		if( newNonTerminals.count( rule.first ) ) {
-			for( const auto& rhs : rule.second ) {
-				if( all_of( rhs.begin( ), rhs.end( ), testCallback ) )
-				grammar::AddRawRule::addRawRule ( ret, rule.first, rhs );
+	for ( const auto & rule : rawRules ) {
+		if ( ret.getNonterminalAlphabet ( ).contains ( rule.first ) ) {
+			for ( const auto& rhs : rule.second ) {
+				if ( all_of ( rhs.begin ( ), rhs.end ( ), testCallback ) )
+					grammar::AddRawRule::addRawRule ( ret, rule.first, rhs );
 			}
 		}
 	}
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
index 8a50b0bb7c..95deaf8bec 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
@@ -50,10 +50,9 @@ T UnreachableStatesRemover::remove ( const T & fsm ) {
 		if( Qa.count( transition.first.first ) )
 			M.addTransition( transition.first.first, transition.first.second, transition.second );
 
-	ext::set<StateType> intersect;
-	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
+	std::set_intersection ( fsm.getFinalStates ( ).begin ( ), fsm.getFinalStates ( ).end ( ), Qa.begin ( ), Qa.end ( ), ext::callback_iterator ( [ & ] ( const StateType & state ) {
 		M.addFinalState( state );
+	} ) );
 
 	return M;
 }
@@ -78,10 +77,9 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov
 		if( Qa.count( transition.first.first ) )
 			M.addTransition( transition.first.first, transition.first.second, transition.second );
 
-	ext::set<StateType> intersect;
-	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
+	std::set_intersection ( fsm.getFinalStates ( ).begin ( ), fsm.getFinalStates ( ).end ( ), Qa.begin ( ), Qa.end ( ), ext::callback_iterator ( [ & ] ( const StateType & state ) {
 		M.addFinalState( state );
+	} ) );
 
 	return M;
 }
-- 
GitLab