From 7e3f919b6bda816ea576d0e651c6c93e0a132d74 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 1 Mar 2019 11:39:40 +0100
Subject: [PATCH] template FTA to PostfixPDA

---
 .../convert/ToPostfixPushdownAutomaton.cpp    | 89 +------------------
 .../convert/ToPostfixPushdownAutomaton.h      | 75 +++++++++++++++-
 .../automaton/convert/FTAtoPDATest.cpp        |  4 +-
 3 files changed, 77 insertions(+), 91 deletions(-)

diff --git a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp
index 9bae87f9e6..1737c77998 100644
--- a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp
+++ b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp
@@ -6,104 +6,19 @@
  */
 
 #include "ToPostfixPushdownAutomaton.h"
-
-#include <exception/CommonException.h>
-
-#include <alphabet/BottomOfTheStackSymbol.h>
-#include <alphabet/EndSymbol.h>
-#include <label/InitialStateLabel.h>
-#include <label/FinalStateLabel.h>
-
-#include <automaton/TA/DFTA.h>
-#include <automaton/TA/NFTA.h>
-#include <automaton/PDA/DPDA.h>
-#include <automaton/PDA/NPDA.h>
-
 #include <registration/AlgoRegistration.hpp>
 
 namespace automaton {
 
 namespace convert {
 
-automaton::DPDA < > ToPostfixPushdownAutomaton::convert ( const automaton::DFTA < > & dfta ) {
-	automaton::DPDA < > automaton(label::InitialStateLabel::instance < DefaultStateType > ( ), alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ));
-
-	for (const auto & rankedSymbol : dfta.getInputAlphabet()) {
-		automaton.addInputSymbol ( DefaultSymbolType ( rankedSymbol ) );
-	}
-	automaton.addInputSymbol(alphabet::EndSymbol::instance < DefaultSymbolType > ( ));
-
-	for (const auto & state : dfta.getStates()) {
-		automaton.addPushdownStoreSymbol(state);
-	}
-
-	for (const auto & transition : dfta.getTransitions()) {
-		ext::vector<DefaultSymbolType> pop;
-		pop.reserve(transition.first.second.size());
-		for (const auto & state : transition.first.second) {
-			pop.push_back(state);
-		}
-		ext::vector<DefaultSymbolType> push (1, transition.second);
-		automaton.addTransition(automaton.getInitialState(), DefaultSymbolType ( common::ranked_symbol < > ( transition.first.first ) ), pop, automaton.getInitialState(), push);
-	}
-
-	auto finalPDAState = label::FinalStateLabel::instance < DefaultStateType > ( );
-	automaton.addState(finalPDAState);
-	automaton.addFinalState(finalPDAState);
-
-	for (const auto & finalState : dfta.getFinalStates()) {
-		ext::vector<DefaultSymbolType> pop = {alphabet::BottomOfTheStackSymbol::instance<DefaultSymbolType>(), finalState};
-		ext::vector<DefaultSymbolType> push;
-		automaton.addTransition(automaton.getInitialState(), alphabet::EndSymbol::instance<DefaultSymbolType>(), pop, finalPDAState, push);
-	}
-
-	return automaton;
-}
-
-automaton::NPDA < > ToPostfixPushdownAutomaton::convert ( const automaton::NFTA < > & nfta ) {
-	automaton::NPDA < > automaton(label::InitialStateLabel::instance < DefaultStateType > ( ), alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ));
-
-	for (const auto & rankedSymbol : nfta.getInputAlphabet()) {
-		automaton.addInputSymbol ( DefaultSymbolType ( rankedSymbol ) );
-	}
-	automaton.addInputSymbol(alphabet::EndSymbol::instance < DefaultSymbolType > ( ));
-
-	for (const auto & state : nfta.getStates()) {
-		automaton.addPushdownStoreSymbol(state);
-	}
-
-	for (const auto & transition : nfta.getTransitions()) {
-		for (const auto & toState : transition.second) {
-			ext::vector <DefaultSymbolType> pop;
-			pop.reserve(transition.first.second.size());
-			for (const auto & state : transition.first.second) {
-				pop.push_back(state);
-			}
-			ext::vector <DefaultSymbolType> push(1, toState);
-			automaton.addTransition(automaton.getInitialState(), DefaultSymbolType ( common::ranked_symbol < > ( transition.first.first ) ), pop, automaton.getInitialState(), push);
-		}
-	}
-
-	auto finalPDAState = label::FinalStateLabel::instance < DefaultStateType > ( );
-	automaton.addState(finalPDAState);
-	automaton.addFinalState(finalPDAState);
-
-	for (const auto & finalState : nfta.getFinalStates()) {
-		ext::vector<DefaultSymbolType> pop = {alphabet::BottomOfTheStackSymbol::instance<DefaultSymbolType>(), finalState};
-		ext::vector<DefaultSymbolType> push;
-		automaton.addTransition(automaton.getInitialState(), alphabet::EndSymbol::instance<DefaultSymbolType>(), pop, finalPDAState, push);
-	}
-
-	return automaton;
-}
-
-auto ToAutomatonDFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::DPDA < >, const automaton::DFTA < > & > ( ToPostfixPushdownAutomaton::convert, "dfta" ).setDocumentation (
+auto ToAutomatonDFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::DPDA < ext::variant < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < DefaultStateType, alphabet::BottomOfTheStackSymbol >, char >, const automaton::DFTA < > & > ( ToPostfixPushdownAutomaton::convert, "dfta" ).setDocumentation (
 "Performs the conversion of the deterministic FTA to the deterministic PDA\n\
 \n\
 @param dfta Deterministic finite tree automaton to convert\n\
 @return (D)PDA equivalent to original finite tree automaton reading linearized postfix tree" );
 
-auto ToAutomatonNFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::NPDA < >, const automaton::NFTA < > & > ( ToPostfixPushdownAutomaton::convert, "nfta" ).setDocumentation (
+auto ToAutomatonNFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::NPDA < ext::variant < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < DefaultStateType, alphabet::BottomOfTheStackSymbol >, char >, const automaton::NFTA < > & > ( ToPostfixPushdownAutomaton::convert, "nfta" ).setDocumentation (
 "Performs the conversion of the deterministic FTA to the deterministic PDA\n\
 \n\
 @param nfta Nondeterministic finite tree automaton to convert\n\
diff --git a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h
index 507e5b00f7..9b4b9e73af 100644
--- a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h
+++ b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h
@@ -29,6 +29,9 @@
 #include <automaton/PDA/NPDA.h>
 #include <automaton/PDA/DPDA.h>
 
+#include <alphabet/BottomOfTheStackSymbol.h>
+#include <alphabet/EndSymbol.h>
+
 namespace automaton {
 
 namespace convert {
@@ -43,16 +46,84 @@ public:
 	 * @param dfta Deterministic finite tree automaton to convert
 	 * @return (D)PDA equivalent to original finite tree automaton reading linearized postfix tree
 	 */
-	static automaton::DPDA < > convert ( const automaton::DFTA < > & dfta );
+	template < class SymbolType, class RankType, class StateType >
+	static automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > convert ( const automaton::DFTA < SymbolType, RankType, StateType > & dfta );
 
 	/**
 	 * Performs the conversion of the nondeterministic FTA to the nondeterministic PDA.
 	 * @param nfta Nondeterministic finite tree automaton to convert
 	 * @return (N)PDA equivalent to original finite tree automaton reading linearized postfix tree
 	 */
-	static automaton::NPDA < > convert ( const automaton::NFTA < > & nfta );
+	template < class SymbolType, class RankType, class StateType >
+	static automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > convert ( const automaton::NFTA < SymbolType, RankType, StateType > & nfta );
 };
 
+template < class SymbolType, class RankType, class StateType >
+automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > ToPostfixPushdownAutomaton::convert ( const automaton::DFTA < SymbolType, RankType, StateType > & dfta ) {
+	automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > automaton ( 'q', alphabet::BottomOfTheStackSymbol ( ) );
+
+	for ( const auto & rankedSymbol : dfta.getInputAlphabet ( ) ) {
+		automaton.addInputSymbol ( rankedSymbol );
+	}
+	automaton.addInputSymbol ( alphabet::EndSymbol ( ) );
+
+	for ( const StateType & state : dfta.getStates ( ) ) {
+		automaton.addPushdownStoreSymbol ( state );
+	}
+
+	for (const auto & transition : dfta.getTransitions()) {
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop ( transition.first.second.begin ( ), transition.first.second.end ( ) );
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push ( 1, transition.second );
+		automaton.addTransition ( automaton.getInitialState ( ), transition.first.first, pop, automaton.getInitialState ( ), push );
+	}
+
+	auto finalPDAState = 'r';
+	automaton.addState ( finalPDAState );
+	automaton.addFinalState ( finalPDAState );
+
+	for ( const auto & finalState : dfta.getFinalStates ( ) ) {
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop = { finalState, alphabet::BottomOfTheStackSymbol ( ) };
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push;
+		automaton.addTransition ( automaton.getInitialState ( ), alphabet::EndSymbol ( ), pop, finalPDAState, push );
+	}
+
+	return automaton;
+}
+
+template < class SymbolType, class RankType, class StateType >
+automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > ToPostfixPushdownAutomaton::convert ( const automaton::NFTA < SymbolType, RankType, StateType > & nfta ) {
+	automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > automaton ( 'q', alphabet::BottomOfTheStackSymbol ( ) );
+
+	for ( const auto & symbol : nfta.getInputAlphabet ( ) ) {
+		automaton.addInputSymbol ( symbol );
+	}
+	automaton.addInputSymbol ( alphabet::EndSymbol ( ) );
+
+	for ( const StateType & state : nfta.getStates ( ) ) {
+		automaton.addPushdownStoreSymbol ( state );
+	}
+
+	for ( const auto & transition : nfta.getTransitions ( ) ) {
+		for ( const StateType & toState : transition.second ) {
+			ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop ( transition.first.second.begin ( ), transition.first.second.end ( ) );
+			ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push ( 1, toState );
+			automaton.addTransition (automaton.getInitialState ( ), transition.first.first, pop, automaton.getInitialState ( ), push );
+		}
+	}
+
+	char finalPDAState = 'r';
+	automaton.addState ( finalPDAState );
+	automaton.addFinalState ( finalPDAState );
+
+	for ( const StateType & finalState : nfta.getFinalStates ( ) ) {
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop = { finalState, alphabet::BottomOfTheStackSymbol ( ) };
+		ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push;
+		automaton.addTransition ( automaton.getInitialState ( ), alphabet::EndSymbol ( ), pop, finalPDAState, push );
+	}
+
+	return automaton;
+}
+
 } /* namespace convert */
 
 } /* namespace automaton */
diff --git a/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp b/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp
index 5e8ca0332f..f71056d9df 100644
--- a/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp
+++ b/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp
@@ -41,7 +41,7 @@ TEST_CASE ( "FTAtoPDA", "[unit][algo][automaton][convert]" ) {
 
 		automaton.addFinalState(DefaultStateType(3));
 
-		automaton::DPDA < > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton);
+		automaton::DPDA < ext::variant < common::ranked_symbol < object::Object, unsigned int >, alphabet::EndSymbol >, string::Epsilon < >, ext::variant < object::Object, alphabet::BottomOfTheStackSymbol >, char > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton);
 		CHECK(res.getStates().size() == 2);
 		CHECK(res.getTransitions().size() == 5);
 		CHECK(res.getFinalStates().size() == 1);
@@ -72,7 +72,7 @@ TEST_CASE ( "FTAtoPDA", "[unit][algo][automaton][convert]" ) {
 
 		automaton.addFinalState(DefaultStateType(3));
 
-		automaton::NPDA < > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton);
+		automaton::NPDA < ext::variant < common::ranked_symbol < object::Object, unsigned int >, alphabet::EndSymbol >, string::Epsilon < >, ext::variant < object::Object, alphabet::BottomOfTheStackSymbol >, char > res = automaton::convert::ToPostfixPushdownAutomaton::convert ( automaton );
 
 		CHECK(res.getStates().size() == 2);
 		CHECK(res.getTransitions().size() == 5);
-- 
GitLab