From 9b70641db8a7830204e076576cef3b066a2f5f3d Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 5 May 2016 15:23:44 +0200
Subject: [PATCH] more strict linearised tree representations

---
 .../arbology/exact/BadCharacterShiftTable.cpp |  19 +--
 .../src/arbology/exact/BoyerMooreHorspool.cpp |   4 +-
 ...neUsingBadCharacterShiftAndBorderArray.cpp |   2 +-
 .../exact/ExactPatternMatchingAutomaton.cpp   |  20 ++--
 .../exact/ExactSubtreeMatchingAutomaton.cpp   |   2 +-
 .../exact/ExactSubtreeRepeatsNaive.cpp        |   2 +-
 .../src/arbology/exact/KnuthMorrisPratt.cpp   |   4 +-
 .../exact/ReversedBadCharacterShiftTable.cpp  |  33 +++---
 .../exact/ReversedBoyerMooreHorspool.cpp      |   4 +-
 .../src/arbology/exact/SubtreeJumpTable.cpp   |   2 +-
 .../src/tree/common/TreeFromXMLParser.cpp     |  20 ++++
 alib2data/src/tree/common/TreeFromXMLParser.h |   2 +
 .../src/tree/common/TreeToXMLComposer.cpp     |  15 +++
 alib2data/src/tree/common/TreeToXMLComposer.h |   2 +
 .../tree/ranked/PrefixRankedBarPattern.cpp    | 111 +++++++++++-------
 .../src/tree/ranked/PrefixRankedBarPattern.h  |  29 +++--
 .../src/tree/ranked/PrefixRankedBarTree.cpp   |  73 ++++++++----
 .../src/tree/ranked/PrefixRankedBarTree.h     |  19 +--
 .../src/tree/ranked/PrefixRankedPattern.cpp   |   6 +-
 alib2data/src/tree/unranked/PrefixBarTree.cpp |  48 +++++---
 alib2data/src/tree/unranked/PrefixBarTree.h   |  12 +-
 .../test-src/automaton/AutomatonTest.cpp      |   4 +-
 alib2data/test-src/tree/PatternTest.cpp       |  21 ++--
 23 files changed, 282 insertions(+), 172 deletions(-)

diff --git a/alib2algo/src/arbology/exact/BadCharacterShiftTable.cpp b/alib2algo/src/arbology/exact/BadCharacterShiftTable.cpp
index 9fa0b5aa77..08ceca90ae 100644
--- a/alib2algo/src/arbology/exact/BadCharacterShiftTable.cpp
+++ b/alib2algo/src/arbology/exact/BadCharacterShiftTable.cpp
@@ -24,7 +24,7 @@ std::map < alphabet::RankedSymbol, size_t > BadCharacterShiftTable::bcs ( const
 
 	 // initialisation of bcs table to the size of the pattern
 	for ( const alphabet::RankedSymbol & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
 		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
 	}
@@ -40,11 +40,11 @@ std::map < alphabet::RankedSymbol, size_t > BadCharacterShiftTable::bcs ( const
 	// limit the shift by occurrence of the last variable
 
 	for ( const alphabet::RankedSymbol & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
 		size_t tmp = lastSOffset;
 
-		if ( symbol.getSymbol ( ) != pattern.getBarSymbol ( ) )
+		if ( ! pattern.getBars ( ).count ( symbol ) )
 			 // size of the smallest subtree containing given terminal depend
 			 // on the arity of the terminal
 			tmp += symbol.getRank ( ).getData ( ) * 2;
@@ -59,13 +59,14 @@ std::map < alphabet::RankedSymbol, size_t > BadCharacterShiftTable::bcs ( const
 	}
 
 	 // limit the shift by position of symbols within the pattern
-	for ( unsigned i = 0; i < pattern.getContent ( ).size ( ) - 1; i++ ) // last symbol is not concerned
-		if ( ( pattern.getContent ( )[i] != pattern.getSubtreeWildcard ( ) ) && ( pattern.getContent ( )[i].getSymbol ( ) != pattern.getVariablesBarSymbol ( ) ) ) {
-			size_t tmp = pattern.getContent ( ).size ( ) - i - 1;
+	for ( unsigned i = 0; i < pattern.getContent ( ).size ( ) - 1; i++ ) { // last symbol is not concerned
+		if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue;
 
-			if ( bcs[pattern.getContent ( )[i]] > tmp )
-				bcs[pattern.getContent ( )[i]] = tmp;
-		}
+		size_t tmp = pattern.getContent ( ).size ( ) - i - 1;
+
+		if ( bcs[pattern.getContent ( )[i]] > tmp )
+			bcs[pattern.getContent ( )[i]] = tmp;
+	}
 
 	return bcs;
 }
diff --git a/alib2algo/src/arbology/exact/BoyerMooreHorspool.cpp b/alib2algo/src/arbology/exact/BoyerMooreHorspool.cpp
index 92813d1fa4..1d0905226c 100644
--- a/alib2algo/src/arbology/exact/BoyerMooreHorspool.cpp
+++ b/alib2algo/src/arbology/exact/BoyerMooreHorspool.cpp
@@ -52,7 +52,7 @@ std::set < unsigned > BoyerMooreHorspool::match ( const tree::PrefixRankedBarTre
 				 // match of symbol
 				offset = offset - 1;
 				j = j - 1;
-			} else if ( ( pattern.getContent ( )[j].getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) && ( subject.getContent ( )[offset].getSymbol ( ) == pattern.getBarSymbol ( ) ) ) {
+			} else if ( ( pattern.getContent ( )[j] == pattern.getVariablesBar ( ) ) && ( pattern.getBars ( ).count ( subject.getContent ( )[offset] )) ) {
 				 // match of variable with subtree
 				offset = subjectSubtreeJumpTable[offset];
 				j = j - 2;
@@ -64,7 +64,7 @@ std::set < unsigned > BoyerMooreHorspool::match ( const tree::PrefixRankedBarTre
 		 // match was found
 		if ( j == 0 ) occ.insert ( offset );
 
-		 // shift heristics
+		 // shift heuristics
 		i += bcs[subject.getContent ( )[i + pattern.getContent ( ).size ( ) - 1]];
 	}
 
diff --git a/alib2algo/src/arbology/exact/DeadZoneUsingBadCharacterShiftAndBorderArray.cpp b/alib2algo/src/arbology/exact/DeadZoneUsingBadCharacterShiftAndBorderArray.cpp
index c0bb52488a..64d229e3d1 100644
--- a/alib2algo/src/arbology/exact/DeadZoneUsingBadCharacterShiftAndBorderArray.cpp
+++ b/alib2algo/src/arbology/exact/DeadZoneUsingBadCharacterShiftAndBorderArray.cpp
@@ -59,7 +59,7 @@ void DeadZoneUsingBadCharacterShiftAndBorderArray::match_rec ( std::set < unsign
 			 // match of symbol
 			offset++;
 			j++;
-		} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( subject.getContent ( )[offset].getSymbol ( ) != pattern.getBarSymbol ( ) ) ) {
+		} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( ! pattern.getBars ( ).count ( subject.getContent ( )[offset] )  ) ) {
 			 // match of variable with subtree
 			offset = subjectSubtreeJumpTable[offset];
 			j += 2;
diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
index 2ec5ce847f..a0cb96c0bb 100644
--- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
@@ -130,9 +130,9 @@ automaton::VisiblyPushdownNPDA ExactPatternMatchingAutomaton::construct ( const
 	res.addInitialState ( automaton::State ( 0 ) );
 
 	for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
-		if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) )
+		if ( pattern.getBars ( ).count ( symbol ) )
 			res.addReturnInputSymbol ( alphabet::Symbol { symbol } );
 		else
 			res.addCallInputSymbol ( alphabet::Symbol { symbol } );
@@ -141,9 +141,9 @@ automaton::VisiblyPushdownNPDA ExactPatternMatchingAutomaton::construct ( const
 	res.setStackAlphabet ( { alphabet::Symbol { alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK }, alphabet::symbolFrom ( 'T' ), alphabet::symbolFrom ( 'R' ) } );
 
 	for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
-		if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) )
+		if ( pattern.getBars ( ).count ( symbol ) )
 			res.addReturnTransition ( automaton::State ( 0 ), alphabet::Symbol { symbol }, alphabet::symbolFrom ( 'T' ), automaton::State ( 0 ) );
 		else
 			res.addCallTransition ( automaton::State ( 0 ), alphabet::Symbol { symbol }, automaton::State ( 0 ), alphabet::symbolFrom ( 'T' ) );
@@ -156,26 +156,26 @@ automaton::VisiblyPushdownNPDA ExactPatternMatchingAutomaton::construct ( const
 
 		if ( symbol == pattern.getSubtreeWildcard ( ) ) {
 			for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
-				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) || ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) ) ) continue;
+				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) || ( pattern.getBars ( ).count ( symbol ) ) ) continue;
 
 				res.addCallTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, automaton::State ( i ), alphabet::symbolFrom ( 'R' ) );
 			}
-		} else if ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) {
+		} else if ( symbol == pattern.getVariablesBar ( ) ) {
 			for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
-				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
-				if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) )
+				if ( pattern.getBars ( ).count ( symbol ) )
 					res.addReturnTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, alphabet::symbolFrom ( 'T' ), automaton::State ( i - 1 ) );
 				else
 					res.addCallTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, automaton::State ( i - 1 ), alphabet::symbolFrom ( 'T' ) );
 			}
 
 			for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
-				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) || ( symbol.getSymbol ( ) != pattern.getBarSymbol ( ) ) ) continue;
+				if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) || ( ! pattern.getBars ( ).count ( symbol ) ) ) continue;
 
 				res.addReturnTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, alphabet::symbolFrom ( 'R' ), automaton::State ( i ) );
 			}
-		} else if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) ) {
+		} else if ( pattern.getBars ( ).count ( symbol ) ) {
 			res.addReturnTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, alphabet::symbolFrom ( 'T' ), automaton::State ( i ) );
 		} else {
 			res.addCallTransition ( automaton::State ( i - 1 ), alphabet::Symbol { symbol }, automaton::State ( i ), alphabet::symbolFrom ( 'T' ) );
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
index af9fc4a11d..432f1c1638 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
@@ -59,7 +59,7 @@ automaton::InputDrivenNPDA ExactSubtreeMatchingAutomaton::construct ( const tree
 	for ( const alphabet::RankedSymbol & symbol : pattern.getAlphabet ( ) ) {
 		res.addInputSymbol ( alphabet::Symbol { symbol } );
 
-		if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) )
+		if ( pattern.getBars ( ).count ( symbol ) )
 			res.setPushdownStoreOperation ( alphabet::Symbol { symbol }, std::vector < alphabet::Symbol > { 1, alphabet::symbolFrom ( 'S' ) }, std::vector < alphabet::Symbol > { } );
 		else
 			res.setPushdownStoreOperation ( alphabet::Symbol { symbol }, std::vector < alphabet::Symbol > { }, std::vector < alphabet::Symbol > { 1, alphabet::symbolFrom ( 'S' ) } );
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeRepeatsNaive.cpp b/alib2algo/src/arbology/exact/ExactSubtreeRepeatsNaive.cpp
index 32e1ee6cae..5a8fee56a4 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeRepeatsNaive.cpp
+++ b/alib2algo/src/arbology/exact/ExactSubtreeRepeatsNaive.cpp
@@ -110,7 +110,7 @@ tree::PrefixRankedBarTree ExactSubtreeRepeatsNaive::repeats ( const tree::Prefix
 	std::map < std::pair < alphabet::RankedSymbol, std::vector < alphabet::RankedSymbol > >, int > data;
 
 	repeatsPrefixRankedBar ( tree.getContent ( ), res, data, minId, index );
-	return tree::PrefixRankedBarTree ( tree.getBarSymbol ( ), res );
+	return tree::PrefixRankedBarTree ( tree.getBars ( ), res );
 }
 
 auto ExactRepeatsNaivePrefixRankedBarTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::PrefixRankedBarTree, tree::PrefixRankedBarTree > ( ExactSubtreeRepeatsNaive::repeats );
diff --git a/alib2algo/src/arbology/exact/KnuthMorrisPratt.cpp b/alib2algo/src/arbology/exact/KnuthMorrisPratt.cpp
index 8e9f0b6aca..795f324a13 100644
--- a/alib2algo/src/arbology/exact/KnuthMorrisPratt.cpp
+++ b/alib2algo/src/arbology/exact/KnuthMorrisPratt.cpp
@@ -54,7 +54,7 @@ std::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedBarTree
 				 // match of symbol
 				offset++;
 				j++;
-			} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( subject.getContent ( )[offset].getSymbol ( ) != pattern.getBarSymbol ( ) ) ) {
+			} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( ! pattern.getBars ( ).count ( subject.getContent ( )[offset] ) ) ) {
 				 // match of variable with subtree
 				offset = subjectSubtreeJumpTable[offset];
 				j += 2;
@@ -66,7 +66,7 @@ std::set < unsigned > KnuthMorrisPratt::match ( const tree::PrefixRankedBarTree
 		 // match was found
 		if ( j >= pattern.getContent ( ).size ( ) ) occ.insert ( i );
 
-		 // shift heristics
+		 // shift heuristics
 		i += j - ba[j];
 	}
 
diff --git a/alib2algo/src/arbology/exact/ReversedBadCharacterShiftTable.cpp b/alib2algo/src/arbology/exact/ReversedBadCharacterShiftTable.cpp
index 810ed8417a..e8e345eb76 100644
--- a/alib2algo/src/arbology/exact/ReversedBadCharacterShiftTable.cpp
+++ b/alib2algo/src/arbology/exact/ReversedBadCharacterShiftTable.cpp
@@ -25,7 +25,7 @@ std::map < alphabet::RankedSymbol, size_t > ReversedBadCharacterShiftTable::bcs
 
 	 // initialisation of bcs table to the size of the pattern
 	for ( const alphabet::RankedSymbol & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
 		bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) );
 	}
@@ -35,17 +35,17 @@ std::map < alphabet::RankedSymbol, size_t > ReversedBadCharacterShiftTable::bcs
 	unsigned firstSBarOffset = pattern.getContent ( ).size ( ) + 1;
 
 	for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- )
-		if ( pattern.getContent ( )[i].getSymbol ( ) == pattern.getVariablesBarSymbol ( ) )
+		if ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) )
 			firstSBarOffset = i;
 
 	// limit the shift by occurrence of the last variable
 
 	for ( const alphabet::RankedSymbol & symbol : alphabet ) {
-		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol.getSymbol ( ) == pattern.getVariablesBarSymbol ( ) ) ) continue;
+		if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
 
 		size_t tmp = firstSBarOffset;
 
-		if ( symbol.getSymbol ( ) == pattern.getBarSymbol ( ) )
+		if ( pattern.getBars ( ).count ( symbol ) )
 			 // size of the smallest subtree containing given terminal depend
 			 // on the arity of the terminal
 			tmp += symbol.getRank ( ).getData ( ) * 2;
@@ -60,13 +60,14 @@ std::map < alphabet::RankedSymbol, size_t > ReversedBadCharacterShiftTable::bcs
 	}
 
 	 // 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.getContent ( )[i].getSymbol ( ) != pattern.getVariablesBarSymbol ( ) ) ) {
-			size_t tmp = i;
+	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
+		if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue;
 
-			if ( bcs[pattern.getContent ( )[i]] > tmp )
-				bcs[pattern.getContent ( )[i]] = tmp;
-		}
+		size_t tmp = i;
+
+		if ( bcs[pattern.getContent ( )[i]] > tmp )
+			bcs[pattern.getContent ( )[i]] = tmp;
+	}
 
 	return bcs;
 }
@@ -104,13 +105,13 @@ std::map < alphabet::RankedSymbol, size_t > ReversedBadCharacterShiftTable::bcs
 	}
 
 	 // 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 ( ) ) {
-			size_t tmp = i;
+	for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned
+		if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) continue;
+		size_t tmp = i;
 
-			if ( bcs[pattern.getContent ( )[i]] > tmp )
-				bcs[pattern.getContent ( )[i]] = tmp;
-		}
+		if ( bcs[pattern.getContent ( )[i]] > tmp )
+			bcs[pattern.getContent ( )[i]] = tmp;
+	}
 
 	return bcs;
 }
diff --git a/alib2algo/src/arbology/exact/ReversedBoyerMooreHorspool.cpp b/alib2algo/src/arbology/exact/ReversedBoyerMooreHorspool.cpp
index 7698cf64a6..c6ddbfb88e 100644
--- a/alib2algo/src/arbology/exact/ReversedBoyerMooreHorspool.cpp
+++ b/alib2algo/src/arbology/exact/ReversedBoyerMooreHorspool.cpp
@@ -54,7 +54,7 @@ std::set < unsigned > ReversedBoyerMooreHorspool::match ( const tree::PrefixRank
 				 // match of symbol
 				offset = offset + 1;
 				j = j + 1;
-			} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( subject.getContent ( )[offset].getSymbol ( ) != pattern.getBarSymbol ( ) ) ) {
+			} else if ( ( pattern.getContent ( )[j] == pattern.getSubtreeWildcard ( ) ) && ( ! pattern.getBars ( ).count ( subject.getContent ( )[offset] )  ) ) {
 				 // match of variable with subtree
 				offset = subjectSubtreeJumpTable[offset];
 				j = j + 2;
@@ -66,7 +66,7 @@ std::set < unsigned > ReversedBoyerMooreHorspool::match ( const tree::PrefixRank
 		 // match was found
 		if ( j == pattern.getContent ( ).size ( ) ) occ.insert ( i );
 
-		 // shift heristics
+		 // shift heuristics
 		i -= bcs[subject.getContent ( )[i]];
 	}
 
diff --git a/alib2algo/src/arbology/exact/SubtreeJumpTable.cpp b/alib2algo/src/arbology/exact/SubtreeJumpTable.cpp
index 96eb18c220..b8b151d01f 100644
--- a/alib2algo/src/arbology/exact/SubtreeJumpTable.cpp
+++ b/alib2algo/src/arbology/exact/SubtreeJumpTable.cpp
@@ -73,7 +73,7 @@ int SubtreeJumpTable::buildDataPointersBar ( std::vector < int > & res, const T
 	res.push_back ( 0 );
 	int index = begin + 1;
 
-	if ( subject.getContent ( )[begin].getSymbol ( ) != subject.getBarSymbol ( ) )
+	if ( ! subject.getBars ( ).count ( subject.getContent ( )[begin] ) )
 		for ( unsigned i = 0; i < subject.getContent ( )[begin].getRank ( ).getData ( ); i++ )
 			index = buildDataPointersBar ( res, subject, index );
 
diff --git a/alib2data/src/tree/common/TreeFromXMLParser.cpp b/alib2data/src/tree/common/TreeFromXMLParser.cpp
index 11aa1a1c3f..2cebc7588f 100644
--- a/alib2data/src/tree/common/TreeFromXMLParser.cpp
+++ b/alib2data/src/tree/common/TreeFromXMLParser.cpp
@@ -20,6 +20,18 @@ alphabet::Symbol TreeFromXMLParser::parseBar ( std::deque < sax::Token >::iterat
 	return bar;
 }
 
+std::set < alphabet::RankedSymbol > TreeFromXMLParser::parseBars ( std::deque < sax::Token >::iterator & input ) {
+	std::set < alphabet::RankedSymbol > bars;
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "bars" );
+
+	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
+		bars.insert ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "bars" );
+
+	return bars;
+}
+
 alphabet::Symbol TreeFromXMLParser::parseVariablesBar ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "variablesBar" );
 	alphabet::Symbol variablesBar ( alib::xmlApi < alphabet::Symbol >::parse ( input ) );
@@ -28,6 +40,14 @@ alphabet::Symbol TreeFromXMLParser::parseVariablesBar ( std::deque < sax::Token
 	return variablesBar;
 }
 
+alphabet::RankedSymbol TreeFromXMLParser::parseRankedVariablesBar ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "RankedVariablesBar" );
+	alphabet::RankedSymbol rankedVariablesBar ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) );
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "RankedVariablesBar" );
+
+	return rankedVariablesBar;
+}
+
 alphabet::Symbol TreeFromXMLParser::parseSubtreeWildcardSymbol ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "subtreeWildcard" );
 	alphabet::Symbol subtreeWildcard ( alib::xmlApi < alphabet::Symbol >::parse ( input ) );
diff --git a/alib2data/src/tree/common/TreeFromXMLParser.h b/alib2data/src/tree/common/TreeFromXMLParser.h
index 292bf38d22..490ab1100a 100644
--- a/alib2data/src/tree/common/TreeFromXMLParser.h
+++ b/alib2data/src/tree/common/TreeFromXMLParser.h
@@ -34,7 +34,9 @@ public:
 	static std::set < alphabet::Symbol > parseUnrankedAlphabet ( std::deque < sax::Token >::iterator & input );
 
 	static alphabet::Symbol parseBar ( std::deque < sax::Token >::iterator & input );
+	static std::set < alphabet::RankedSymbol > parseBars ( std::deque < sax::Token >::iterator & input );
 	static alphabet::Symbol parseVariablesBar ( std::deque < sax::Token >::iterator & input );
+	static alphabet::RankedSymbol parseRankedVariablesBar ( std::deque < sax::Token >::iterator & input );
 
 	static alphabet::Symbol parseSubtreeWildcardSymbol ( std::deque < sax::Token >::iterator & input );
 	static alphabet::RankedSymbol parseSubtreeWildcardRankedSymbol ( std::deque < sax::Token >::iterator & input );
diff --git a/alib2data/src/tree/common/TreeToXMLComposer.cpp b/alib2data/src/tree/common/TreeToXMLComposer.cpp
index 89bee9d20f..2ebc5b3e40 100644
--- a/alib2data/src/tree/common/TreeToXMLComposer.cpp
+++ b/alib2data/src/tree/common/TreeToXMLComposer.cpp
@@ -16,12 +16,27 @@ void TreeToXMLComposer::composeBar ( std::deque < sax::Token > & out, const alph
 	out.emplace_back ( sax::Token ( "bar", sax::Token::TokenType::END_ELEMENT ) );
 }
 
+void TreeToXMLComposer::composeBars ( std::deque < sax::Token > & out, const std::set < alphabet::RankedSymbol > & symbols ) {
+	out.emplace_back ( sax::Token ( "bars", sax::Token::TokenType::START_ELEMENT ) );
+
+	for ( const auto & symbol : symbols )
+		alib::xmlApi < alphabet::RankedSymbol >::compose ( out, symbol );
+
+	out.emplace_back ( sax::Token ( "bars", sax::Token::TokenType::END_ELEMENT ) );
+}
+
 void TreeToXMLComposer::composeVariablesBar ( std::deque < sax::Token > & out, const alphabet::Symbol & symbol ) {
 	out.emplace_back ( sax::Token ( "variablesBar", sax::Token::TokenType::START_ELEMENT ) );
 	alib::xmlApi < alphabet::Symbol >::compose ( out, symbol );
 	out.emplace_back ( sax::Token ( "variablesBar", sax::Token::TokenType::END_ELEMENT ) );
 }
 
+void TreeToXMLComposer::composeVariablesBar ( std::deque < sax::Token > & out, const alphabet::RankedSymbol & symbol ) {
+	out.emplace_back ( sax::Token ( "RankedVariablesBar", sax::Token::TokenType::START_ELEMENT ) );
+	alib::xmlApi < alphabet::RankedSymbol >::compose ( out, symbol );
+	out.emplace_back ( sax::Token ( "RankedVariablesBar", sax::Token::TokenType::END_ELEMENT ) );
+}
+
 void TreeToXMLComposer::composeSubtreeWildcard ( std::deque < sax::Token > & out, const alphabet::Symbol & symbol ) {
 	out.emplace_back ( sax::Token ( "subtreeWildcard", sax::Token::TokenType::START_ELEMENT ) );
 	alib::xmlApi < alphabet::Symbol >::compose ( out, symbol );
diff --git a/alib2data/src/tree/common/TreeToXMLComposer.h b/alib2data/src/tree/common/TreeToXMLComposer.h
index 67fbd8bc03..d28c280b4b 100644
--- a/alib2data/src/tree/common/TreeToXMLComposer.h
+++ b/alib2data/src/tree/common/TreeToXMLComposer.h
@@ -27,7 +27,9 @@ public:
 	static void composeAlphabet ( std::deque < sax::Token > & out, const std::set < alphabet::Symbol > & symbols );
 
 	static void composeBar ( std::deque < sax::Token > & out, const alphabet::Symbol & symbol );
+	static void composeBars ( std::deque < sax::Token > & out, const std::set < alphabet::RankedSymbol > & symbols );
 	static void composeVariablesBar ( std::deque < sax::Token > & out, const alphabet::Symbol & symbol );
+	static void composeVariablesBar ( std::deque < sax::Token > & out, const alphabet::RankedSymbol & symbol );
 
 	static void composeSubtreeWildcard ( std::deque < sax::Token > & out, const alphabet::Symbol & symbol );
 	static void composeSubtreeWildcard ( std::deque < sax::Token > & out, const alphabet::RankedSymbol & symbol );
diff --git a/alib2data/src/tree/ranked/PrefixRankedBarPattern.cpp b/alib2data/src/tree/ranked/PrefixRankedBarPattern.cpp
index 495ad4e013..bbdcc5dc1f 100644
--- a/alib2data/src/tree/ranked/PrefixRankedBarPattern.cpp
+++ b/alib2data/src/tree/ranked/PrefixRankedBarPattern.cpp
@@ -30,40 +30,45 @@
 
 namespace tree {
 
-PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( alphabet ) + std::set < alphabet::RankedSymbol > { subtreeWildcard } ), std::make_tuple ( subtreeWildcard ) ), bar ( std::move ( bar ) ), variablesBar ( std::move ( variablesBar ) ) {
+PrefixRankedBarPattern::PrefixRankedBarPattern ( std::set < alphabet::RankedSymbol > bars, alphabet::RankedSymbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, BarSymbols >, std::tuple < SubtreeWildcard, VariablesBarSymbol > > ( std::make_tuple ( std::move ( alphabet ), std::move ( bars ) ), std::make_tuple ( std::move ( subtreeWildcard ), std::move ( variablesBar ) ) ) {
 	setContent ( std::move ( data ) );
 }
 
-PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedBarPattern ( std::move ( bar ), std::move ( variablesBar ), std::move ( subtreeWildcard ), std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ), std::move ( data ) ) {
+PrefixRankedBarPattern::PrefixRankedBarPattern ( std::set < alphabet::RankedSymbol > bars, alphabet::RankedSymbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedBarPattern ( bars, variablesBar, subtreeWildcard, std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ) + bars + std::set < alphabet::RankedSymbol > { variablesBar, subtreeWildcard }, data ) {
 }
 
-PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, const RankedPattern & tree ) : std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > ( tree.getAlphabet ( ) ) ), std::make_tuple ( tree.getSubtreeWildcard ( ) ) ), bar ( std::move ( bar ) ), variablesBar ( std::move ( variablesBar ) ) {
-	toPrefixRankedBar ( tree.getRoot ( ) );
+PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol barBase, alphabet::RankedSymbol variablesBar, const RankedPattern & tree ) : PrefixRankedBarPattern ( computeBars ( tree.getAlphabet ( ), barBase ) + std::set < alphabet::RankedSymbol > { variablesBar }, variablesBar, tree.getSubtreeWildcard ( ), tree.getAlphabet ( ) + computeBars ( tree.getAlphabet ( ), barBase ) + std::set < alphabet::RankedSymbol > { variablesBar, tree.getSubtreeWildcard ( ) }, toPrefixRankedBar ( tree.getRoot ( ), tree.getSubtreeWildcard ( ), barBase, variablesBar ) ) {
+}
 
-	for ( const alphabet::RankedSymbol & symbol : tree.getAlphabet ( ) ) {
-		accessComponent < GeneralAlphabet > ( ).add ( alphabet::RankedSymbol ( this->bar, symbol.getRank ( ) ) );
-	}
+PrefixRankedBarPattern::PrefixRankedBarPattern ( const PrefixRankedBarTree & tree ) : PrefixRankedBarPattern ( tree.getBars() + std::set < alphabet::RankedSymbol > { alphabet::VariablesBarSymbol::RANKED_BAR_SYMBOL }, alphabet::VariablesBarSymbol::RANKED_BAR_SYMBOL, alphabet::SubtreeWildcardSymbol::RANKED_SUBTREE_WILDCARD_SYMBOL, tree.getAlphabet ( ) + std::set < alphabet::RankedSymbol > { alphabet::VariablesBarSymbol::RANKED_BAR_SYMBOL, alphabet::SubtreeWildcardSymbol::RANKED_SUBTREE_WILDCARD_SYMBOL }, tree.getContent ( ) ) {
+}
 
-	accessComponent < GeneralAlphabet > ( ).add ( alphabet::RankedSymbol ( this->variablesBar, tree.getSubtreeWildcard ( ).getRank ( ) ) );
+PrefixRankedBarPattern::PrefixRankedBarPattern ( const RankedPattern & tree ) : PrefixRankedBarPattern ( alphabet::BarSymbol::BAR_SYMBOL, alphabet::VariablesBarSymbol::RANKED_BAR_SYMBOL, tree ) {
 }
 
-PrefixRankedBarPattern::PrefixRankedBarPattern ( const PrefixRankedBarTree & tree ) : PrefixRankedBarPattern ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), alphabet::Symbol ( alphabet::VariablesBarSymbol::BAR ), alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 ), tree.getAlphabet ( ), tree.getContent ( ) ) {
+std::set < alphabet::RankedSymbol > PrefixRankedBarPattern::computeBars ( const std::set < alphabet::RankedSymbol > & alphabet, const alphabet::Symbol & barBase ) {
+	return std::transform < alphabet::RankedSymbol > ( alphabet, [&] ( const alphabet::RankedSymbol & symbol) {
+			return alphabet::RankedSymbol ( barBase, symbol.getRank ( ) );
+	} );
 }
 
-PrefixRankedBarPattern::PrefixRankedBarPattern ( const RankedPattern & tree ) : PrefixRankedBarPattern ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), alphabet::Symbol ( alphabet::VariablesBarSymbol::BAR ), tree ) {
+std::vector < alphabet::RankedSymbol > PrefixRankedBarPattern::toPrefixRankedBar ( const RankedNode & node, const alphabet::RankedSymbol & subtreeWildcard, const alphabet::Symbol & barBase, const alphabet::RankedSymbol & variablesBar ) {
+	std::vector < alphabet::RankedSymbol > res;
+	toPrefixRankedBar ( node, subtreeWildcard, barBase, variablesBar, res );
+	return res;
 }
 
-void PrefixRankedBarPattern::toPrefixRankedBar ( const RankedNode & node ) {
-	if ( node.getSymbol ( ) == accessElement < tree::SubtreeWildcard > ( ).get ( ) ) {
-		m_Data.push_back ( node.getSymbol ( ) );
-		m_Data.push_back ( alphabet::RankedSymbol ( variablesBar, node.getSymbol ( ).getRank ( ) ) );
+void PrefixRankedBarPattern::toPrefixRankedBar ( const RankedNode & node, const alphabet::RankedSymbol & subtreeWildcard, const alphabet::Symbol & barBase, const alphabet::RankedSymbol & variablesBar, std::vector < alphabet::RankedSymbol > & linearNotation ) {
+	if ( node.getSymbol ( ) == subtreeWildcard ) {
+		linearNotation.push_back ( node.getSymbol ( ) );
+		linearNotation.push_back ( variablesBar );
 	} else {
-		m_Data.push_back ( node.getSymbol ( ) );
+		linearNotation.push_back ( node.getSymbol ( ) );
 
 		for ( const std::smart_ptr < const RankedNode > & child : node.getChildren ( ) )
-			toPrefixRankedBar ( * child );
+			toPrefixRankedBar ( * child, subtreeWildcard, barBase, variablesBar, linearNotation );
 
-		m_Data.push_back ( alphabet::RankedSymbol ( bar, node.getSymbol ( ).getRank ( ) ) );
+		linearNotation.push_back ( alphabet::RankedSymbol ( barBase, node.getSymbol ( ).getRank ( ) ) );
 	}
 }
 
@@ -92,35 +97,27 @@ void PrefixRankedBarPattern::setContent ( std::vector < alphabet::RankedSymbol >
 	this->m_Data = std::move ( data );
 }
 
-const alphabet::Symbol & PrefixRankedBarPattern::getBarSymbol ( ) const {
-	return bar;
-}
-
-const alphabet::Symbol & PrefixRankedBarPattern::getVariablesBarSymbol ( ) const {
-	return variablesBar;
-}
-
 void PrefixRankedBarPattern::arityChecksum ( const std::vector < alphabet::RankedSymbol > & data ) {
 	int arityChecksumTerminals = 1;
 	int arityChecksumBars  = 1;
 	int arityChecksumTypes = 0;
 
 	for ( const alphabet::RankedSymbol & symbol : data ) {
-		if ( ( symbol.getSymbol ( ) != bar ) && ( symbol.getSymbol ( ) != variablesBar ) ) {
+		if ( getBars ( ).count ( symbol ) || symbol == getVariablesBar ( ) ) {
+			arityChecksumBars += symbol.getRank ( ).getData ( );
+			arityChecksumBars -= 1;
+			arityChecksumTypes -= 1;
+		} else {
 			arityChecksumTerminals += symbol.getRank ( ).getData ( );
 			arityChecksumTerminals -= 1;
 			arityChecksumTypes += 1;
-		} else {
-			arityChecksumBars  += symbol.getRank ( ).getData ( );
-			arityChecksumBars  -= 1;
-			arityChecksumTypes -= 1;
 		}
 	}
 
 	if ( ( arityChecksumTerminals != 0 ) || ( arityChecksumBars != 0 ) || ( arityChecksumTypes != 0 ) ) throw TreeException ( "The string does not form a tree" );
 
-	for ( unsigned i = 0; i < data.size ( ); ++i )
-		if ( ( data[i] == accessElement < tree::SubtreeWildcard > ( ).get ( ) ) && ( ( ( i + 1 ) == data.size ( ) ) || ( data[i + 1].getSymbol ( ) != variablesBar ) ) )
+	for ( unsigned i = 1; i < data.size ( ); ++i )
+		if ( data[i - 1] == getSubtreeWildcard ( ) && data[i] != getVariablesBar ( ) )
 			throw TreeException ( "Inconsystency of SubtreeWildcard and variablesBar" );
 
 }
@@ -130,8 +127,8 @@ bool PrefixRankedBarPattern::isEmpty ( ) const {
 }
 
 int PrefixRankedBarPattern::compare ( const PrefixRankedBarPattern & other ) const {
-	auto first = std::tie ( m_Data, getAlphabet(), getSubtreeWildcard(), bar, variablesBar );
-	auto second = std::tie ( other.m_Data, other.getAlphabet(), other.getSubtreeWildcard(), bar, variablesBar );
+	auto first = std::tie ( m_Data, getAlphabet(), getSubtreeWildcard(), getBars(), getVariablesBar() );
+	auto second = std::tie ( other.m_Data, other.getAlphabet(), other.getSubtreeWildcard(), other.getBars(), other.getVariablesBar() );
 
 	std::compare < decltype ( first ) > comp;
 
@@ -162,20 +159,20 @@ const std::string PrefixRankedBarPattern::XML_TAG_NAME = "PrefixRankedBarPattern
 
 PrefixRankedBarPattern PrefixRankedBarPattern::parse ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, PrefixRankedBarPattern::XML_TAG_NAME );
-	alphabet::Symbol bar = TreeFromXMLParser::parseBar ( input );
-	alphabet::Symbol variablesBarSymbol = TreeFromXMLParser::parseVariablesBar ( input );
+	std::set < alphabet::RankedSymbol > bars = TreeFromXMLParser::parseBars ( input );
+	alphabet::RankedSymbol variablesBarSymbol = TreeFromXMLParser::parseRankedVariablesBar ( input );
 	alphabet::RankedSymbol subtreeWildcardSymbol = TreeFromXMLParser::parseSubtreeWildcardRankedSymbol ( input );
 	std::set < alphabet::RankedSymbol > rankedAlphabet = TreeFromXMLParser::parseRankedAlphabet ( input );
 	std::vector < alphabet::RankedSymbol > data = TreeFromXMLParser::parseRankedContent ( input );
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, PrefixRankedBarPattern::XML_TAG_NAME );
 
-	return PrefixRankedBarPattern ( std::move ( bar ), std::move ( variablesBarSymbol ), std::move ( subtreeWildcardSymbol ), std::move ( rankedAlphabet ), std::move ( data ) );
+	return PrefixRankedBarPattern ( std::move ( bars ), std::move ( variablesBarSymbol ), std::move ( subtreeWildcardSymbol ), std::move ( rankedAlphabet ), std::move ( data ) );
 }
 
 void PrefixRankedBarPattern::compose ( std::deque < sax::Token > & out ) const {
 	out.emplace_back ( PrefixRankedBarPattern::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT );
-	TreeToXMLComposer::composeBar ( out, bar );
-	TreeToXMLComposer::composeVariablesBar ( out, variablesBar );
+	TreeToXMLComposer::composeBars ( out, getBars() );
+	TreeToXMLComposer::composeVariablesBar ( out, getVariablesBar() );
 	TreeToXMLComposer::composeSubtreeWildcard ( out, getSubtreeWildcard() );
 	TreeToXMLComposer::composeAlphabet ( out, getAlphabet() );
 	TreeToXMLComposer::composeContent ( out, m_Data );
@@ -191,7 +188,7 @@ bool tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alp
 	const tree::PrefixRankedBarPattern * pattern = static_cast < const tree::PrefixRankedBarPattern * > ( this );
 	const std::vector < alphabet::RankedSymbol > & content = pattern->getContent ( );
 
-	return std::find ( content.begin ( ), content.end ( ), symbol ) != content.end ( ) || pattern->accessElement < tree::SubtreeWildcard > ( ).get ( ) == symbol;
+	return std::find ( content.begin ( ), content.end ( ), symbol ) != content.end ( ) || pattern->accessElement < tree::VariablesBarSymbol > ( ).get ( ) == symbol || pattern->accessComponent < tree::BarSymbols > ( ).get ( ).count ( symbol ) || pattern->accessElement < tree::SubtreeWildcard > ( ).get ( ) == symbol;
 }
 
 template < >
@@ -203,13 +200,45 @@ template < >
 void tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::valid ( const alphabet::RankedSymbol & ) const {
 }
 
+template < >
+bool tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::BarSymbols >::used ( const alphabet::RankedSymbol & symbol ) const {
+	const tree::PrefixRankedBarPattern * pattern = static_cast < const tree::PrefixRankedBarPattern * > ( this );
+	const std::vector < alphabet::RankedSymbol > & content = pattern->getContent ( );
+
+	return std::find ( content.begin ( ), content.end ( ), symbol ) != content.end ( ) || pattern->accessElement < tree::VariablesBarSymbol > ( ).get ( ) == symbol;
+}
+
+template < >
+bool tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::BarSymbols >::available ( const alphabet::RankedSymbol & symbol ) const {
+	const tree::PrefixRankedBarPattern * pattern = static_cast < const tree::PrefixRankedBarPattern * > ( this );
+
+	return pattern->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
+}
+
+template < >
+void tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::BarSymbols >::valid ( const alphabet::RankedSymbol & ) const {
+}
+
 template < >
 bool tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::available ( const alphabet::RankedSymbol & symbol ) const {
 	return static_cast < const tree::PrefixRankedBarPattern * > ( this )->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
 }
 
 template < >
-void tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & ) const {
+void tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & symbol ) const {
+	if( symbol.getRank().getData() != 0 )
+		throw tree::TreeException ( "SubtreeWildcard symbol has nonzero arity" );
+}
+
+template < >
+bool tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::VariablesBarSymbol >::available ( const alphabet::RankedSymbol & symbol ) const {
+	return static_cast < const tree::PrefixRankedBarPattern * > ( this )->accessComponent < tree::BarSymbols > ( ).get ( ).count ( symbol );
+}
+
+template < >
+void tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::VariablesBarSymbol >::valid ( const alphabet::RankedSymbol & symbol ) const {
+	if( symbol.getRank().getData() != 0 )
+		throw tree::TreeException ( "VariablesBarSymbol has nonzero arity" );
 }
 
 } /* namespace std */
diff --git a/alib2data/src/tree/ranked/PrefixRankedBarPattern.h b/alib2data/src/tree/ranked/PrefixRankedBarPattern.h
index 8f5311c6f6..bb297428e3 100644
--- a/alib2data/src/tree/ranked/PrefixRankedBarPattern.h
+++ b/alib2data/src/tree/ranked/PrefixRankedBarPattern.h
@@ -22,23 +22,24 @@ class RankedPattern;
 class PrefixRankedBarTree;
 class GeneralAlphabet;
 class SubtreeWildcard;
+class BarSymbols;
+class VariablesBarSymbol;
 
 /**
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of LinearStringElement.
  */
-class PrefixRankedBarPattern : public RankedTreeBase, public std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > {
+class PrefixRankedBarPattern : public RankedTreeBase, public std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, BarSymbols >, std::tuple < SubtreeWildcard, VariablesBarSymbol > > {
 	std::vector < alphabet::RankedSymbol > m_Data;
 
-	alphabet::Symbol bar;
-	alphabet::Symbol variablesBar;
-
-	void toPrefixRankedBar ( const RankedNode & node );
+	static std::set < alphabet::RankedSymbol > computeBars ( const std::set < alphabet::RankedSymbol > & alphabet, const alphabet::Symbol & barBase );
+	static void toPrefixRankedBar ( const RankedNode & node, const alphabet::RankedSymbol & subtreeWildcard, const alphabet::Symbol & barBase, const alphabet::RankedSymbol & variablesBar, std::vector < alphabet::RankedSymbol > & linearNotation );
+	static std::vector < alphabet::RankedSymbol > toPrefixRankedBar ( const RankedNode & node, const alphabet::RankedSymbol & subtreeWildcard, const alphabet::Symbol & barBase, const alphabet::RankedSymbol & variablesBar );
 
 public:
-	explicit PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data );
-	explicit PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data );
-	explicit PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, const RankedPattern & tree );
+	explicit PrefixRankedBarPattern ( std::set < alphabet::RankedSymbol > bar, alphabet::RankedSymbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data );
+	explicit PrefixRankedBarPattern ( std::set < alphabet::RankedSymbol > bar, alphabet::RankedSymbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data );
+	explicit PrefixRankedBarPattern ( alphabet::Symbol barBase, alphabet::RankedSymbol variablesBar, const RankedPattern & tree );
 	explicit PrefixRankedBarPattern ( const PrefixRankedBarTree & tree );
 	explicit PrefixRankedBarPattern ( const RankedPattern & tree );
 
@@ -58,15 +59,19 @@ public:
 		accessComponent < GeneralAlphabet > ( ).add ( symbols );
 	}
 
+	const std::set < alphabet::RankedSymbol > & getBars ( ) const {
+		return accessComponent < BarSymbols > ( ).get ( );
+	}
+
 	const alphabet::RankedSymbol & getSubtreeWildcard ( ) const {
 		return accessElement < SubtreeWildcard > ( ).get ( );
 	}
 
-	void setContent ( std::vector < alphabet::RankedSymbol > data );
-
-	const alphabet::Symbol & getBarSymbol ( ) const;
+	const alphabet::RankedSymbol & getVariablesBar ( ) const {
+		return accessElement < VariablesBarSymbol > ( ).get ( );
+	}
 
-	const alphabet::Symbol & getVariablesBarSymbol ( ) const;
+	void setContent ( std::vector < alphabet::RankedSymbol > data );
 
 	void arityChecksum ( const std::vector < alphabet::RankedSymbol > & data );
 
diff --git a/alib2data/src/tree/ranked/PrefixRankedBarTree.cpp b/alib2data/src/tree/ranked/PrefixRankedBarTree.cpp
index ccb874c71e..93ecf8c81f 100644
--- a/alib2data/src/tree/ranked/PrefixRankedBarTree.cpp
+++ b/alib2data/src/tree/ranked/PrefixRankedBarTree.cpp
@@ -27,31 +27,38 @@
 
 namespace tree {
 
-PrefixRankedBarTree::PrefixRankedBarTree ( alphabet::Symbol bar, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : std::Components < PrefixRankedBarTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( alphabet ) ), std::tuple < > ( ) ), bar ( std::move ( bar ) ) {
+PrefixRankedBarTree::PrefixRankedBarTree ( std::set < alphabet::RankedSymbol > bars, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : std::Components < PrefixRankedBarTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, BarSymbols >, std::tuple < > > ( std::make_tuple ( std::move ( alphabet ), std::move ( bars ) ), std::tuple < > ( ) ) {
 	setContent ( std::move ( data ) );
 }
 
-PrefixRankedBarTree::PrefixRankedBarTree ( alphabet::Symbol bar, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedBarTree ( std::move ( bar ), std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ), std::move ( data ) ) {
+PrefixRankedBarTree::PrefixRankedBarTree ( std::set < alphabet::RankedSymbol > bars, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedBarTree ( bars, bars + std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ), data ) {
 }
 
-PrefixRankedBarTree::PrefixRankedBarTree ( alphabet::Symbol bar, const RankedTree & tree ) : std::Components < PrefixRankedBarTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > ( tree.getAlphabet ( ) ) ), std::tuple < > ( ) ), bar ( std::move ( bar ) ) {
-	toPrefixRankedBar ( tree.getRoot ( ) );
+PrefixRankedBarTree::PrefixRankedBarTree ( alphabet::Symbol barBase, const RankedTree & tree ) : PrefixRankedBarTree ( computeBars ( tree.getAlphabet ( ), barBase ), tree.getAlphabet ( ) + computeBars ( tree.getAlphabet ( ), barBase ), toPrefixRankedBar ( tree.getRoot ( ), barBase ) ) {
+}
 
-	for ( const alphabet::RankedSymbol & symbol : tree.getAlphabet ( ) ) {
-		accessComponent < GeneralAlphabet > ( ).add ( alphabet::RankedSymbol ( this->bar, symbol.getRank ( ) ) );
-	}
+PrefixRankedBarTree::PrefixRankedBarTree ( const RankedTree & tree ) : PrefixRankedBarTree ( alphabet::BarSymbol::BAR_SYMBOL, tree ) {
+}
+
+std::set < alphabet::RankedSymbol > PrefixRankedBarTree::computeBars ( const std::set < alphabet::RankedSymbol > & alphabet, const alphabet::Symbol & barBase ) {
+	return std::transform < alphabet::RankedSymbol > ( alphabet, [&] ( const alphabet::RankedSymbol & symbol) {
+			return alphabet::RankedSymbol ( barBase, symbol.getRank ( ) );
+	} );
 }
 
-PrefixRankedBarTree::PrefixRankedBarTree ( const RankedTree & tree ) : PrefixRankedBarTree ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), tree ) {
+std::vector < alphabet::RankedSymbol > PrefixRankedBarTree::toPrefixRankedBar ( const RankedNode & node, const alphabet::Symbol & barBase ) {
+	std::vector < alphabet::RankedSymbol > res;
+	toPrefixRankedBar ( node, barBase, res );
+	return res;
 }
 
-void PrefixRankedBarTree::toPrefixRankedBar ( const RankedNode & node ) {
-	m_Data.push_back ( node.getSymbol ( ) );
+void PrefixRankedBarTree::toPrefixRankedBar ( const RankedNode & node, const alphabet::Symbol & barBase, std::vector < alphabet::RankedSymbol > & linearNotation ) {
+	linearNotation.push_back ( node.getSymbol ( ) );
 
 	for ( const std::smart_ptr < const RankedNode > & child : node.getChildren ( ) )
-		toPrefixRankedBar ( * child );
+		toPrefixRankedBar ( * child, barBase, linearNotation );
 
-	m_Data.push_back ( alphabet::RankedSymbol ( bar, node.getSymbol ( ).getRank ( ) ) );
+	linearNotation.push_back ( alphabet::RankedSymbol ( barBase, node.getSymbol ( ).getRank ( ) ) );
 }
 
 RankedTreeBase * PrefixRankedBarTree::clone ( ) const {
@@ -66,10 +73,6 @@ const std::vector < alphabet::RankedSymbol > & PrefixRankedBarTree::getContent (
 	return this->m_Data;
 }
 
-const alphabet::Symbol & PrefixRankedBarTree::getBarSymbol ( ) const {
-	return bar;
-}
-
 void PrefixRankedBarTree::setContent ( std::vector < alphabet::RankedSymbol > data ) {
 	arityChecksum ( data );
 
@@ -89,14 +92,14 @@ void PrefixRankedBarTree::arityChecksum ( const std::vector < alphabet::RankedSy
 	int arityChecksumTypes = 0;
 
 	for ( const alphabet::RankedSymbol & symbol : data ) {
-		if ( symbol.getSymbol ( ) != bar ) {
+		if ( getBars ( ).count ( symbol ) ) {
+			arityChecksumBars += symbol.getRank ( ).getData ( );
+			arityChecksumBars -= 1;
+			arityChecksumTypes -= 1;
+		} else {
 			arityChecksumTerminals += symbol.getRank ( ).getData ( );
 			arityChecksumTerminals -= 1;
 			arityChecksumTypes += 1;
-		} else {
-			arityChecksumBars  += symbol.getRank ( ).getData ( );
-			arityChecksumBars  -= 1;
-			arityChecksumTypes -= 1;
 		}
 	}
 
@@ -108,8 +111,8 @@ bool PrefixRankedBarTree::isEmpty ( ) const {
 }
 
 int PrefixRankedBarTree::compare ( const PrefixRankedBarTree & other ) const {
-	auto first = std::tie ( m_Data, getAlphabet(), bar );
-	auto second = std::tie ( other.m_Data, other.getAlphabet(), bar );
+	auto first = std::tie ( m_Data, getAlphabet(), getBars() );
+	auto second = std::tie ( other.m_Data, other.getAlphabet(), other.getBars() );
 
 	std::compare < decltype ( first ) > comp;
 
@@ -140,17 +143,17 @@ const std::string PrefixRankedBarTree::XML_TAG_NAME = "PrefixRankedBarTree";
 
 PrefixRankedBarTree PrefixRankedBarTree::parse ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, PrefixRankedBarTree::XML_TAG_NAME );
-	alphabet::Symbol bar = TreeFromXMLParser::parseBar ( input );
+	std::set < alphabet::RankedSymbol > bars = TreeFromXMLParser::parseBars ( input );
 	std::set < alphabet::RankedSymbol > rankedAlphabet = TreeFromXMLParser::parseRankedAlphabet ( input );
 	std::vector < alphabet::RankedSymbol > data = TreeFromXMLParser::parseRankedContent ( input );
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, PrefixRankedBarTree::XML_TAG_NAME );
 
-	return PrefixRankedBarTree ( std::move ( bar ), std::move ( rankedAlphabet ), std::move ( data ) );
+	return PrefixRankedBarTree ( std::move ( bars ), std::move ( rankedAlphabet ), std::move ( data ) );
 }
 
 void PrefixRankedBarTree::compose ( std::deque < sax::Token > & out ) const {
 	out.emplace_back ( PrefixRankedBarTree::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT );
-	TreeToXMLComposer::composeBar ( out, bar );
+	TreeToXMLComposer::composeBars ( out, getBars() );
 	TreeToXMLComposer::composeAlphabet ( out, getAlphabet() );
 	TreeToXMLComposer::composeContent ( out, m_Data );
 	out.emplace_back ( PrefixRankedBarTree::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT );
@@ -176,6 +179,24 @@ template < >
 void tree::PrefixRankedBarTree::Component < tree::PrefixRankedBarTree, alphabet::RankedSymbol, tree::GeneralAlphabet >::valid ( const alphabet::RankedSymbol & ) const {
 }
 
+template < >
+bool tree::PrefixRankedBarTree::Component < tree::PrefixRankedBarTree, alphabet::RankedSymbol, tree::BarSymbols >::used ( const alphabet::RankedSymbol & symbol ) const {
+	const std::vector < alphabet::RankedSymbol > & content = static_cast < const tree::PrefixRankedBarTree * > ( this )->getContent ( );
+
+	return std::find ( content.begin ( ), content.end ( ), symbol ) != content.end ( );
+}
+
+template < >
+bool tree::PrefixRankedBarTree::Component < tree::PrefixRankedBarTree, alphabet::RankedSymbol, tree::BarSymbols >::available ( const alphabet::RankedSymbol & symbol ) const {
+	const tree::PrefixRankedBarTree * tree = static_cast < const tree::PrefixRankedBarTree * > ( this );
+
+	return tree->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
+}
+
+template < >
+void tree::PrefixRankedBarTree::Component < tree::PrefixRankedBarTree, alphabet::RankedSymbol, tree::BarSymbols >::valid ( const alphabet::RankedSymbol & ) const {
+}
+
 } /* namespace std */
 
 namespace alib {
diff --git a/alib2data/src/tree/ranked/PrefixRankedBarTree.h b/alib2data/src/tree/ranked/PrefixRankedBarTree.h
index dac39c2fe6..7f90319748 100644
--- a/alib2data/src/tree/ranked/PrefixRankedBarTree.h
+++ b/alib2data/src/tree/ranked/PrefixRankedBarTree.h
@@ -20,22 +20,23 @@ namespace tree {
 
 class RankedTree;
 class GeneralAlphabet;
+class BarSymbols;
 
 /**
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of LinearStringElement.
  */
-class PrefixRankedBarTree : public RankedTreeBase, public std::Components < PrefixRankedBarTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > {
+class PrefixRankedBarTree : public RankedTreeBase, public std::Components < PrefixRankedBarTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, BarSymbols >, std::tuple < > > {
 	std::vector < alphabet::RankedSymbol > m_Data;
 
-	alphabet::Symbol bar;
-
-	void toPrefixRankedBar ( const RankedNode & node );
+	static std::set < alphabet::RankedSymbol > computeBars ( const std::set < alphabet::RankedSymbol > & alphabet, const alphabet::Symbol & barBase );
+	static void toPrefixRankedBar ( const RankedNode & node, const alphabet::Symbol & barBase, std::vector < alphabet::RankedSymbol > & linearNotation );
+	static std::vector < alphabet::RankedSymbol > toPrefixRankedBar ( const RankedNode & node, const alphabet::Symbol & barBase );
 
 public:
-	explicit PrefixRankedBarTree ( alphabet::Symbol bar, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data );
-	explicit PrefixRankedBarTree ( alphabet::Symbol bar, std::vector < alphabet::RankedSymbol > data );
-	explicit PrefixRankedBarTree ( alphabet::Symbol bar, const RankedTree & tree );
+	explicit PrefixRankedBarTree ( std::set < alphabet::RankedSymbol > bars, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data );
+	explicit PrefixRankedBarTree ( std::set < alphabet::RankedSymbol > bars, std::vector < alphabet::RankedSymbol > data );
+	explicit PrefixRankedBarTree ( alphabet::Symbol barBase, const RankedTree & tree );
 	explicit PrefixRankedBarTree ( const RankedTree & tree );
 
 	virtual RankedTreeBase * clone ( ) const;
@@ -54,7 +55,9 @@ public:
 		accessComponent < GeneralAlphabet > ( ).add ( symbols );
 	}
 
-	const alphabet::Symbol & getBarSymbol ( ) const;
+	const std::set < alphabet::RankedSymbol > & getBars ( ) const {
+		return accessComponent < BarSymbols > ( ).get ( );
+	}
 
 	void setContent ( std::vector < alphabet::RankedSymbol > data );
 
diff --git a/alib2data/src/tree/ranked/PrefixRankedPattern.cpp b/alib2data/src/tree/ranked/PrefixRankedPattern.cpp
index dcd4c392a8..1ba063ce60 100644
--- a/alib2data/src/tree/ranked/PrefixRankedPattern.cpp
+++ b/alib2data/src/tree/ranked/PrefixRankedPattern.cpp
@@ -35,7 +35,7 @@ PrefixRankedPattern::PrefixRankedPattern ( alphabet::RankedSymbol subtreeWildcar
 PrefixRankedPattern::PrefixRankedPattern ( alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedPattern ( std::move ( subtreeWildcard ), std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ), std::move ( data ) ) {
 }
 
-PrefixRankedPattern::PrefixRankedPattern ( const PrefixRankedTree & tree ) : PrefixRankedPattern ( alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 ), tree.getAlphabet ( ), tree.getContent ( ) ) {
+PrefixRankedPattern::PrefixRankedPattern ( const PrefixRankedTree & tree ) : PrefixRankedPattern ( alphabet::SubtreeWildcardSymbol::RANKED_SUBTREE_WILDCARD_SYMBOL, tree.getAlphabet ( ), tree.getContent ( ) ) {
 }
 
 PrefixRankedPattern::PrefixRankedPattern ( const RankedPattern & tree ) : std::Components < PrefixRankedPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > ( tree.getAlphabet ( ) ) ), std::make_tuple ( tree.getSubtreeWildcard ( ) ) ) {
@@ -169,7 +169,9 @@ bool tree::PrefixRankedPattern::Element < tree::PrefixRankedPattern, alphabet::R
 }
 
 template < >
-void tree::PrefixRankedPattern::Element < tree::PrefixRankedPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & ) const {
+void tree::PrefixRankedPattern::Element < tree::PrefixRankedPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & symbol ) const {
+	if( symbol.getRank().getData() != 0 )
+		throw tree::TreeException ( "SubtreeWildcard symbol has nonzero arity" );
 }
 
 } /* namespace std */
diff --git a/alib2data/src/tree/unranked/PrefixBarTree.cpp b/alib2data/src/tree/unranked/PrefixBarTree.cpp
index be0f5ed2e0..3165342c2c 100644
--- a/alib2data/src/tree/unranked/PrefixBarTree.cpp
+++ b/alib2data/src/tree/unranked/PrefixBarTree.cpp
@@ -27,27 +27,32 @@
 
 namespace tree {
 
-PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, std::set < alphabet::Symbol > alphabet, std::vector < alphabet::Symbol > data ) : std::Components < PrefixBarTree, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( alphabet ) ), std::tuple < > ( ) ), bar ( std::move ( bar ) ) {
+PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, std::set < alphabet::Symbol > alphabet, std::vector < alphabet::Symbol > data ) : std::Components < PrefixBarTree, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < BarSymbol > > ( std::make_tuple ( std::move ( alphabet ) ), std::make_tuple ( std::move ( bar ) ) ) {
 	setContent ( std::move ( data ) );
 }
 
-PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, std::vector < alphabet::Symbol > data ) : PrefixBarTree ( std::move ( bar ), std::set < alphabet::Symbol > ( data.begin ( ), data.end ( ) ), std::move ( data ) ) {
+PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, std::vector < alphabet::Symbol > data ) : PrefixBarTree ( std::move ( bar ), std::set < alphabet::Symbol > ( data.begin ( ), data.end ( ) ) + std::set < alphabet::Symbol > { bar }, std::move ( data ) ) {
 }
 
-PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, const UnrankedTree & tree ) : std::Components < PrefixBarTree, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::set < alphabet::Symbol > ( tree.getAlphabet ( ) ) + std::set < alphabet::Symbol > { bar } ), std::tuple < > ( ) ), bar ( bar ) {
-	toPrefixBar ( tree.getRoot ( ) );
+PrefixBarTree::PrefixBarTree ( alphabet::Symbol bar, const UnrankedTree & tree ) : PrefixBarTree ( bar, tree.getAlphabet ( ) + std::set < alphabet::Symbol > { bar }, toPrefixBar ( tree.getRoot ( ), bar ) ) {
 }
 
-PrefixBarTree::PrefixBarTree ( const UnrankedTree & tree ) : PrefixBarTree ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), tree ) {
+PrefixBarTree::PrefixBarTree ( const UnrankedTree & tree ) : PrefixBarTree ( alphabet::BarSymbol::BAR_SYMBOL, tree ) {
 }
 
-void PrefixBarTree::toPrefixBar ( const UnrankedNode & node ) {
-	m_Data.push_back ( node.getSymbol ( ) );
+std::vector < alphabet::Symbol > PrefixBarTree::toPrefixBar ( const UnrankedNode & node, const alphabet::Symbol & bar ) {
+	std::vector < alphabet::Symbol > res;
+	toPrefixBar ( node, bar, res );
+	return res;
+}
+
+void PrefixBarTree::toPrefixBar ( const UnrankedNode & node, const alphabet::Symbol & bar, std::vector < alphabet::Symbol > & linearNotation ) {
+	linearNotation.push_back ( node.getSymbol ( ) );
 
 	for ( const std::smart_ptr < const UnrankedNode > & child : node.getChildren ( ) )
-		toPrefixBar ( * child );
+		toPrefixBar ( * child, bar, linearNotation );
 
-	m_Data.push_back ( bar );
+	linearNotation.push_back ( bar );
 }
 
 UnrankedTreeBase * PrefixBarTree::clone ( ) const {
@@ -62,10 +67,6 @@ const std::vector < alphabet::Symbol > & PrefixBarTree::getContent ( ) const {
 	return this->m_Data;
 }
 
-const alphabet::Symbol & PrefixBarTree::getBarSymbol ( ) const {
-	return bar;
-}
-
 void PrefixBarTree::setContent ( std::vector < alphabet::Symbol > data ) {
 	arityChecksum ( data );
 
@@ -83,10 +84,10 @@ void PrefixBarTree::arityChecksum ( const std::vector < alphabet::Symbol > & dat
 	int arityChecksumTypes = 0;
 
 	for ( const alphabet::Symbol & symbol : data ) {
-		if ( symbol != bar )
-			arityChecksumTypes += 1;
-		else
+		if ( symbol == getBar ( ) )
 			arityChecksumTypes -= 1;
+		else
+			arityChecksumTypes += 1;
 	}
 
 	if ( arityChecksumTypes != 0 ) throw TreeException ( "The string does not form a tree" );
@@ -97,8 +98,8 @@ bool PrefixBarTree::isEmpty ( ) const {
 }
 
 int PrefixBarTree::compare ( const PrefixBarTree & other ) const {
-	auto first = std::tie ( m_Data, getAlphabet ( ) );
-	auto second = std::tie ( other.m_Data, other.getAlphabet ( ) );
+	auto first = std::tie ( m_Data, getAlphabet ( ), getBar ( ) );
+	auto second = std::tie ( other.m_Data, other.getAlphabet ( ), other.getBar ( ) );
 
 	std::compare < decltype ( first ) > comp;
 
@@ -139,7 +140,7 @@ PrefixBarTree PrefixBarTree::parse ( std::deque < sax::Token >::iterator & input
 
 void PrefixBarTree::compose ( std::deque < sax::Token > & out ) const {
 	out.emplace_back ( PrefixBarTree::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT );
-	TreeToXMLComposer::composeBar ( out, bar );
+	TreeToXMLComposer::composeBar ( out, getBar ( ) );
 	TreeToXMLComposer::composeAlphabet ( out, getAlphabet ( ) );
 	TreeToXMLComposer::composeContent ( out, m_Data );
 	out.emplace_back ( PrefixBarTree::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT );
@@ -165,6 +166,15 @@ template < >
 void tree::PrefixBarTree::Component < tree::PrefixBarTree, alphabet::Symbol, tree::GeneralAlphabet >::valid ( const alphabet::Symbol & ) const {
 }
 
+template < >
+bool tree::PrefixBarTree::Element < tree::PrefixBarTree, alphabet::Symbol, tree::BarSymbol >::available ( const alphabet::Symbol & symbol ) const {
+	return static_cast < const tree::PrefixBarTree * > ( this )->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
+}
+
+template < >
+void tree::PrefixBarTree::Element < tree::PrefixBarTree, alphabet::Symbol, tree::BarSymbol >::valid ( const alphabet::Symbol & ) const {
+}
+
 } /* namespace std */
 
 namespace alib {
diff --git a/alib2data/src/tree/unranked/PrefixBarTree.h b/alib2data/src/tree/unranked/PrefixBarTree.h
index f1b3cf51c6..b0c45eb06e 100644
--- a/alib2data/src/tree/unranked/PrefixBarTree.h
+++ b/alib2data/src/tree/unranked/PrefixBarTree.h
@@ -20,17 +20,17 @@ namespace tree {
 
 class UnrankedTree;
 class GeneralAlphabet;
+class BarSymbol;
 
 /**
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of LinearStringElement.
  */
-class PrefixBarTree : public UnrankedTreeBase, public std::Components < PrefixBarTree, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < > > {
+class PrefixBarTree : public UnrankedTreeBase, public std::Components < PrefixBarTree, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < BarSymbol > > {
 	std::vector < alphabet::Symbol > m_Data;
 
-	alphabet::Symbol bar;
-
-	void toPrefixBar ( const UnrankedNode & node );
+	static std::vector < alphabet::Symbol > toPrefixBar ( const UnrankedNode & node, const alphabet::Symbol & bar );
+	static void toPrefixBar ( const UnrankedNode & node, const alphabet::Symbol & bar, std::vector < alphabet::Symbol > & linearNotation );
 
 public:
 	explicit PrefixBarTree ( alphabet::Symbol bar, std::set < alphabet::Symbol > alphabet, std::vector < alphabet::Symbol > data );
@@ -54,7 +54,9 @@ public:
 		accessComponent < GeneralAlphabet > ( ).add ( symbols );
 	}
 
-	const alphabet::Symbol & getBarSymbol ( ) const;
+	const alphabet::Symbol & getBar ( ) const {
+		return accessElement < BarSymbol > ( ).get ( );
+	}
 
 	void setContent ( std::vector < alphabet::Symbol > data );
 
diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp
index bccaf25f02..d0dc1297a2 100644
--- a/alib2data/test-src/automaton/AutomatonTest.cpp
+++ b/alib2data/test-src/automaton/AutomatonTest.cpp
@@ -217,12 +217,12 @@ void AutomatonTest::testNPDATransitions() {
 }
 
 void AutomatonTest::testRHPDATransitions() {
-	automaton::RealTimeHeightDeterministicNPDA automaton{alphabet::Symbol(alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK)};
+	automaton::RealTimeHeightDeterministicNPDA automaton{alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK_SYMBOL};
 	automaton.setStates({automaton::State(1), automaton::State(2), automaton::State(3)});
 	automaton.setInitialStates({automaton::State(1)});
 
 	automaton.setInputAlphabet({alphabet::symbolFrom("a"), alphabet::symbolFrom("b")});
-	automaton.setStackAlphabet({alphabet::Symbol(alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK), alphabet::symbolFrom("X"), alphabet::symbolFrom("Y")});
+	automaton.setStackAlphabet({alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK_SYMBOL, alphabet::symbolFrom("X"), alphabet::symbolFrom("Y")});
 
 	automaton.addCallTransition(automaton::State(1), alphabet::symbolFrom("a"), automaton::State(2), alphabet::symbolFrom("X"));
 	automaton.addCallTransition(automaton::State(2), automaton::State(3), alphabet::symbolFrom("X"));
diff --git a/alib2data/test-src/tree/PatternTest.cpp b/alib2data/test-src/tree/PatternTest.cpp
index d1140fa74b..4a50f37b7d 100644
--- a/alib2data/test-src/tree/PatternTest.cpp
+++ b/alib2data/test-src/tree/PatternTest.cpp
@@ -69,10 +69,10 @@ void PatternTest::testRankedPatternParser() {
 	const alphabet::Symbol uS { alphabet::SubtreeWildcardSymbol {} };
 	const std::set<alphabet::Symbol> ualphabet {ua, ub, uc, uS};
 
-	tree::UnrankedNode * unode3 = new tree::UnrankedNode(uc, {});
-	tree::UnrankedNode * unode4 = new tree::UnrankedNode(uS, {});
-	tree::UnrankedNode * unode2 = new tree::UnrankedNode(ub, {unode3});
-	tree::UnrankedNode unode1(ua, {unode2, unode4});
+	tree::UnrankedNode unode3(uc, {});
+	tree::UnrankedNode unode4(uS, {});
+	tree::UnrankedNode unode2(ub, {std::make_smart<tree::UnrankedNode>(std::move(unode3))});
+	tree::UnrankedNode unode1(ua, {std::make_smart<tree::UnrankedNode>(std::move(unode2)), std::make_smart<tree::UnrankedNode>(std::move(unode4))});
 
 	tree::UnrankedPattern tree2(uS, ualphabet, std::move(unode1));
 
@@ -89,10 +89,10 @@ void PatternTest::testUnrankedPatternParser() {
 	const alphabet::Symbol S { alphabet::SubtreeWildcardSymbol {} };
 	const std::set<alphabet::Symbol> alphabet {a, b, c, S};
 
-	tree::UnrankedNode * node3 = new tree::UnrankedNode(c, {});
-	tree::UnrankedNode * node4 = new tree::UnrankedNode(S, {});
-	tree::UnrankedNode * node2 = new tree::UnrankedNode(b, {node3});
-	tree::UnrankedNode node1(a, {node2, node4});
+	tree::UnrankedNode node3(c, {});
+	tree::UnrankedNode node4(S, {});
+	tree::UnrankedNode node2(b, {std::make_smart<tree::UnrankedNode>(std::move(node3))});
+	tree::UnrankedNode node1(a, {std::make_smart<tree::UnrankedNode>(std::move(node2)), std::make_smart<tree::UnrankedNode>(std::move(node4))});
 
 	tree::UnrankedPattern tree(S, alphabet, std::move(node1));
 
@@ -163,9 +163,6 @@ void PatternTest::testPrefixRankedPatternParser() {
 }
 
 void PatternTest::testPrefixRankedBarPatternParser() {
-	const alphabet::Symbol bar{alphabet::BarSymbol{}};
-	const alphabet::Symbol variablesBar{alphabet::VariablesBarSymbol{}};
-
 	const alphabet::RankedSymbol a ('a', 2);
 	const alphabet::RankedSymbol b ('b', 1);
 	const alphabet::RankedSymbol c ('c', 0);
@@ -179,7 +176,7 @@ void PatternTest::testPrefixRankedBarPatternParser() {
 	tree::RankedNode node1(a, {std::make_smart<tree::RankedNode>(std::move(node2)), std::make_smart<tree::RankedNode>(std::move(node4))});
 
 	tree::RankedPattern pattern(S, alphabet, std::move(node1));
-	tree::PrefixRankedBarPattern pattern2(bar, variablesBar, pattern);
+	tree::PrefixRankedBarPattern pattern2(alphabet::BarSymbol::BAR_SYMBOL, alphabet::VariablesBarSymbol::RANKED_BAR_SYMBOL, pattern);
 
 	CPPUNIT_ASSERT( pattern2 == pattern2 );
 	{
-- 
GitLab