From 6929094306c0bde785e9393798af5e7f31761673 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 6 Feb 2018 21:22:14 +0100
Subject: [PATCH] nonrecursive local closure algo

---
 .../determinize/common/RHDPDACommon.h         | 46 +++++++++----------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
index b4c89f124f..d0db39d313 100644
--- a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
+++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
@@ -84,37 +84,38 @@ ext::set<ext::set<ext::pair<StateType,StateType>>> existsDirtyState(const T& d,
 	return dirtyStates;
 }
 
-template<class T, class DeterministicStateType >
-void localClosure(ext::set<DeterministicStateType>& states, const ext::set<DeterministicStateType>& oldStates, const T & d) {
-	ext::set<DeterministicStateType> newStates;
+template < class T, class DeterministicStateType >
+ext::set < DeterministicStateType > localClosure ( const DeterministicStateType & initState, const T & d ) {
+	ext::set < DeterministicStateType > closed { initState };
+	ext::deque < DeterministicStateType > queue { initState };
 
-	for(const DeterministicStateType& state : oldStates) {
-		for(const auto& transition : d.getLocalTransitions()) {
-			if(transition.second != state) continue;
+	while ( ! queue.empty ( ) ) {
+		DeterministicStateType state = std::move ( queue.back ( ) );
+		queue.pop_back ( );
 
-			if(!states.count(transition.first.first)) {
-				states.insert(transition.first.first);
-				newStates.insert(transition.first.first);
-			}
+		for ( const auto & transition : d.getLocalTransitions ( ) ) {
+			if ( transition.second != state )
+				continue;
+
+			if ( closed.insert ( transition.first.first ).second )
+				queue.push_back ( transition.first.first );
 		}
 
-		for(const auto& transition : d.getReturnTransitions()) {
-			if(transition.second != state) continue;
+		for ( const auto & transition : d.getReturnTransitions ( ) ) {
+			if ( transition.second != state )
+				continue;
 
-			const auto& popSymbol = std::get<2>(transition.first);
-			if(popSymbol == d.getBottomOfTheStackSymbol()) continue;
+			const auto & popSymbol = std::get < 2 > ( transition.first );
+			if ( popSymbol == d.getBottomOfTheStackSymbol ( ) )
+				continue;
 
 			const DeterministicStateType & statePart = popSymbol.first;
-
-			if(!states.count(statePart)) {
-				states.insert(statePart);
-				newStates.insert(statePart);
-			}
+			if ( closed.insert ( statePart ).second )
+				queue.push_back ( statePart );
 		}
 	}
 
-	if(newStates.empty()) return;
-	localClosure(states, newStates, d);
+	return closed;
 }
 
 template<class T, class DeterministicStateType, class InputSymbolType, class DeterministicPushdownStoreSymbolType, class R>
@@ -142,8 +143,7 @@ ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>
 		}
 		if(!originalPops) continue;
 
-		ext::set<DeterministicStateType> lc { state };
-		localClosure(lc, ext::set<DeterministicStateType>{state}, d); //intentional copy
+		ext::set < DeterministicStateType > lc = localClosure ( state, d );
 
 		ext::set<DeterministicPushdownStoreSymbolType> topSymbols;
 		for(const DeterministicStateType& localState : lc) {
-- 
GitLab