From e5cb2839353401fb6227120b0e0396027e959b8d Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 21 Sep 2014 11:17:07 +0200
Subject: [PATCH] Partial fix DeterminizeVPA

---
 .../src/determinize/vpa/VPADeterminizer.cpp   | 21 ++++-----
 .../test-src/determinize/determinizeTest.cpp  | 46 +++++++++++++++++++
 .../test-src/determinize/determinizeTest.h    |  2 +
 3 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp b/alib2algo/src/determinize/vpa/VPADeterminizer.cpp
index a676e490c9..d820e5197d 100644
--- a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp
+++ b/alib2algo/src/determinize/vpa/VPADeterminizer.cpp
@@ -6,6 +6,7 @@
 #include "label/Label.h"
 #include "label/LabelSetLabel.h"
 #include "label/LabelPairLabel.h"
+#include <std/set.hpp>
 
 namespace determinize {
 
@@ -291,7 +292,7 @@ automaton::VisiblyPushdownNPDA VPADeterminizer::determinize(const automaton::Vis
 		std::pair<label::Label, alphabet::Symbol>* stateSymbol = existsDirtyStateSymbol(d);
 		const automaton::State* state = existsDirtyState(d);
 		if(stateSymbol != NULL) {
-			for(alphabet::Symbol symbol : n.getReturnInputAlphabet()) {
+			for(const alphabet::Symbol& symbol : n.getReturnInputAlphabet()) {
 				if(stateSymbol->second == d.getBottomOfTheStackSymbol()) {
 					retInitial(stateSymbol->first, stateSymbol->second, symbol, n, d);
 				} else {
@@ -300,26 +301,22 @@ automaton::VisiblyPushdownNPDA VPADeterminizer::determinize(const automaton::Vis
 			}
 			delete stateSymbol; //TODO remove this...
 		} else if(state != NULL) {
-			for(alphabet::Symbol symbol : n.getLocalInputAlphabet()) {
+			for(const alphabet::Symbol& symbol : n.getLocalInputAlphabet()) {
 				local(*state, symbol, n, d);
 			}
-			for(alphabet::Symbol symbol : n.getCallInputAlphabet()) {
+			for(const alphabet::Symbol symbol : n.getCallInputAlphabet()) {
 				call(*state, symbol, n, d);
 			}
 		} else {
 			break;
 		}
 	}
-	
-	std::set<label::Label> fin = retrieveLabels(n.getFinalStates());
-	
-	for(automaton::State state : d.getStates()) {
-		std::set<label::Label> labels = retrieveDSubSet(VPADeterminizer::unpackFromDVPAStateLabel(state.getName()));
-		std::set<label::Label> finalLabels(fin);
 
-		finalLabels.erase(labels.begin(), labels.end());
-		
-		if(!finalLabels.empty()) {
+	std::set<label::Label> finalLabels = retrieveLabels(n.getFinalStates());
+	for(const automaton::State& state : d.getStates()) {
+		const std::set<label::Label> labels = retrieveDSubSet(VPADeterminizer::unpackFromDVPAStateLabel(state.getName()));
+
+		if(!std::empty_intersection(finalLabels, labels)) {
 			d.addFinalState(state);
 		}
 	}
diff --git a/alib2algo/test-src/determinize/determinizeTest.cpp b/alib2algo/test-src/determinize/determinizeTest.cpp
index 6f7187a560..e19b33138d 100644
--- a/alib2algo/test-src/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/determinize/determinizeTest.cpp
@@ -67,3 +67,49 @@ void determinizeTest::testDeterminizeIDPDA() {
 
   CPPUNIT_ASSERT(determinized.getStates().size() == 3);
 }
+
+void determinizeTest::testDeterminizeVPA() {
+  automaton::VisiblyPushdownNPDA automaton(alphabet::Symbol(alphabet::BottomOfTheStackSymbol {}));
+
+  automaton.addCallInputSymbol(alphabet::symbolFrom('a'));
+  automaton.addReturnInputSymbol(alphabet::symbolFrom('^'));
+
+  automaton.addStackSymbol(alphabet::symbolFrom('A'));
+  automaton.addStackSymbol(alphabet::symbolFrom('B'));
+  automaton.addStackSymbol(alphabet::symbolFrom('C'));
+  automaton.addStackSymbol(alphabet::symbolFrom('D'));
+  automaton.addStackSymbol(alphabet::symbolFrom('E'));
+  automaton.addStackSymbol(alphabet::symbolFrom('F'));
+  automaton.addStackSymbol(alphabet::symbolFrom('T'));
+
+  automaton.addState(automaton::State(0));
+  automaton.addState(automaton::State(1));
+  automaton.addState(automaton::State(2));
+  automaton.addState(automaton::State(3));
+  automaton.addState(automaton::State(4));
+  automaton.addState(automaton::State(5));
+  automaton.addState(automaton::State(6));
+
+
+  automaton.addTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(0), alphabet::symbolFrom('A'));
+  automaton.addTransition(automaton::State(0), alphabet::symbolFrom('^'), alphabet::symbolFrom('A'), automaton::State(0));
+
+  automaton.addTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(1), alphabet::symbolFrom('B'));
+
+  automaton.addTransition(automaton::State(1), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('C'));
+  automaton.addTransition(automaton::State(2), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('D'));
+  automaton.addTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('D'), automaton::State(2));
+  automaton.addTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('C'), automaton::State(3));
+
+  automaton.addTransition(automaton::State(3), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('E'));
+  automaton.addTransition(automaton::State(4), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('F'));
+  automaton.addTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('F'), automaton::State(4));
+  automaton.addTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('E'), automaton::State(5));
+
+  automaton.addTransition(automaton::State(5), alphabet::symbolFrom('^'), alphabet::symbolFrom('B'), automaton::State(6));
+
+  automaton.addInitialState(automaton::State(0));
+  automaton.addFinalState(automaton::State(4));
+
+  alib::DataFactory::toStdout(automaton);
+}
diff --git a/alib2algo/test-src/determinize/determinizeTest.h b/alib2algo/test-src/determinize/determinizeTest.h
index 0d2d93e80b..1269f9ad95 100644
--- a/alib2algo/test-src/determinize/determinizeTest.h
+++ b/alib2algo/test-src/determinize/determinizeTest.h
@@ -8,6 +8,7 @@ class determinizeTest : public CppUnit::TestFixture
   CPPUNIT_TEST_SUITE( determinizeTest );
   CPPUNIT_TEST( testDeterminizeNFA );
   CPPUNIT_TEST( testDeterminizeIDPDA );
+  CPPUNIT_TEST( testDeterminizeVPA );
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -16,6 +17,7 @@ public:
 
   void testDeterminizeNFA();
   void testDeterminizeIDPDA();
+  void testDeterminizeVPA();
 };
 
 #endif  // DETERMINIZE_TEST_H_
-- 
GitLab