From e3ad22bfacfe674db9d7c3f93345e33e67c1181f Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 6 Dec 2016 09:24:13 +0100
Subject: [PATCH] template tree properties algorithms

---
 .../properties/ExactSubtreeRepeatsNaive.cpp   |  93 -------------
 .../properties/ExactSubtreeRepeatsNaive.h     | 118 ++++++++++++++++-
 .../ReversedBadCharacterShiftTable.cpp        | 112 ----------------
 .../ReversedBadCharacterShiftTable.h          | 125 +++++++++++++++++-
 4 files changed, 233 insertions(+), 215 deletions(-)

diff --git a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp
index 9c14e08469..51ff2af299 100644
--- a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp
+++ b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp
@@ -6,13 +6,6 @@
  */
 
 #include "ExactSubtreeRepeatsNaive.h"
-#include "SubtreeJumpTable.h"
-
-#include <tree/ranked/RankedTree.h>
-#include <tree/ranked/PrefixRankedTree.h>
-#include <tree/ranked/PrefixRankedBarTree.h>
-#include <tree/Tree.h>
-#include <global/GlobalData.h>
 
 namespace tree {
 
@@ -22,94 +15,8 @@ tree::Tree ExactSubtreeRepeatsNaive::repeats ( const tree::Tree & tree ) {
 	return dispatch ( tree.getData ( ) );
 }
 
-std::tree < std::ranked_symbol < > > ExactSubtreeRepeatsNaive::repeats ( const std::tree < std::ranked_symbol < > > & node, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId ) {
-	std::vector < std::tree < std::ranked_symbol < > > > children;
-	std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( node.getData ( ), std::vector < std::ranked_symbol < > > ( ) );
-
-	for ( const std::tree < std::ranked_symbol < > > & child : node.getChildren() ) {
-		children.push_back ( repeats ( child, data, minId ) );
-		childRepeatsKey.second.push_back ( children.back ( ).getData ( ) );
-	}
-
-	int & uniqueRepeatId = data[childRepeatsKey];
-
-	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
-
-	return std::tree < std::ranked_symbol < > > ( std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), node.getData ( ).getRank ( ) ), std::move ( children ) );
-}
-
-tree::RankedTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::RankedTree < > & tree ) {
-	int minId = 1;
-	std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data;
-
-	return tree::RankedTree < > ( repeats ( tree.getContent ( ), data, minId ) );
-}
-
 auto ExactRepeatsNaiveRankedTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::RankedTree < >, tree::RankedTree < > > ( ExactSubtreeRepeatsNaive::repeats );
-
-std::ranked_symbol < > ExactSubtreeRepeatsNaive::repeatsPrefixRanked ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ) {
-	int begin = index;
-	std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < > > ( ) );
-
-	res.push_back ( std::ranked_symbol < > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) );
-
-	index++;
-
-	for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i )
-		childRepeatsKey.second.push_back ( repeatsPrefixRanked ( symbols, res, data, minId, index ) );
-
-	int & uniqueRepeatId = data[childRepeatsKey];
-
-	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
-
-	res[begin] = std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) );
-	return res[begin];
-}
-
-tree::PrefixRankedTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedTree < > & tree ) {
-	int minId = 1;
-	int index = 0;
-	std::vector < std::ranked_symbol < > > res;
-	std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data;
-
-	repeatsPrefixRanked ( tree.getContent ( ), res, data, minId, index );
-	return tree::PrefixRankedTree < > ( res );
-}
-
 auto ExactRepeatsNaivePrefixRankedTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::PrefixRankedTree < >, tree::PrefixRankedTree < > > ( ExactSubtreeRepeatsNaive::repeats );
-
-std::ranked_symbol < > ExactSubtreeRepeatsNaive::repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ) {
-	int begin = index;
-	std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < > > ( ) );
-
-	res.push_back ( std::ranked_symbol < > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) );
-
-	index++;
-
-	for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i )
-		childRepeatsKey.second.push_back ( repeatsPrefixRankedBar ( symbols, res, data, minId, index ) );
-
-	int & uniqueRepeatId = data[childRepeatsKey];
-
-	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
-
-	res[begin] = std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) );
-	res.push_back ( symbols[index] );
-	index++;
-
-	return res[begin];
-}
-
-tree::PrefixRankedBarTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedBarTree < > & tree ) {
-	int minId = 1;
-	int index = 0;
-	std::vector < std::ranked_symbol < > > res;
-	std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data;
-
-	repeatsPrefixRankedBar ( tree.getContent ( ), res, data, minId, index );
-	return tree::PrefixRankedBarTree < > ( tree.getBars ( ), res );
-}
-
 auto ExactRepeatsNaivePrefixRankedBarTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::PrefixRankedBarTree < >, tree::PrefixRankedBarTree < > > ( ExactSubtreeRepeatsNaive::repeats );
 
 } /* namespace properties */
diff --git a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h
index 2378926916..3f81f6e3da 100644
--- a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h
+++ b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h
@@ -17,6 +17,14 @@
 #include <tree>
 #include <alphabet/RankedSymbol.h>
 
+#include "SubtreeJumpTable.h"
+
+#include <tree/ranked/RankedTree.h>
+#include <tree/ranked/PrefixRankedTree.h>
+#include <tree/ranked/PrefixRankedBarTree.h>
+#include <tree/Tree.h>
+#include <global/GlobalData.h>
+
 namespace tree {
 
 namespace properties {
@@ -25,9 +33,14 @@ namespace properties {
  * Simple computation of subtree repeats
  */
 class ExactSubtreeRepeatsNaive : public std::SingleDispatch < ExactSubtreeRepeatsNaive, tree::Tree, const tree::TreeBase & > {
-	static std::tree < std::ranked_symbol < > > repeats ( const std::tree < std::ranked_symbol < > > & node, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId );
-	static std::ranked_symbol < > repeatsPrefixRanked ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index );
-	static std::ranked_symbol < > repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index );
+	template < class SymbolType, class RankType >
+	static std::tree < std::ranked_symbol < SymbolType, RankType > > repeats ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId );
+
+	template < class SymbolType, class RankType >
+	static std::ranked_symbol < SymbolType, RankType > repeatsPrefixRanked ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index );
+
+	template < class SymbolType, class RankType >
+	static std::ranked_symbol < SymbolType, RankType > repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index );
 
 public:
 	/**
@@ -40,12 +53,105 @@ public:
 	 * Compute a same shaped tree with nodes containing unique subtree ids.
 	 * @return Tree of repeats
 	 */
-	static tree::RankedTree < > repeats ( const tree::RankedTree < > & tree );
-	static tree::PrefixRankedTree < > repeats ( const tree::PrefixRankedTree < > & tree );
-	static tree::PrefixRankedBarTree < > repeats ( const tree::PrefixRankedBarTree < > & tree );
+	template < class SymbolType, class RankType >
+	static tree::RankedTree < SymbolType, RankType > repeats ( const tree::RankedTree < SymbolType, RankType > & tree );
+	template < class SymbolType, class RankType >
+	static tree::PrefixRankedTree < SymbolType, RankType > repeats ( const tree::PrefixRankedTree < SymbolType, RankType > & tree );
+	template < class SymbolType, class RankType >
+	static tree::PrefixRankedBarTree < SymbolType, RankType > repeats ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree );
 
 };
 
+template < class SymbolType, class RankType >
+std::tree < std::ranked_symbol < SymbolType, RankType > > ExactSubtreeRepeatsNaive::repeats ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId ) {
+	std::vector < std::tree < std::ranked_symbol < SymbolType, RankType > > > children;
+	std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( node.getData ( ), std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) );
+
+	for ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & child : node.getChildren() ) {
+		children.push_back ( repeats ( child, data, minId ) );
+		childRepeatsKey.second.push_back ( children.back ( ).getData ( ) );
+	}
+
+	int & uniqueRepeatId = data[childRepeatsKey];
+
+	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
+
+	return std::tree < std::ranked_symbol < SymbolType, RankType > > ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), node.getData ( ).getRank ( ) ), std::move ( children ) );
+}
+
+template < class SymbolType, class RankType >
+tree::RankedTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::RankedTree < SymbolType, RankType > & tree ) {
+	int minId = 1;
+	std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data;
+
+	return tree::RankedTree < SymbolType, RankType > ( repeats ( tree.getContent ( ), data, minId ) );
+}
+
+template < class SymbolType, class RankType >
+std::ranked_symbol < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeatsPrefixRanked ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ) {
+	int begin = index;
+	std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) );
+
+	res.push_back ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) );
+
+	index++;
+
+	for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i )
+		childRepeatsKey.second.push_back ( repeatsPrefixRanked ( symbols, res, data, minId, index ) );
+
+	int & uniqueRepeatId = data[childRepeatsKey];
+
+	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
+
+	res[begin] = std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) );
+	return res[begin];
+}
+
+template < class SymbolType, class RankType >
+tree::PrefixRankedTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedTree < SymbolType, RankType > & tree ) {
+	int minId = 1;
+	int index = 0;
+	std::vector < std::ranked_symbol < SymbolType, RankType > > res;
+	std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data;
+
+	repeatsPrefixRanked ( tree.getContent ( ), res, data, minId, index );
+	return tree::PrefixRankedTree < SymbolType, RankType > ( res );
+}
+
+template < class SymbolType, class RankType >
+std::ranked_symbol < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ) {
+	int begin = index;
+	std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) );
+
+	res.push_back ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) );
+
+	index++;
+
+	for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i )
+		childRepeatsKey.second.push_back ( repeatsPrefixRankedBar ( symbols, res, data, minId, index ) );
+
+	int & uniqueRepeatId = data[childRepeatsKey];
+
+	if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++;
+
+	res[begin] = std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) );
+	res.push_back ( symbols[index] );
+	index++;
+
+	return res[begin];
+}
+
+template < class SymbolType, class RankType >
+tree::PrefixRankedBarTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree ) {
+	int minId = 1;
+	int index = 0;
+	std::vector < std::ranked_symbol < SymbolType, RankType > > res;
+	std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data;
+
+	repeatsPrefixRankedBar ( tree.getContent ( ), res, data, minId, index );
+	return tree::PrefixRankedBarTree < SymbolType, RankType > ( tree.getBars ( ), res );
+}
+
 } /* namespace properties */
 
 } /* namespace tree */
diff --git a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp
index 25e5d2188e..dd9f293170 100644
--- a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp
+++ b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp
@@ -7,11 +7,6 @@
 
 #include "ReversedBadCharacterShiftTable.h"
 
-#include <tree/ranked/PrefixRankedBarPattern.h>
-#include <tree/ranked/PrefixRankedBarNonlinearPattern.h>
-#include <tree/ranked/PrefixRankedPattern.h>
-#include <tree/ranked/PrefixRankedNonlinearPattern.h>
-
 namespace tree {
 
 namespace properties {
@@ -20,116 +15,9 @@ std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs
 	return dispatch ( pattern.getData ( ) );
 }
 
-std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < > & pattern ) {
-	return bcs ( tree::PrefixRankedBarNonlinearPattern < > ( pattern ) );
-}
-
 auto ReversedBadCharacterShiftTablePrefixRankedBarPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedBarPattern < > > ( ReversedBadCharacterShiftTable::bcs );
-
-std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < > & pattern ) {
-	const std::set < std::ranked_symbol < > > & alphabet = pattern.getAlphabet ( );
-
-	std::map < std::ranked_symbol < >, size_t > bcs;
-
-	 // initialisation of bcs table to the size of the pattern
-	for ( const std::ranked_symbol < > & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
-
-		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
-	}
-
-	 // find the distance between the beginning of the pattern and the index
-	 // of the first symbol representing the variable's bar
-	unsigned firstSBarOffset = pattern.getContent ( ).size ( ) + 1;
-
-	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
-		if ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) )
-			firstSBarOffset = i;
-
-	// limit the shift by occurrence of the last variable
-
-	for ( const std::ranked_symbol < > & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
-
-		size_t tmp = firstSBarOffset;
-
-		if ( pattern.getBars ( ).count ( symbol ) )
-			 // size of the smallest subtree containing given terminal depend
-			 // on the arity of the terminal
-			tmp += ( size_t ) symbol.getRank ( ) * 2;
-		else if ( tmp >= 2 )
-			 // bar symbols match the variable bar which is one symbol after
-			 // the last variable, conditioned because of the case S S| where
-			 // the -1 would cause shift by 0 -- illegal
-			tmp -= 1;
-
-		if ( bcs[symbol] > tmp )
-			bcs[symbol] = tmp;
-	}
-
-	 // limit the shift by position of symbols within the pattern
-	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
-		if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue;
-
-		size_t tmp = i;
-
-		if ( bcs[pattern.getContent ( )[i]] > tmp )
-			bcs[pattern.getContent ( )[i]] = tmp;
-	}
-
-	return bcs;
-}
-
 auto ReversedBadCharacterShiftTablePrefixRankedBarNonlinearPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedBarNonlinearPattern < > > ( ReversedBadCharacterShiftTable::bcs );
-
-std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedPattern < > & pattern ) {
-	return bcs ( tree::PrefixRankedNonlinearPattern < > ( pattern ) );
-}
-
 auto ReversedBadCharacterShiftTablePrefixRankedPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedPattern < > > ( ReversedBadCharacterShiftTable::bcs );
-
-std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < > & pattern ) {
-	const std::set < std::ranked_symbol < > > & alphabet = pattern.getAlphabet ( );
-
-	std::map < std::ranked_symbol < >, size_t > bcs;
-
-	 // initialisation of bcs table to the size of the pattern
-	for ( const std::ranked_symbol < > & symbol : alphabet ) {
-		if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue;
-
-		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
-	}
-
-	 // find the distance between the beginning of the pattern and the index
-	 // of the first symbol representing the variable's bar
-	unsigned firstSOffset = pattern.getContent ( ).size ( ) + 1;
-
-	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
-		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) )
-			firstSOffset = i;
-
-	if ( firstSOffset == 0 ) firstSOffset = 1;
-
-	 // limit the shift by occurrence of the last variable
-	for ( const std::ranked_symbol < > & symbol : alphabet ) {
-		if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue;
-
-		if ( bcs[symbol] > firstSOffset )
-			bcs[symbol] = firstSOffset;
-	}
-
-	 // limit the shift by position of symbols within the pattern
-	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
-		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) continue;
-		size_t tmp = i;
-
-		if ( bcs[pattern.getContent ( )[i]] > tmp )
-			bcs[pattern.getContent ( )[i]] = tmp;
-	}
-
-	return bcs;
-}
-
 auto ReversedBadCharacterShiftTablePrefixRankedNonlinearPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedNonlinearPattern < > > ( ReversedBadCharacterShiftTable::bcs );
 
 } /* namespace properties */
diff --git a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h
index 0eb08f2487..edfbab9a7e 100644
--- a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h
+++ b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h
@@ -16,6 +16,11 @@
 #include <set>
 #include <map>
 
+#include <tree/ranked/PrefixRankedBarPattern.h>
+#include <tree/ranked/PrefixRankedBarNonlinearPattern.h>
+#include <tree/ranked/PrefixRankedPattern.h>
+#include <tree/ranked/PrefixRankedNonlinearPattern.h>
+
 namespace tree {
 
 namespace properties {
@@ -32,13 +37,125 @@ public:
 	 */
 	static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::RankedTreeWrapper & pattern );
 
-	static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedBarPattern < > & pattern );
-	static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedBarNonlinearPattern < > & pattern );
-	static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedPattern < > & pattern );
-	static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedNonlinearPattern < > & pattern );
+	template < class SymbolType, class RankType >
+	static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern );
+	template < class SymbolType, class RankType >
+	static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > & pattern );
+	template < class SymbolType, class RankType >
+	static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern );
+	template < class SymbolType, class RankType >
+	static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType, RankType > & pattern );
 
 };
 
+template < class SymbolType, class RankType >
+std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern ) {
+	return bcs ( tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > ( pattern ) );
+}
+
+template < class SymbolType, class RankType >
+std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > & pattern ) {
+	const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabet = pattern.getAlphabet ( );
+
+	std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs;
+
+	 // initialisation of bcs table to the size of the pattern
+	for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) {
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
+
+		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
+	}
+
+	 // find the distance between the beginning of the pattern and the index
+	 // of the first symbol representing the variable's bar
+	unsigned firstSBarOffset = pattern.getContent ( ).size ( ) + 1;
+
+	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
+		if ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) )
+			firstSBarOffset = i;
+
+	// limit the shift by occurrence of the last variable
+
+	for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) {
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
+
+		size_t tmp = firstSBarOffset;
+
+		if ( pattern.getBars ( ).count ( symbol ) )
+			 // size of the smallest subtree containing given terminal depend
+			 // on the arity of the terminal
+			tmp += ( size_t ) symbol.getRank ( ) * 2;
+		else if ( tmp >= 2 )
+			 // bar symbols match the variable bar which is one symbol after
+			 // the last variable, conditioned because of the case S S| where
+			 // the -1 would cause shift by 0 -- illegal
+			tmp -= 1;
+
+		if ( bcs[symbol] > tmp )
+			bcs[symbol] = tmp;
+	}
+
+	 // limit the shift by position of symbols within the pattern
+	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
+		if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue;
+
+		size_t tmp = i;
+
+		if ( bcs[pattern.getContent ( )[i]] > tmp )
+			bcs[pattern.getContent ( )[i]] = tmp;
+	}
+
+	return bcs;
+}
+
+template < class SymbolType, class RankType >
+std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern ) {
+	return bcs ( tree::PrefixRankedNonlinearPattern < SymbolType, RankType > ( pattern ) );
+}
+
+template < class SymbolType, class RankType >
+std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType, RankType > & pattern ) {
+	const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabet = pattern.getAlphabet ( );
+
+	std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs;
+
+	 // initialisation of bcs table to the size of the pattern
+	for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) {
+		if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue;
+
+		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
+	}
+
+	 // find the distance between the beginning of the pattern and the index
+	 // of the first symbol representing the variable's bar
+	unsigned firstSOffset = pattern.getContent ( ).size ( ) + 1;
+
+	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
+		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) )
+			firstSOffset = i;
+
+	if ( firstSOffset == 0 ) firstSOffset = 1;
+
+	 // limit the shift by occurrence of the last variable
+	for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) {
+		if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue;
+
+		if ( bcs[symbol] > firstSOffset )
+			bcs[symbol] = firstSOffset;
+	}
+
+	 // limit the shift by position of symbols within the pattern
+	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
+		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) continue;
+		size_t tmp = i;
+
+		if ( bcs[pattern.getContent ( )[i]] > tmp )
+			bcs[pattern.getContent ( )[i]] = tmp;
+	}
+
+	return bcs;
+}
+
 } /* namespace properties */
 
 } /* namespace tree */
-- 
GitLab