From cd4456406513ac41ee9e6301ae54f79394d731c0 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 28 Jan 2018 18:29:43 +0100
Subject: [PATCH] partial template tree pattern matching automata construction

---
 .../exact/ExactPatternMatchingAutomaton.cpp   | 69 +-----------------
 .../exact/ExactPatternMatchingAutomaton.h     | 71 ++++++++++++++++++-
 2 files changed, 71 insertions(+), 69 deletions(-)

diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
index 44bc0e0b6a..99fb225cac 100644
--- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
@@ -21,8 +21,6 @@
 #include <automaton/PDA/NPDA.h>
 #include <automaton/TA/NFTA.h>
 
-#include <alphabet/BottomOfTheStackSymbol.h>
-
 #include <alib/deque>
 #include <alphabet/RankedSymbol.h>
 #include <registration/AlgoRegistration.hpp>
@@ -119,72 +117,7 @@ automaton::InputDrivenNPDA < > ExactPatternMatchingAutomaton::construct ( const
 
 auto ExactPatternMatchingAutomatonPrefixRankedBarTree = registration::AbstractRegister < ExactPatternMatchingAutomaton, automaton::InputDrivenNPDA < >, const tree::PrefixRankedBarTree < > & > ( ExactPatternMatchingAutomaton::construct );
 
-automaton::VisiblyPushdownNPDA < > ExactPatternMatchingAutomaton::construct ( const tree::PrefixRankedBarPattern < > & pattern ) {
-	automaton::VisiblyPushdownNPDA < > res ( alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) );
-
-	res.addState ( DefaultStateType ( 0 ) );
-	res.addInitialState ( DefaultStateType ( 0 ) );
-
-	for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
-
-		if ( pattern.getBars ( ).count ( symbol ) )
-			res.addReturnInputSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ) );
-		else
-			res.addCallInputSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ) );
-	}
-
-	res.setPushdownStoreAlphabet ( { alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) , DefaultSymbolType ( 'T' ), DefaultSymbolType ( 'R' ) } );
-
-	for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
-
-		if ( pattern.getBars ( ).count ( symbol ) )
-			res.addReturnTransition ( DefaultStateType ( 0 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultSymbolType ( 'T' ), DefaultStateType ( 0 ) );
-		else
-			res.addCallTransition ( DefaultStateType ( 0 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( 0 ), DefaultSymbolType ( 'T' ) );
-	}
-
-	int i = 1;
-
-	for ( const common::ranked_symbol < > & symbol : pattern.getContent ( ) ) {
-		res.addState ( DefaultStateType ( i ) );
-
-		if ( symbol == pattern.getSubtreeWildcard ( ) ) {
-			for ( const common::ranked_symbol < > & alphabetSymbol : pattern.getAlphabet ( ) ) {
-				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
-
-				res.addCallTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { alphabetSymbol } ), DefaultStateType ( i ), DefaultSymbolType ( 'R' ) );
-			}
-		} else if ( symbol == pattern.getVariablesBar ( ) ) {
-			for ( const common::ranked_symbol < > & alphabetSymbol : pattern.getAlphabet ( ) ) {
-				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) ) continue;
-
-				if ( pattern.getBars ( ).count ( alphabetSymbol ) )
-					res.addReturnTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { alphabetSymbol } ), DefaultSymbolType ( 'T' ), DefaultStateType ( i - 1 ) );
-				else
-					res.addCallTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { alphabetSymbol } ), DefaultStateType ( i - 1 ), DefaultSymbolType ( 'T' ) );
-			}
-
-			for ( const common::ranked_symbol < > & alphabetSymbol : pattern.getAlphabet ( ) ) {
-				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( ! pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
-
-				res.addReturnTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { alphabetSymbol } ), DefaultSymbolType ( 'R' ), DefaultStateType ( i ) );
-			}
-		} else if ( pattern.getBars ( ).count ( symbol ) ) {
-			res.addReturnTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultSymbolType ( 'T' ), DefaultStateType ( i ) );
-		} else {
-			res.addCallTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( i ), DefaultSymbolType ( 'T' ) );
-		}
-
-		i++;
-	}
-
-	res.addFinalState ( DefaultStateType ( i - 1 ) );
-	return res;
-}
-
-auto ExactPatternMatchingAutomatonPrefixRankedBarPattern = registration::AbstractRegister < ExactPatternMatchingAutomaton, automaton::VisiblyPushdownNPDA < >, const tree::PrefixRankedBarPattern < > & > ( ExactPatternMatchingAutomaton::construct );
+auto ExactPatternMatchingAutomatonPrefixRankedBarPattern = registration::AbstractRegister < ExactPatternMatchingAutomaton, automaton::VisiblyPushdownNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedBarPattern < > & > ( ExactPatternMatchingAutomaton::construct );
 
 automaton::NFTA < > ExactPatternMatchingAutomaton::construct ( const tree::RankedTree < > & pattern ) {
 	return ExactSubtreeMatchingAutomaton::construct ( pattern );
diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
index 75e98272ca..62ef9efb81 100644
--- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
+++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
@@ -11,6 +11,8 @@
 #include <automaton/AutomatonFeatures.h>
 #include <tree/TreeFeatures.h>
 
+#include <alphabet/BottomOfTheStackSymbol.h>
+
 namespace arbology {
 
 namespace exact {
@@ -23,13 +25,80 @@ public:
 	 */
 	static automaton::NPDA < > construct ( const tree::PrefixRankedPattern < > & pattern );
 	static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedTree < > & pattern );
-	static automaton::VisiblyPushdownNPDA < > construct ( const tree::PrefixRankedBarPattern < > & pattern );
+	template < class SymbolType, class RankType >
+	static automaton::VisiblyPushdownNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern );
 	static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedBarTree < > & pattern );
 	static automaton::NFTA < > construct ( const tree::RankedTree < > & pattern );
 	static automaton::NFTA < > construct ( const tree::RankedPattern < > & pattern );
 
 };
 
+template < class SymbolType, class RankType >
+automaton::VisiblyPushdownNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactPatternMatchingAutomaton::construct ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern ) {
+	automaton::VisiblyPushdownNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( alphabet::BottomOfTheStackSymbol::instance < char > ( ) );
+
+	res.addState ( 0 );
+	res.addInitialState ( 0 );
+
+	for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) {
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
+
+		if ( pattern.getBars ( ).count ( symbol ) )
+			res.addReturnInputSymbol ( symbol );
+		else
+			res.addCallInputSymbol ( symbol );
+	}
+
+	res.setPushdownStoreAlphabet ( { alphabet::BottomOfTheStackSymbol::instance < char > ( ) , 'T', 'R' } );
+
+	for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) {
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
+
+		if ( pattern.getBars ( ).count ( symbol ) )
+			res.addReturnTransition ( 0, symbol, 'T', 0 );
+		else
+			res.addCallTransition ( 0, symbol, 0, 'T' );
+	}
+
+	unsigned i = 1;
+
+	for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getContent ( ) ) {
+		res.addState ( i );
+
+		if ( symbol == pattern.getSubtreeWildcard ( ) ) {
+			for ( const common::ranked_symbol < SymbolType, RankType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
+				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
+
+				res.addCallTransition ( i - 1, alphabetSymbol, i, 'R' );
+			}
+		} else if ( symbol == pattern.getVariablesBar ( ) ) {
+			for ( const common::ranked_symbol < SymbolType, RankType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
+				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) ) continue;
+
+				if ( pattern.getBars ( ).count ( alphabetSymbol ) )
+					res.addReturnTransition ( i - 1, alphabetSymbol, 'T', i - 1 );
+				else
+					res.addCallTransition ( i - 1, alphabetSymbol, i - 1, 'T' );
+			}
+
+			for ( const common::ranked_symbol < SymbolType, RankType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
+				if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( ! pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
+
+				res.addReturnTransition ( i - 1, alphabetSymbol, 'R', i );
+			}
+		} else if ( pattern.getBars ( ).count ( symbol ) ) {
+			res.addReturnTransition ( i - 1, symbol, 'T', i );
+		} else {
+			res.addCallTransition ( i - 1, symbol, i, 'T' );
+		}
+
+		i++;
+	}
+
+	res.addFinalState ( i - 1 );
+	return res;
+}
+
 } /* namespace exact */
 
 } /* namespace arbology */
-- 
GitLab