diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp
index 023bf220786392865eee8086fad4d28c4b7c63d9..e2bd69b8cd42a237c4ef9b2357dbd5c21b849c5f 100644
--- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp
@@ -14,6 +14,8 @@ namespace exact {
 
 auto ExactTreePatternAutomatonPrefixRankedTree = registration::AbstractRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedTree < > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & > ( ExactTreePatternAutomaton::construct );
 
+auto ExactTreePatternAutomatonPrefixRankedBarTree = registration::AbstractRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedBarTree < > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & > ( ExactTreePatternAutomaton::construct );
+
 } /* namespace exact */
 
 } /* namespace arbology */
diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h
index c208a9d05b1c4220c3d4e6ace02fae27c7ccb10e..86569ee64e639066afe527282f29070dd6b92b4a 100644
--- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h
+++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h
@@ -9,7 +9,10 @@
 #define _EXACT_TREE_PATTERN_AUTOMATON_H__
 
 #include <alphabet/SubtreeWildcardSymbol.h>
+
 #include <tree/ranked/PrefixRankedTree.h>
+#include <tree/ranked/PrefixRankedBarTree.h>
+
 #include <automaton/PDA/InputDrivenNPDA.h>
 
 #include <alib/deque>
@@ -21,13 +24,64 @@ namespace exact {
 class ExactTreePatternAutomaton {
 public:
 	/**
-	 * Performs conversion.
-	 * @return left regular grammar equivalent to source automaton.
+	 * Construct a tree pattern automaton.
+	 * @return input driven automaton implementing an index for tree patterns.
+	 */
+	template < class SymbolType, class RankType >
+	static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & variablesBar );
+
+	/**
+	 * Construct a tree pattern automaton.
+	 * @return input driven automaton implementing an index for tree patterns.
 	 */
 	template < class SymbolType, class RankType >
 	static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard );
 };
 
+template < class SymbolType, class RankType >
+automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & variablesBar ) {
+	char S = alphabet::SubtreeWildcardSymbol::instance < char > ( );
+	automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( 0, S );
+
+	for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getAlphabet ( ) ) {
+		res.addInputSymbol ( symbol );
+		if ( tree.getBars ( ).count ( symbol ) )
+			res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, S ), ext::vector < char > { } );
+		else
+			res.setPushdownStoreOperation ( symbol, ext::vector < char > { }, ext::vector < char > ( 1, S ) );
+	}
+
+	res.addInputSymbol ( subtreeWildcard );
+	res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > ( 1, S ), ext::vector < char > { } );
+
+	res.addInputSymbol ( variablesBar );
+	res.setPushdownStoreOperation ( variablesBar, ext::vector < char > { }, ext::vector < char > ( 1, S ) );
+
+	unsigned i = 1;
+	ext::deque < unsigned > subtreeJumps;
+
+	for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getContent ( ) ) {
+		res.addState ( i );
+		res.addTransition ( i - 1, symbol, i );
+		res.addTransition ( 0, std::move ( symbol ), i );
+
+		if ( tree.getBars ( ).count ( symbol ) ) {
+			unsigned source = subtreeJumps.back ( );
+			subtreeJumps.pop_back ( );
+
+			res.addState ( ~0 - i );
+			res.addTransition ( source, subtreeWildcard, ~0 - i );
+			res.addTransition ( ~0 - i, variablesBar, i );
+		} else {
+			subtreeJumps.push_back ( i - 1 );
+		}
+
+		i++;
+	}
+
+	return res;
+}
+
 template < class SymbolType, class RankType >
 automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard ) {
 	char S = alphabet::SubtreeWildcardSymbol::instance < char > ( );