From 2af12bbf172344d37b73c3648eeece8fb86662f8 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 27 Jan 2020 17:44:21 +0100
Subject: [PATCH] Quantum Leap Tree algo + refactor

---
 alib2algo/src/arbology/exact/Exact.cpp        |   1 +
 .../src/arbology/exact/KnuthMorrisPratt.h     |  12 +-
 ...eapUsingQuickSearchShiftAndBorderArray.cxx |  15 +++
 ...mLeapUsingQuickSearchShiftAndBorderArray.h | 100 +++++++++++++++
 alib2algo/src/arbology/exact/QuickSearch.h    |   6 +-
 .../src/arbology/exact/ReversedQuickSearch.h  |  10 +-
 .../src/tree/exact/ForwardOccurrenceTest.cpp  |   4 +-
 .../src/tree/exact/ForwardOccurrenceTest.h    | 120 ++++++++----------
 .../QuickSearchBadCharacterShiftTable.cpp     |  16 ---
 .../tree/properties/QuickSearchShiftTable.cpp |  16 +++
 ...erShiftTable.h => QuickSearchShiftTable.h} |  14 +-
 ...ersedQuickSearchBadCharacterShiftTable.cpp |  18 ---
 .../ReversedQuickSearchShiftTable.cpp         |  18 +++
 ...able.h => ReversedQuickSearchShiftTable.h} |  16 +--
 .../test-src/tests/arbologyTest.cpp           |   3 +
 15 files changed, 238 insertions(+), 131 deletions(-)
 create mode 100644 alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.cxx
 create mode 100644 alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.h
 delete mode 100644 alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.cpp
 create mode 100644 alib2algo/src/tree/properties/QuickSearchShiftTable.cpp
 rename alib2algo/src/tree/properties/{QuickSearchBadCharacterShiftTable.h => QuickSearchShiftTable.h} (86%)
 delete mode 100644 alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.cpp
 create mode 100644 alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.cpp
 rename alib2algo/src/tree/properties/{ReversedQuickSearchBadCharacterShiftTable.h => ReversedQuickSearchShiftTable.h} (88%)

diff --git a/alib2algo/src/arbology/exact/Exact.cpp b/alib2algo/src/arbology/exact/Exact.cpp
index 04d6ded347..481be9fa85 100644
--- a/alib2algo/src/arbology/exact/Exact.cpp
+++ b/alib2algo/src/arbology/exact/Exact.cpp
@@ -11,3 +11,4 @@
 #include "QuickSearch.cxx"
 #include "ReversedBoyerMooreHorspool.cxx"
 #include "ReversedQuickSearch.cxx"
+#include "QuantumLeapUsingQuickSearchShiftAndBorderArray.cxx"
diff --git a/alib2algo/src/arbology/exact/KnuthMorrisPratt.h b/alib2algo/src/arbology/exact/KnuthMorrisPratt.h
index d0d11f136b..0a88a95825 100644
--- a/alib2algo/src/arbology/exact/KnuthMorrisPratt.h
+++ b/alib2algo/src/arbology/exact/KnuthMorrisPratt.h
@@ -79,11 +79,12 @@ ext::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedBarTree
 
 	 // index to the subject
 	unsigned i = 0;
+	unsigned j = 0;
 
 	 // main loop of the algorithm over all possible indexes where the pattern can start
 	while ( i + pattern.getContent ( ).size ( ) <= subject.getContent ( ).size ( ) ) {
 		 // index to the pattern
-		unsigned j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, pattern, i );
+		j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, pattern, i, j );
 
 		 // match was found
 		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( i );
@@ -123,11 +124,12 @@ ext::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedBarTree
 
 	 // index to the subject
 	unsigned i = 0;
+	unsigned j = 0;
 
 	 // main loop of the algorithm over all possible indexes where the pattern can start
 	while ( i + pattern.getContent ( ).size ( ) <= subject.getContent ( ).size ( ) ) {
 		 // index to the pattern
-		unsigned j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, repeats, pattern, i );
+		j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, repeats, pattern, i, j );
 
 		 // match was found
 		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( i );
@@ -171,11 +173,12 @@ ext::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedTree < S
 
 	 // index to the subject
 	unsigned i = 0;
+	unsigned j = 0;
 
 	 // main loop of the algorithm over all possible indexes where the pattern can start
 	while ( i + pattern.getContent ( ).size ( ) <= subject.getContent ( ).size ( ) ) {
 		 // index to the pattern
-		unsigned j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, pattern, i );
+		j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, pattern, i, j );
 
 		 // match was found
 		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( i );
@@ -215,11 +218,12 @@ ext::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedTree < S
 
 	 // index to the subject
 	unsigned i = 0;
+	unsigned j = 0;
 
 	 // main loop of the algorithm over all possible indexes where the pattern can start
 	while ( i + pattern.getContent ( ).size ( ) <= subject.getContent ( ).size ( ) ) {
 		 // index to the pattern
-		unsigned j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, repeats, pattern, i );
+		j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, repeats, pattern, i, j );
 
 		 // match was found
 		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( i );
diff --git a/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.cxx b/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.cxx
new file mode 100644
index 0000000000..db4d6b9bbb
--- /dev/null
+++ b/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.cxx
@@ -0,0 +1,15 @@
+/*
+ * QuantumLeapUsingQuickSearchShiftAndBorderArray.cpp
+ *
+ *  Created on: 27. 1. 2020
+ *      Author: Jan Travnicek
+ */
+
+#include "QuantumLeapUsingQuickSearchShiftAndBorderArray.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto QuantumLeapUsingQuickSearchShiftAndBorderArray = registration::AbstractRegister < arbology::exact::QuantumLeapUsingQuickSearchShiftAndBorderArray, ext::set < unsigned >, const tree::PrefixRankedTree < > &, const tree::PrefixRankedPattern < > &, size_t > ( arbology::exact::QuantumLeapUsingQuickSearchShiftAndBorderArray::match );
+
+} /* namespace */
diff --git a/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.h b/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.h
new file mode 100644
index 0000000000..ba3da5a826
--- /dev/null
+++ b/alib2algo/src/arbology/exact/QuantumLeapUsingQuickSearchShiftAndBorderArray.h
@@ -0,0 +1,100 @@
+/*
+ * QuantumLeapUsingQuickSearchShiftAndBorderArray.h
+ *
+ *  Created on: 27. 1. 2020
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _QUICK_SEARCH_USING_QUICK_SEARCH_SHIFT_AND_BORDER_ARRAY_H_
+#define _QUICK_SEARCH_USING_QUICK_SEARCH_SHIFT_AND_BORDER_ARRAY_H_
+
+#include <alib/set>
+#include <alib/map>
+
+#include <tree/ranked/PrefixRankedTree.h>
+#include <tree/ranked/PrefixRankedPattern.h>
+
+#include <tree/properties/ReversedBadCharacterShiftTable.h>
+#include <tree/properties/BorderArrayNaive.h>
+#include <tree/properties/SubtreeJumpTable.h>
+#include <tree/exact/ForwardOccurrenceTest.h>
+
+#include <ext/algorithm>
+
+namespace arbology {
+
+namespace exact {
+
+/**
+ * Implementation of DeadZone matching using bcs as shifting method to both directions
+ */
+class QuantumLeapUsingQuickSearchShiftAndBorderArray {
+public:
+	/**
+	 * Search for pattern in a linearised tree.
+	 * @return set set of occurences
+	 */
+	template < class SymbolType >
+	static ext::set < unsigned > match ( const tree::PrefixRankedTree < SymbolType > & subject, const tree::PrefixRankedPattern < SymbolType > & pattern, size_t z );
+};
+
+template < class SymbolType >
+ext::set < unsigned > QuantumLeapUsingQuickSearchShiftAndBorderArray::match ( const tree::PrefixRankedTree < SymbolType > & subject, const tree::PrefixRankedPattern < SymbolType > & pattern, size_t z ) {
+	ext::set < unsigned > occ;
+	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
+	ext::vector < size_t > construct = tree::properties::BorderArray::construct ( pattern );
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bqss = tree::properties::ReversedQuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getAlphabet ( ) ) {
+		bqss [ symbol ] = z - bqss [ symbol ];
+	}
+
+	size_t Spos = pattern.getContent ( ).size ( );
+	for ( size_t i = 0; i < pattern.getContent ( ).size ( ); ++ i ) {
+		if ( pattern.getContent ( ) [ i ] == pattern.getSubtreeWildcard ( ) ) {
+			Spos = i;
+			break;
+		}
+	}
+
+	size_t haystack_offset = 0;
+	size_t j = 0;
+
+	while ( haystack_offset + pattern.getContent ( ).size ( ) <= subject.getContent ( ).size ( ) ) {
+		j = tree::exact::ForwardOccurrenceTest::occurrence ( subject, subjectSubtreeJumpTable, pattern, haystack_offset, j );
+
+		 // match was found
+		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( haystack_offset );
+
+		if ( haystack_offset + pattern.getContent().size() == subject.getContent().size() ) { // this is needed only because there is no terminating character in the subject ...
+			break; // Here we don't do any more shifts if the pattern is already aligned at the utter end of the text
+		}
+
+		size_t shf;
+		if ( j == 0 ) {
+			shf = 1;
+		} else {
+			size_t shift = j - construct [ j ];
+			 // shift heuristics
+			shf = shift;
+			j = ext::min ( Spos, j ) - shift;
+		}
+
+		size_t shb = z;
+		if ( haystack_offset + z - 1 < subject.getContent ( ).size ( ) ) // this condition is needed because at worst MAX ( z - m, 0 ) additional characters are needed in the subject after its end
+			shb = bqss [ subject.getContent ( ) [ haystack_offset + z - 1 ] ];
+		if ( shf > shb ) {
+			haystack_offset += z;
+			j = 0;
+		} else {
+			haystack_offset += shf;
+		}
+	}
+
+	return occ;
+}
+
+} /* namespace exact */
+
+} /* namespace arbology */
+
+#endif /* _QUICK_SEARCH_USING_QUICK_SEARCH_SHIFT_AND_BORDER_ARRAY_H_ */
diff --git a/alib2algo/src/arbology/exact/QuickSearch.h b/alib2algo/src/arbology/exact/QuickSearch.h
index 1bc29b56ec..ece021b3de 100644
--- a/alib2algo/src/arbology/exact/QuickSearch.h
+++ b/alib2algo/src/arbology/exact/QuickSearch.h
@@ -13,7 +13,7 @@
 
 #include <common/ranked_symbol.hpp>
 
-#include <tree/properties/QuickSearchBadCharacterShiftTable.h>
+#include <tree/properties/QuickSearchShiftTable.h>
 #include <tree/properties/SubtreeJumpTable.h>
 #include <tree/properties/ExactSubtreeRepeatsNaive.h>
 #include <tree/exact/BackwardOccurrenceTest.h>
@@ -54,7 +54,7 @@ ext::set < unsigned > QuickSearch::match ( const tree::PrefixRankedBarTree < Sym
 template < class SymbolType >
 ext::set < unsigned > QuickSearch::match ( const tree::PrefixRankedBarTree < SymbolType > & subject, const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::QuickSearchBadCharacterShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::QuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 
 	// index to the subject
@@ -82,7 +82,7 @@ ext::set < unsigned > QuickSearch::match ( const tree::PrefixRankedBarTree < Sym
 template < class SymbolType >
 ext::set < unsigned > QuickSearch::match ( const tree::PrefixRankedBarTree < SymbolType > & subject, const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::QuickSearchBadCharacterShiftTable::bcs ( pattern ); //NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::QuickSearchShiftTable::bcs ( pattern ); //NOTE: the subjects alphabet must be a subset or equal to the pattern
 
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 	tree::PrefixRankedBarTree < unsigned > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( subject );
diff --git a/alib2algo/src/arbology/exact/ReversedQuickSearch.h b/alib2algo/src/arbology/exact/ReversedQuickSearch.h
index 841bd286d4..169664bd06 100644
--- a/alib2algo/src/arbology/exact/ReversedQuickSearch.h
+++ b/alib2algo/src/arbology/exact/ReversedQuickSearch.h
@@ -12,7 +12,7 @@
 #include <alib/map>
 #include <common/ranked_symbol.hpp>
 
-#include <tree/properties/ReversedQuickSearchBadCharacterShiftTable.h>
+#include <tree/properties/ReversedQuickSearchShiftTable.h>
 #include <tree/properties/SubtreeJumpTable.h>
 #include <tree/properties/ExactSubtreeRepeatsNaive.h>
 #include <tree/exact/ForwardOccurrenceTest.h>
@@ -62,7 +62,7 @@ ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedBarTr
 template < class SymbolType >
 ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedBarTree < SymbolType > & subject, const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 
 	// index to the subject
@@ -93,7 +93,7 @@ ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedBarTr
 template < class SymbolType >
 ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedBarTree < SymbolType > & subject, const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 	ext::map < common::ranked_symbol < SymbolType >, unsigned > variablesSetting;
 
@@ -131,7 +131,7 @@ ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedTree
 template < class SymbolType >
 ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedTree < SymbolType > & subject, const tree::PrefixRankedPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 
 	// index to the subject
@@ -161,7 +161,7 @@ ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedTree
 template < class SymbolType >
 ext::set < unsigned > ReversedQuickSearch::match ( const tree::PrefixRankedTree < SymbolType > & subject, const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ) {
 	ext::set < unsigned > occ;
-	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
+	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs = tree::properties::ReversedQuickSearchShiftTable::bcs ( pattern ); // NOTE: the subjects alphabet must be a subset or equal to the pattern
 	ext::vector < int > subjectSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( subject );
 	tree::PrefixRankedTree < unsigned > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( subject );
 
diff --git a/alib2algo/src/tree/exact/ForwardOccurrenceTest.cpp b/alib2algo/src/tree/exact/ForwardOccurrenceTest.cpp
index 85537fbff5..b795e3d267 100644
--- a/alib2algo/src/tree/exact/ForwardOccurrenceTest.cpp
+++ b/alib2algo/src/tree/exact/ForwardOccurrenceTest.cpp
@@ -10,8 +10,8 @@
 
 namespace {
 
-auto ForwardOccurrenceTestPrefixRankedTree = registration::AbstractRegister < tree::exact::ForwardOccurrenceTest, size_t, const tree::PrefixRankedTree < > &, const ext::vector < int > &, const tree::PrefixRankedTree < > &, size_t > ( tree::exact::ForwardOccurrenceTest::occurrence, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "subject", "subjectSubtreeJumpTable", "pattern", "position" );
+auto ForwardOccurrenceTestPrefixRankedTree = registration::AbstractRegister < tree::exact::ForwardOccurrenceTest, size_t, const tree::PrefixRankedTree < > &, const ext::vector < int > &, const tree::PrefixRankedTree < > &, size_t, size_t > ( tree::exact::ForwardOccurrenceTest::occurrence, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "subject", "subjectSubtreeJumpTable", "pattern", "haystack_offset", "needle_offset" );
 
-auto ForwardOccurrenceTestPrefixRankedBarTree = registration::AbstractRegister < tree::exact::ForwardOccurrenceTest, size_t, const tree::PrefixRankedBarTree < > &, const ext::vector < int > &, const tree::PrefixRankedBarTree < > &, size_t > ( tree::exact::ForwardOccurrenceTest::occurrence, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "subject", "subjectSubtreeJumpTable", "pattern", "position" );
+auto ForwardOccurrenceTestPrefixRankedBarTree = registration::AbstractRegister < tree::exact::ForwardOccurrenceTest, size_t, const tree::PrefixRankedBarTree < > &, const ext::vector < int > &, const tree::PrefixRankedBarTree < > &, size_t, size_t > ( tree::exact::ForwardOccurrenceTest::occurrence, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "subject", "subjectSubtreeJumpTable", "pattern", "haystack_offset", "needle_offset" );
 
 } /* namespace */
diff --git a/alib2algo/src/tree/exact/ForwardOccurrenceTest.h b/alib2algo/src/tree/exact/ForwardOccurrenceTest.h
index 44b3c2c787..bbfedf4edc 100644
--- a/alib2algo/src/tree/exact/ForwardOccurrenceTest.h
+++ b/alib2algo/src/tree/exact/ForwardOccurrenceTest.h
@@ -24,145 +24,129 @@ namespace exact {
 class ForwardOccurrenceTest {
 public:
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarTree < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarTree < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition = 0);
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarPattern < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition = 0 );
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedBarTree < unsigned > & repeats, const PrefixRankedBarNonlinearPattern < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedBarTree < unsigned > & repeats, const PrefixRankedBarNonlinearPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition = 0);
 
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedTree < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedTree < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition = 0);
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedPattern < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition =0 );
 	template < class SymbolType >
-	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedTree < unsigned > & repeats, const PrefixRankedNonlinearPattern < SymbolType > & pattern, size_t subjectPosition );
+	static size_t occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedTree < unsigned > & repeats, const PrefixRankedNonlinearPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition = 0 );
 };
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarTree < SymbolType > & pattern, size_t subjectPosition ) {
-	return occurrence ( subject, subjectSubtreeJumpTable, tree::PrefixRankedBarPattern < SymbolType > ( pattern ), subjectPosition );
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarTree < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
+	return occurrence ( subject, subjectSubtreeJumpTable, tree::PrefixRankedBarPattern < SymbolType > ( pattern ), subjectPosition, patternPosition );
 }
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarPattern < SymbolType > & pattern, size_t subjectPosition ) {
-	 // offset to the subject
-	size_t offset = subjectPosition;
-	size_t j = 0;
-
-	while ( ( j < pattern.getContent ( ).size ( ) ) && ( offset < subject.getContent ( ).size ( ) ) ) {
-		if ( subject.getContent ( )[offset] == pattern.getContent ( )[j] ) {
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedBarPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
+	while ( ( patternPosition < pattern.getContent ( ).size ( ) ) && ( subjectPosition < subject.getContent ( ).size ( ) ) ) {
+		if ( subject.getContent ( )[subjectPosition] == pattern.getContent ( )[patternPosition] ) {
 			 // match of symbol
-			offset = offset + 1;
-			j = j + 1;
-		} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( ! subject.getBars ( ).count ( subject.getContent ( )[offset] ) ) ) { //the second part of the condition is needed to handle S |S
+			subjectPosition = subjectPosition + 1;
+			patternPosition = patternPosition + 1;
+		} else if ( ( pattern.getContent ( )[patternPosition] == pattern.getSubtreeWildcard ( ) ) && ( ! subject.getBars ( ).count ( subject.getContent ( )[subjectPosition] ) ) ) { //the second part of the condition is needed to handle S |S
 			 // match of variable with subtree
-			offset = subjectSubtreeJumpTable[offset];
-			j = j + 2;
+			subjectPosition = subjectSubtreeJumpTable[subjectPosition];
+			patternPosition = patternPosition + 2;
 		} else {
 			break;
 		}
 	}
 
-	return j;
+	return patternPosition;
 }
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedBarTree < unsigned > & repeats, const PrefixRankedBarNonlinearPattern < SymbolType > & pattern, size_t subjectPosition ) {
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedBarTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedBarTree < unsigned > & repeats, const PrefixRankedBarNonlinearPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
 
 	 // to represent state of variable to subtree repeat
 	ext::map < common::ranked_symbol < SymbolType >, unsigned > variablesSetting;
 
-	// offset to the subject
-	unsigned offset = subjectPosition;
-	unsigned j = 0;
-
-	while ( ( j < pattern.getContent ( ).size ( ) ) && ( offset < subject.getContent ( ).size ( ) ) ) {
-		if ( subject.getContent ( )[offset] == pattern.getContent ( )[j] ) {
+	while ( ( patternPosition < pattern.getContent ( ).size ( ) ) && ( subjectPosition < subject.getContent ( ).size ( ) ) ) {
+		if ( subject.getContent ( )[subjectPosition] == pattern.getContent ( )[patternPosition] ) {
 			 // match of symbol
-			offset = offset + 1;
-			j = j + 1;
-		} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[j] ) ) && ( ! subject.getBars ( ).count ( subject.getContent ( )[offset] ) ) ) { //the second part of the condition is needed to handle S |S
+			subjectPosition = subjectPosition + 1;
+			patternPosition = patternPosition + 1;
+		} else if ( ( pattern.getContent ( )[patternPosition] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[patternPosition] ) ) && ( ! subject.getBars ( ).count ( subject.getContent ( )[subjectPosition] ) ) ) { //the second part of the condition is needed to handle S |S
 			 // check nonlinear variable
-			if ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ j ] ) ) {
-				auto setting = variablesSetting.find ( pattern.getContent ( )[ j ] );
+			if ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ patternPosition ] ) ) {
+				auto setting = variablesSetting.find ( pattern.getContent ( )[ patternPosition ] );
 
-				if ( setting != variablesSetting.end ( ) && repeats.getContent ( )[ offset ].getSymbol ( ) != setting->second )
+				if ( setting != variablesSetting.end ( ) && repeats.getContent ( )[ subjectPosition ].getSymbol ( ) != setting->second )
 					break;
 
-				variablesSetting.insert ( std::make_pair ( pattern.getContent ( )[ j ], repeats.getContent( )[ offset ].getSymbol ( ) ) );
+				variablesSetting.insert ( std::make_pair ( pattern.getContent ( )[ patternPosition ], repeats.getContent( )[ subjectPosition ].getSymbol ( ) ) );
 			}
 
 			 // match of variable with subtree
-			offset = subjectSubtreeJumpTable[offset];
-			j = j + 2;
+			subjectPosition = subjectSubtreeJumpTable[subjectPosition];
+			patternPosition = patternPosition + 2;
 		} else {
 			break;
 		}
 	}
 
-	return j;
+	return patternPosition;
 }
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedTree < SymbolType > & pattern, size_t subjectPosition ) {
-	return occurrence ( subject, subjectSubtreeJumpTable, tree::PrefixRankedPattern < SymbolType > ( pattern ), subjectPosition );
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedTree < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
+	return occurrence ( subject, subjectSubtreeJumpTable, tree::PrefixRankedPattern < SymbolType > ( pattern ), subjectPosition, patternPosition );
 }
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedPattern < SymbolType > & pattern, size_t subjectPosition ) {
-	 // offset to the subject
-	unsigned offset = subjectPosition;
-	size_t j = 0;
-
-	while ( ( j < pattern.getContent ( ).size ( ) ) && ( offset < subject.getContent ( ).size ( ) ) ) {
-		if ( subject.getContent ( )[offset] == pattern.getContent ( )[j] )
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const PrefixRankedPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
+	while ( ( patternPosition < pattern.getContent ( ).size ( ) ) && ( subjectPosition < subject.getContent ( ).size ( ) ) ) {
+		if ( subject.getContent ( )[subjectPosition] == pattern.getContent ( )[patternPosition] )
 			 // match of symbol
-			offset = offset + 1;
-		else if ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) )
+			subjectPosition = subjectPosition + 1;
+		else if ( pattern.getContent ( )[patternPosition] == pattern.getSubtreeWildcard ( ) )
 			 // match of variable with subtree
-			offset = subjectSubtreeJumpTable[offset];
+			subjectPosition = subjectSubtreeJumpTable[subjectPosition];
 		else
 			break;
 
-		j = j + 1;
+		patternPosition = patternPosition + 1;
 	}
 
-	return j;
+	return patternPosition;
 }
 
 template < class SymbolType >
-size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedTree < unsigned > & repeats, const PrefixRankedNonlinearPattern < SymbolType > & pattern, size_t subjectPosition ) {
+size_t ForwardOccurrenceTest::occurrence ( const PrefixRankedTree < SymbolType > & subject, const ext::vector < int > & subjectSubtreeJumpTable, const tree::PrefixRankedTree < unsigned > & repeats, const PrefixRankedNonlinearPattern < SymbolType > & pattern, size_t subjectPosition, size_t patternPosition ) {
 	 // to represent state of variable to subtree repeat
 	ext::map < common::ranked_symbol < SymbolType >, unsigned > variablesSetting;
 
-	 // offset to the subject
-	unsigned offset = subjectPosition;
-	unsigned j = 0;
-
-	while ( ( j < pattern.getContent ( ).size ( ) ) && ( offset < subject.getContent ( ).size ( ) ) ) {
-		if ( subject.getContent ( )[offset] == pattern.getContent ( )[j] )
+	while ( ( patternPosition < pattern.getContent ( ).size ( ) ) && ( subjectPosition < subject.getContent ( ).size ( ) ) ) {
+		if ( subject.getContent ( )[subjectPosition] == pattern.getContent ( )[patternPosition] )
 			 // match of symbol
-			offset = offset + 1;
-		else if ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ j ] ) ) {
+			subjectPosition = subjectPosition + 1;
+		else if ( pattern.getContent ( )[patternPosition] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ patternPosition ] ) ) {
 			 // check nonlinear variable
-			if ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ j ] ) ) {
-				auto setting = variablesSetting.find ( pattern.getContent ( )[ j ] );
+			if ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[ patternPosition ] ) ) {
+				auto setting = variablesSetting.find ( pattern.getContent ( )[ patternPosition ] );
 
-				if ( setting != variablesSetting.end ( ) && repeats.getContent ( )[ offset ].getSymbol ( ) != setting->second )
+				if ( setting != variablesSetting.end ( ) && repeats.getContent ( )[ subjectPosition ].getSymbol ( ) != setting->second )
 					break;
 
-				variablesSetting.insert ( std::make_pair ( pattern.getContent ( )[ j ], repeats.getContent( )[ offset ].getSymbol ( ) ) );
+				variablesSetting.insert ( std::make_pair ( pattern.getContent ( )[ patternPosition ], repeats.getContent( )[ subjectPosition ].getSymbol ( ) ) );
 			}
 
 			 // match of variable with subtree
-			offset = subjectSubtreeJumpTable[offset];
+			subjectPosition = subjectSubtreeJumpTable[subjectPosition];
 		} else
 			break;
 
-		j = j + 1;
+		patternPosition = patternPosition + 1;
 	}
 
-	return j;
+	return patternPosition;
 }
 
 } /* namespace exact */
diff --git a/alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.cpp b/alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.cpp
deleted file mode 100644
index 3b605ad2e4..0000000000
--- a/alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * BadCharacterShiftTable.cpp
- *
- *  Created on: 6. 3. 2018
- *	  Author: Michal Cvach
- */
-
-#include "QuickSearchBadCharacterShiftTable.h"
-#include <registration/AlgoRegistration.hpp>
-
-namespace {
-
-auto QuickSearchBadCharacterShiftTablePrefixRankedBarPattern = registration::AbstractRegister < tree::properties::QuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarPattern < > & > ( tree::properties::QuickSearchBadCharacterShiftTable::bcs );
-auto QuickSearchBadCharacterShiftTablePrefixRankedBarNonlinearPattern = registration::AbstractRegister < tree::properties::QuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarNonlinearPattern < > & > ( tree::properties::QuickSearchBadCharacterShiftTable::bcs );
-
-} /* namespace */
diff --git a/alib2algo/src/tree/properties/QuickSearchShiftTable.cpp b/alib2algo/src/tree/properties/QuickSearchShiftTable.cpp
new file mode 100644
index 0000000000..9fdd2eff0c
--- /dev/null
+++ b/alib2algo/src/tree/properties/QuickSearchShiftTable.cpp
@@ -0,0 +1,16 @@
+/*
+ * QuickSearchShiftTable.cpp
+ *
+ *  Created on: 6. 3. 2018
+ *	  Author: Michal Cvach
+ */
+
+#include "QuickSearchShiftTable.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto QuickSearchShiftTablePrefixRankedBarPattern = registration::AbstractRegister < tree::properties::QuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarPattern < > & > ( tree::properties::QuickSearchShiftTable::bcs );
+auto QuickSearchShiftTablePrefixRankedBarNonlinearPattern = registration::AbstractRegister < tree::properties::QuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarNonlinearPattern < > & > ( tree::properties::QuickSearchShiftTable::bcs );
+
+} /* namespace */
diff --git a/alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.h b/alib2algo/src/tree/properties/QuickSearchShiftTable.h
similarity index 86%
rename from alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.h
rename to alib2algo/src/tree/properties/QuickSearchShiftTable.h
index fe96b0c865..8ccf7fac77 100644
--- a/alib2algo/src/tree/properties/QuickSearchBadCharacterShiftTable.h
+++ b/alib2algo/src/tree/properties/QuickSearchShiftTable.h
@@ -1,12 +1,12 @@
 /*
- * BadCharacterShiftTable.h
+ * QuickSearchShiftTable.h
  *
  *  Created on: 6. 3. 2018
  *	  Author: Michal Cvach
  */
 
-#ifndef _ARBOLOGY_QUICK_SEARCH_BAD_CHARACTER_SHIFT_TABLE_H_
-#define _ARBOLOGY_QUICK_SEARCH_BAD_CHARACTER_SHIFT_TABLE_H_
+#ifndef _ARBOLOGY_QUICK_SEARCH_SHIFT_TABLE_H_
+#define _ARBOLOGY_QUICK_SEARCH_SHIFT_TABLE_H_
 
 #include <tree/ranked/PrefixRankedBarPattern.h>
 #include <tree/ranked/PrefixRankedBarNonlinearPattern.h>
@@ -23,7 +23,7 @@ namespace properties {
 /**
 * BadCharacterShiftTable for the QuickSearch algorithm for tree pattern matching.
 */
-class QuickSearchBadCharacterShiftTable {
+class QuickSearchShiftTable {
 public:
 	template < class SymbolType >
 	static ext::map < common::ranked_symbol < SymbolType >, size_t > bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern );
@@ -33,12 +33,12 @@ public:
 };
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > QuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > QuickSearchShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
 	return bcs ( tree::PrefixRankedBarNonlinearPattern < SymbolType > ( pattern ) );
 }
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > QuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > QuickSearchShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
 	const ext::set < common::ranked_symbol < SymbolType > > & alphabet = pattern.getAlphabet ( );
 
 	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs;
@@ -95,4 +95,4 @@ ext::map < common::ranked_symbol < SymbolType >, size_t > QuickSearchBadCharacte
 
 } /* namespace tree */
 
-#endif /* _ARBOLOGY_QUICK_SEARCH_BAD_CHARACTER_SHIFT_TABLE_H_ */
+#endif /* _ARBOLOGY_QUICK_SEARCH_SHIFT_TABLE_H_ */
diff --git a/alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.cpp b/alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.cpp
deleted file mode 100644
index ed40dab50f..0000000000
--- a/alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * ReversedQuickSearchBadCharacterShiftTable.cpp
- *
- *  Created on: 21. 3. 2018
- *	  Author: Michal Cvach
- */
-
-#include "ReversedQuickSearchBadCharacterShiftTable.h"
-#include <registration/AlgoRegistration.hpp>
-
-namespace {
-
-auto ReversedQuickSearchBadCharacterShiftTablePrefixRankedBarPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarPattern < > & > ( tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs );
-auto ReversedQuickSearchBadCharacterShiftTablePrefixRankedBarNonlinearPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarNonlinearPattern < > & > ( tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs );
-auto ReversedQuickSearchBadCharacterShiftTablePrefixRankedPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedPattern < > & > ( tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs );
-auto ReversedQuickSearchBadCharacterShiftTablePrefixRankedNonlinearPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchBadCharacterShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedNonlinearPattern < > & > ( tree::properties::ReversedQuickSearchBadCharacterShiftTable::bcs );
-
-} /* namespace */
diff --git a/alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.cpp b/alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.cpp
new file mode 100644
index 0000000000..946baf6937
--- /dev/null
+++ b/alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.cpp
@@ -0,0 +1,18 @@
+/*
+ * ReversedQuickSearchShiftTable.cpp
+ *
+ *  Created on: 21. 3. 2018
+ *	  Author: Michal Cvach
+ */
+
+#include "ReversedQuickSearchShiftTable.h"
+#include <registration/AlgoRegistration.hpp>
+
+namespace {
+
+auto ReversedQuickSearchShiftTablePrefixRankedBarPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarPattern < > & > ( tree::properties::ReversedQuickSearchShiftTable::bcs );
+auto ReversedQuickSearchShiftTablePrefixRankedBarNonlinearPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedBarNonlinearPattern < > & > ( tree::properties::ReversedQuickSearchShiftTable::bcs );
+auto ReversedQuickSearchShiftTablePrefixRankedPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedPattern < > & > ( tree::properties::ReversedQuickSearchShiftTable::bcs );
+auto ReversedQuickSearchShiftTablePrefixRankedNonlinearPattern = registration::AbstractRegister < tree::properties::ReversedQuickSearchShiftTable, ext::map < common::ranked_symbol < >, size_t >, const tree::PrefixRankedNonlinearPattern < > & > ( tree::properties::ReversedQuickSearchShiftTable::bcs );
+
+} /* namespace */
diff --git a/alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.h b/alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.h
similarity index 88%
rename from alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.h
rename to alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.h
index 364f25b6f9..7eb804fba5 100644
--- a/alib2algo/src/tree/properties/ReversedQuickSearchBadCharacterShiftTable.h
+++ b/alib2algo/src/tree/properties/ReversedQuickSearchShiftTable.h
@@ -1,12 +1,12 @@
 /*
- * ReversedQuickSearchBadCharacterShiftTable.h
+ * ReversedQuickSearchShiftTable.h
  *
  *  Created on: 21. 3. 2018
  *	  Author: Michal Cvach
  */
 
-#ifndef _ARBOLOGY_REVERSED_QUICK_SEARCH_BAD_CHARACTER_SHIFT_TABLE_H_
-#define _ARBOLOGY_REVERSED_QUICK_SEARCH_BAD_CHARACTER_SHIFT_TABLE_H_
+#ifndef _ARBOLOGY_REVERSED_QUICK_SEARCH_SHIFT_TABLE_H_
+#define _ARBOLOGY_REVERSED_QUICK_SEARCH_SHIFT_TABLE_H_
 
 #include <alib/set>
 #include <alib/map>
@@ -25,7 +25,7 @@ namespace properties {
 /**
  * BadCharacterShiftTable for the QuickSearch algorithm for tree pattern matching.
  */
-class ReversedQuickSearchBadCharacterShiftTable {
+class ReversedQuickSearchShiftTable {
 public:
 	template < class SymbolType >
 	static ext::map < common::ranked_symbol < SymbolType >, size_t > bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern );
@@ -39,12 +39,12 @@ public:
 };
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) {
 	return bcs ( tree::PrefixRankedBarNonlinearPattern < SymbolType > ( pattern ) );
 }
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) {
 	const ext::set < common::ranked_symbol < SymbolType > > & alphabet = pattern.getAlphabet ( );
 
 	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs;
@@ -91,12 +91,12 @@ ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchBad
 }
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchShiftTable::bcs ( const tree::PrefixRankedPattern < SymbolType > & pattern ) {
 	return bcs ( tree::PrefixRankedNonlinearPattern < SymbolType > ( pattern ) );
 }
 
 template < class SymbolType >
-ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchBadCharacterShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ) {
+ext::map < common::ranked_symbol < SymbolType >, size_t > ReversedQuickSearchShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ) {
 	const ext::set < common::ranked_symbol < SymbolType > > & alphabet = pattern.getAlphabet ( );
 
 	ext::map < common::ranked_symbol < SymbolType >, size_t > bcs;
diff --git a/alib2integrationtest/test-src/tests/arbologyTest.cpp b/alib2integrationtest/test-src/tests/arbologyTest.cpp
index 36f66b70c4..7414ff13f8 100644
--- a/alib2integrationtest/test-src/tests/arbologyTest.cpp
+++ b/alib2integrationtest/test-src/tests/arbologyTest.cpp
@@ -1,5 +1,6 @@
 #include <catch2/catch.hpp>
 #include <alib/vector>
+#include <alib/string>
 
 #include "testing/TimeoutAqlTest.hpp"
 #include "testing/TestFiles.hpp"
@@ -181,6 +182,8 @@ TEST_CASE ( "Arbology tests | nonlinear pattern ends", "[integration]" ) {
 
 TEST_CASE ( "Arbology tests | pattern", "[integration]" ) {
 	auto definition = GENERATE ( as < std::tuple < std::string, std::string, size_t > > ( ),
+		std::make_tuple ( "Exact Quantum Leap Using QuickSearch Shift And Border Array (Pattern PrefixRanked)",
+				"arbology::exact::QuantumLeapUsingQuickSearchShiftAndBorderArray (PrefixRankedTree)$subject (PrefixRankedPattern)<(tree::GeneralAlphabet::add $pattern <(tree::GeneralAlphabet::get $subject)) " + ext::to_string ( PATTERN_SIZE ), 1000 ),
 		std::make_tuple ( "Exact Pattern Matching Using Full And Linear Index (PrefixRankedBar)",
 				"arbology::indexing::FullAndLinearIndexConstruction (PrefixRankedBarTree) $subject | arbology::query::FullAndLinearIndexPatterns - (PrefixRankedBarPattern) $pattern", 1000 ),
 		std::make_tuple ( "Exact Pattern Matching Using Full And Linear Index (PrefixRanked)",
-- 
GitLab