From 44db95beb19f602a99a18342fdb552034e2165ee Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 7 Oct 2016 15:32:13 +0200
Subject: [PATCH] template UnrankedNonlinearPattern tree

---
 alib2data/src/tree/TreeFeatures.h             |   1 +
 .../tree/ranked/RankedNonlinearPattern.cpp    |   2 +-
 .../src/tree/ranked/RankedNonlinearPattern.h  |   2 +-
 .../unranked/UnrankedNonlinearPattern.cpp     | 105 +---------
 .../tree/unranked/UnrankedNonlinearPattern.h  | 192 ++++++++++++++----
 alib2str/src/tree/TreeFromStringParser.cpp    |   4 +-
 6 files changed, 161 insertions(+), 145 deletions(-)

diff --git a/alib2data/src/tree/TreeFeatures.h b/alib2data/src/tree/TreeFeatures.h
index 9299e0700a..1e62045889 100644
--- a/alib2data/src/tree/TreeFeatures.h
+++ b/alib2data/src/tree/TreeFeatures.h
@@ -45,6 +45,7 @@ template < class SymbolType = alphabet::Symbol >
 class UnrankedTree;
 template < class SymbolType = alphabet::Symbol >
 class UnrankedPattern;
+template < class SymbolType = alphabet::Symbol >
 class UnrankedNonlinearPattern;
 template < class SymbolType = alphabet::Symbol >
 class PrefixBarTree;
diff --git a/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp b/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp
index 5b306cb953..1eaf762b1a 100644
--- a/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp
+++ b/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp
@@ -36,7 +36,7 @@ RankedNonlinearPattern::RankedNonlinearPattern ( std::ranked_symbol < > subtreeW
 RankedNonlinearPattern::RankedNonlinearPattern ( std::ranked_symbol < > subtreeWildcard, std::tree < std::ranked_symbol < > > pattern ) : RankedNonlinearPattern ( subtreeWildcard, std::set < std::ranked_symbol < > > { }, pattern ) {
 }
 
-RankedNonlinearPattern::RankedNonlinearPattern ( const UnrankedNonlinearPattern & other ) : RankedNonlinearPattern ( std::ranked_symbol < > ( other.getSubtreeWildcard ( ), 0 ), TreeAuxiliary::toRankedTree ( other.getContent ( ) ) ) {
+RankedNonlinearPattern::RankedNonlinearPattern ( const UnrankedNonlinearPattern < > & other ) : RankedNonlinearPattern ( std::ranked_symbol < > ( other.getSubtreeWildcard ( ), 0 ), TreeAuxiliary::toRankedTree ( other.getContent ( ) ) ) {
 }
 
 RankedTreeBase * RankedNonlinearPattern::clone ( ) const {
diff --git a/alib2data/src/tree/ranked/RankedNonlinearPattern.h b/alib2data/src/tree/ranked/RankedNonlinearPattern.h
index 7437dc02ce..82f79a8492 100644
--- a/alib2data/src/tree/ranked/RankedNonlinearPattern.h
+++ b/alib2data/src/tree/ranked/RankedNonlinearPattern.h
@@ -48,7 +48,7 @@ public:
 	explicit RankedNonlinearPattern ( std::ranked_symbol < > subtreeWildcard, std::set < std::ranked_symbol < > > nonlinearVariables, std::set < std::ranked_symbol < > > alphabet, std::tree < std::ranked_symbol < > > pattern );
 	explicit RankedNonlinearPattern ( std::ranked_symbol < > subtreeWildcard, std::set < std::ranked_symbol < > > nonlinearVariables, std::tree < std::ranked_symbol < > > pattern );
 	explicit RankedNonlinearPattern ( std::ranked_symbol < > subtreeWildcard, std::tree < std::ranked_symbol < > > pattern );
-	explicit RankedNonlinearPattern ( const UnrankedNonlinearPattern & other );
+	explicit RankedNonlinearPattern ( const UnrankedNonlinearPattern < > & other );
 
 	/**
 	 * @return Root node of the regular expression pattern
diff --git a/alib2data/src/tree/unranked/UnrankedNonlinearPattern.cpp b/alib2data/src/tree/unranked/UnrankedNonlinearPattern.cpp
index b0447f9f9a..8a5a88a346 100644
--- a/alib2data/src/tree/unranked/UnrankedNonlinearPattern.cpp
+++ b/alib2data/src/tree/unranked/UnrankedNonlinearPattern.cpp
@@ -6,115 +6,16 @@
  */
 
 #include "UnrankedNonlinearPattern.h"
-
-#include <iostream>
-#include <algorithm>
-#include <sstream>
-
-#include "../ranked/RankedNonlinearPattern.h"
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/TreeFromXMLParser.h"
-#include "../common/TreeToXMLComposer.h"
-#include "../common/TreeAuxiliary.h"
 #include "../Tree.h"
 #include "../UnrankedTreeWrapper.h"
 #include <object/Object.h>
 #include <core/xmlApi.hpp>
 #include <core/castApi.hpp>
 
-namespace tree {
-
-UnrankedNonlinearPattern::UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::set < alphabet::Symbol > nonlinearVariables, std::set < alphabet::Symbol > alphabet, std::tree < alphabet::Symbol > pattern ) : std::Components < UnrankedNonlinearPattern, alphabet::Symbol, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( alphabet ), std::move ( nonlinearVariables ) ), std::make_tuple ( std::move ( subtreeWildcard ) ) ), content ( std::move ( pattern ) ) {
-	checkAlphabet ( content );
-}
-
-UnrankedNonlinearPattern::UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::set < alphabet::Symbol > nonlinearVariables, std::tree < alphabet::Symbol > pattern ) : UnrankedNonlinearPattern ( subtreeWildcard, nonlinearVariables, std::set < alphabet::Symbol > ( pattern.prefix_begin ( ), pattern.prefix_end ( ) ) + nonlinearVariables + std::set < alphabet::Symbol > { subtreeWildcard }, pattern ) {
-}
-
-UnrankedNonlinearPattern::UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::tree < alphabet::Symbol > pattern ) : UnrankedNonlinearPattern ( subtreeWildcard, std::set < alphabet::Symbol > { }, pattern ) {
-}
-
-UnrankedNonlinearPattern::UnrankedNonlinearPattern ( const RankedNonlinearPattern & other ) : UnrankedNonlinearPattern ( other.getSubtreeWildcard ( ).getSymbol ( ), TreeAuxiliary::unrankSymbols ( other.getAlphabet ( ) ), TreeAuxiliary::toUnrankedTree ( other.getContent ( ) ) ) {
-}
-
-UnrankedTreeBase * UnrankedNonlinearPattern::clone ( ) const {
-	return new UnrankedNonlinearPattern ( * this );
-}
-
-UnrankedTreeBase * UnrankedNonlinearPattern::plunder ( ) && {
-	return new UnrankedNonlinearPattern ( std::move ( * this ) );
-}
-
-const std::tree < alphabet::Symbol > & UnrankedNonlinearPattern::getContent ( ) const {
-	return content;
-}
-
-void UnrankedNonlinearPattern::checkAlphabet ( const std::tree < alphabet::Symbol > & data ) const {
-	std::set < alphabet::Symbol > minimalAlphabet ( data.prefix_begin ( ), data.prefix_end ( ) );
-	std::set < alphabet::Symbol > unknownSymbols;
-	std::set_difference ( minimalAlphabet.begin ( ), minimalAlphabet.end ( ), getAlphabet().begin ( ), getAlphabet().end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) );
-
-	if ( unknownSymbols.size ( ) > 0 )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
-}
-
-void UnrankedNonlinearPattern::setTree ( std::tree < alphabet::Symbol > pattern ) {
-	checkAlphabet ( pattern );
-
-	this->content = std::move ( pattern );
-}
-
-void UnrankedNonlinearPattern::operator >>( std::ostream & out ) const {
-	out << "(UnrankedNonlinearPattern " << this->content << ")";
-}
-
-int UnrankedNonlinearPattern::compare ( const UnrankedNonlinearPattern & other ) const {
-	auto first = std::tie ( content, getAlphabet(), getSubtreeWildcard(), getNonlinearVariables() );
-	auto second = std::tie ( other.content, other.getAlphabet(), other.getSubtreeWildcard(), getNonlinearVariables() );
-
-	std::compare < decltype ( first ) > comp;
-
-	return comp ( first, second );
-}
-
-void UnrankedNonlinearPattern::nicePrint ( std::ostream & os ) const {
-	content.nicePrint ( os );
-}
-
-UnrankedNonlinearPattern::operator std::string ( ) const {
-	std::stringstream ss;
-	ss << * this;
-	return ss.str ( );
-}
-
-UnrankedNonlinearPattern UnrankedNonlinearPattern::parse ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, UnrankedNonlinearPattern::getXmlTagName() );
-	alphabet::Symbol subtreeWildcardSymbol = TreeFromXMLParser::parseSubtreeWildcardSymbol ( input );
-	std::set < alphabet::Symbol > nonlinearVariables = TreeFromXMLParser::parseUnrankedNonlinearVariables ( input );
-	std::set < alphabet::Symbol > rankedAlphabet = TreeFromXMLParser::parseUnrankedAlphabet ( input );
-	std::tree < alphabet::Symbol > root = TreeFromXMLParser::parseUnrankedTreeContent ( input );
-	UnrankedNonlinearPattern tree ( std::move ( subtreeWildcardSymbol ), std::move ( nonlinearVariables ), std::move ( rankedAlphabet ), std::move ( root ) );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, UnrankedNonlinearPattern::getXmlTagName() );
-	return tree;
-}
-
-void UnrankedNonlinearPattern::compose ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( UnrankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
-	TreeToXMLComposer::composeSubtreeWildcard ( out, getSubtreeWildcard ( ) );
-	TreeToXMLComposer::composeNonlinearVariables ( out, getNonlinearVariables ( ) );
-	TreeToXMLComposer::composeAlphabet ( out, getAlphabet ( ) );
-	TreeToXMLComposer::composeContent ( out, getContent ( ) );
-	out.emplace_back ( UnrankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
-}
-
-} /* namespace tree */
-
 namespace alib {
 
-auto UnrankedNonlinearPatternParserRegister = xmlApi < ::tree::Tree >::ParserRegister < ::tree::UnrankedNonlinearPattern > ( );
-auto UnrankedNonlinearPatternParserRegister2 = xmlApi < ::tree::UnrankedTreeWrapper >::ParserRegister < ::tree::UnrankedNonlinearPattern > ( );
-auto UnrankedNonlinearPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < ::tree::UnrankedNonlinearPattern > ( );
+auto UnrankedNonlinearPatternParserRegister = xmlApi < ::tree::Tree >::ParserRegister < ::tree::UnrankedNonlinearPattern < > > ( );
+auto UnrankedNonlinearPatternParserRegister2 = xmlApi < ::tree::UnrankedTreeWrapper >::ParserRegister < ::tree::UnrankedNonlinearPattern < > > ( );
+auto UnrankedNonlinearPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < ::tree::UnrankedNonlinearPattern < > > ( );
 
 } /* namespace alib */
diff --git a/alib2data/src/tree/unranked/UnrankedNonlinearPattern.h b/alib2data/src/tree/unranked/UnrankedNonlinearPattern.h
index 58369e8294..3db9e53262 100644
--- a/alib2data/src/tree/unranked/UnrankedNonlinearPattern.h
+++ b/alib2data/src/tree/unranked/UnrankedNonlinearPattern.h
@@ -11,11 +11,19 @@
 #include <string>
 #include <set>
 #include <tree>
+#include <iostream>
+#include <algorithm>
+#include <sstream>
+
 #include <core/components.hpp>
+#include <sax/FromXMLParserHelper.h>
 
 #include "../TreeFeatures.h"
 #include "../TreeException.h"
 #include "../UnrankedTreeBase.h"
+#include "../common/TreeFromXMLParser.h"
+#include "../common/TreeToXMLComposer.h"
+#include "../common/TreeAuxiliary.h"
 
 namespace tree {
 
@@ -27,59 +35,60 @@ class NonlinearAlphabet;
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a pattern of RegExpElement.
  */
-class UnrankedNonlinearPattern : public UnrankedTreeBase, public std::Components < UnrankedNonlinearPattern, alphabet::Symbol, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > {
-	std::tree < alphabet::Symbol > content;
+template < class SymbolType >
+class UnrankedNonlinearPattern : public UnrankedTreeBase, public std::Components < UnrankedNonlinearPattern < SymbolType >, SymbolType, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > {
+	std::tree < SymbolType > content;
 
-	void checkAlphabet ( const std::tree < alphabet::Symbol > & pattern ) const;
+	void checkAlphabet ( const std::tree < SymbolType > & pattern ) const;
 
 public:
 	/**
-	 * @copydoc std::tree < alphabet::Symbol >::clone() const
+	 * @copydoc std::tree < SymbolType >::clone() const
 	 */
 	virtual UnrankedTreeBase * clone ( ) const;
 
 	/**
-	 * @copydoc std::tree < alphabet::Symbol >::plunder() const
+	 * @copydoc std::tree < SymbolType >::plunder() const
 	 */
 	virtual UnrankedTreeBase * plunder ( ) &&;
 
-	explicit UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::set < alphabet::Symbol > nonlinearVariables, std::set < alphabet::Symbol > alphabet, std::tree < alphabet::Symbol > pattern );
-	explicit UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::set < alphabet::Symbol > nonlinearVariables, std::tree < alphabet::Symbol > pattern );
-	explicit UnrankedNonlinearPattern ( alphabet::Symbol subtreeWildcard, std::tree < alphabet::Symbol > pattern );
+	explicit UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::set < SymbolType > nonlinearVariables, std::set < SymbolType > alphabet, std::tree < SymbolType > pattern );
+	explicit UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::set < SymbolType > nonlinearVariables, std::tree < SymbolType > pattern );
+	explicit UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::tree < SymbolType > pattern );
 	explicit UnrankedNonlinearPattern ( const RankedNonlinearPattern & other );
 
 	/**
 	 * @return Content of the pattern
 	 */
-	const std::tree < alphabet::Symbol > & getContent ( ) const;
+	const std::tree < SymbolType > & getContent ( ) const;
 
-	const std::set < alphabet::Symbol > & getAlphabet ( ) const {
-		return accessComponent < GeneralAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getAlphabet ( ) const {
+		return this->template accessComponent < GeneralAlphabet > ( ).get ( );
 	}
 
-	void extendAlphabet ( const std::set < alphabet::Symbol > & symbols ) {
-		accessComponent < GeneralAlphabet > ( ).add ( symbols );
+	void extendAlphabet ( const std::set < SymbolType > & symbols ) {
+		this->template accessComponent < GeneralAlphabet > ( ).add ( symbols );
 	}
 
-	const alphabet::Symbol & getSubtreeWildcard ( ) const {
-		return accessElement < SubtreeWildcard > ( ).get ( );
+	const SymbolType & getSubtreeWildcard ( ) const {
+		return this->template accessElement < SubtreeWildcard > ( ).get ( );
 	}
 
-	const std::set < alphabet::Symbol > & getNonlinearVariables ( ) const {
-		return accessComponent < NonlinearAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getNonlinearVariables ( ) const {
+		return this->template accessComponent < NonlinearAlphabet > ( ).get ( );
 	}
 
 	/**
 	 * Sets the root node of the regular expression pattern
 	 * @param pattern root node to set
 	 */
-	void setTree ( std::tree < alphabet::Symbol > pattern );
+	void setTree ( std::tree < SymbolType > pattern );
 
 	/**
 	 * Removes symbol from the alphabet of symbol available in the regular expression
 	 * @param symbol removed symbol from the alphabet
 	 */
-	bool removeSymbolFromAlphabet ( const alphabet::Symbol & symbol );
+	bool removeSymbolFromAlphabet ( const SymbolType & symbol );
 
 	/**
 	 * Prints XML representation of the pattern to the output stream.
@@ -113,50 +122,155 @@ public:
 
 } /* namespace tree */
 
+#include "../ranked/RankedNonlinearPattern.h"
+
+namespace tree {
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType >::UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::set < SymbolType > nonlinearVariables, std::set < SymbolType > alphabet, std::tree < SymbolType > pattern ) : std::Components < UnrankedNonlinearPattern, SymbolType, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( alphabet ), std::move ( nonlinearVariables ) ), std::make_tuple ( std::move ( subtreeWildcard ) ) ), content ( std::move ( pattern ) ) {
+	checkAlphabet ( content );
+}
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType >::UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::set < SymbolType > nonlinearVariables, std::tree < SymbolType > pattern ) : UnrankedNonlinearPattern ( subtreeWildcard, nonlinearVariables, std::set < SymbolType > ( pattern.prefix_begin ( ), pattern.prefix_end ( ) ) + nonlinearVariables + std::set < SymbolType > { subtreeWildcard }, pattern ) {
+}
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType >::UnrankedNonlinearPattern ( SymbolType subtreeWildcard, std::tree < SymbolType > pattern ) : UnrankedNonlinearPattern ( subtreeWildcard, std::set < SymbolType > { }, pattern ) {
+}
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType >::UnrankedNonlinearPattern ( const RankedNonlinearPattern & other ) : UnrankedNonlinearPattern ( other.getSubtreeWildcard ( ).getSymbol ( ), TreeAuxiliary::unrankSymbols ( other.getAlphabet ( ) ), TreeAuxiliary::toUnrankedTree ( other.getContent ( ) ) ) {
+}
+
+template < class SymbolType >
+UnrankedTreeBase * UnrankedNonlinearPattern < SymbolType >::clone ( ) const {
+	return new UnrankedNonlinearPattern ( * this );
+}
+
+template < class SymbolType >
+UnrankedTreeBase * UnrankedNonlinearPattern < SymbolType >::plunder ( ) && {
+	return new UnrankedNonlinearPattern ( std::move ( * this ) );
+}
+
+template < class SymbolType >
+const std::tree < SymbolType > & UnrankedNonlinearPattern < SymbolType >::getContent ( ) const {
+	return content;
+}
+
+template < class SymbolType >
+void UnrankedNonlinearPattern < SymbolType >::checkAlphabet ( const std::tree < SymbolType > & data ) const {
+	std::set < SymbolType > minimalAlphabet ( data.prefix_begin ( ), data.prefix_end ( ) );
+	std::set < SymbolType > unknownSymbols;
+	std::set_difference ( minimalAlphabet.begin ( ), minimalAlphabet.end ( ), getAlphabet().begin ( ), getAlphabet().end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) );
+
+	if ( unknownSymbols.size ( ) > 0 )
+		throw exception::CommonException ( "Input symbols not in the alphabet." );
+}
+
+template < class SymbolType >
+void UnrankedNonlinearPattern < SymbolType >::setTree ( std::tree < SymbolType > pattern ) {
+	checkAlphabet ( pattern );
+
+	this->content = std::move ( pattern );
+}
+
+template < class SymbolType >
+void UnrankedNonlinearPattern < SymbolType >::operator >>( std::ostream & out ) const {
+	out << "(UnrankedNonlinearPattern " << this->content << ")";
+}
+
+template < class SymbolType >
+int UnrankedNonlinearPattern < SymbolType >::compare ( const UnrankedNonlinearPattern & other ) const {
+	auto first = std::tie ( content, getAlphabet(), getSubtreeWildcard(), getNonlinearVariables() );
+	auto second = std::tie ( other.content, other.getAlphabet(), other.getSubtreeWildcard(), getNonlinearVariables() );
+
+	std::compare < decltype ( first ) > comp;
+
+	return comp ( first, second );
+}
+
+template < class SymbolType >
+void UnrankedNonlinearPattern < SymbolType >::nicePrint ( std::ostream & os ) const {
+	content.nicePrint ( os );
+}
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template < class SymbolType >
+UnrankedNonlinearPattern < SymbolType > UnrankedNonlinearPattern < SymbolType >::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, UnrankedNonlinearPattern::getXmlTagName() );
+	SymbolType subtreeWildcardSymbol = TreeFromXMLParser::parseSubtreeWildcardSymbol ( input );
+	std::set < SymbolType > nonlinearVariables = TreeFromXMLParser::parseUnrankedNonlinearVariables ( input );
+	std::set < SymbolType > rankedAlphabet = TreeFromXMLParser::parseUnrankedAlphabet ( input );
+	std::tree < SymbolType > root = TreeFromXMLParser::parseUnrankedTreeContent ( input );
+	UnrankedNonlinearPattern < SymbolType > tree ( std::move ( subtreeWildcardSymbol ), std::move ( nonlinearVariables ), std::move ( rankedAlphabet ), std::move ( root ) );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, UnrankedNonlinearPattern::getXmlTagName() );
+	return tree;
+}
+
+template < class SymbolType >
+void UnrankedNonlinearPattern < SymbolType >::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( UnrankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
+	TreeToXMLComposer::composeSubtreeWildcard ( out, getSubtreeWildcard ( ) );
+	TreeToXMLComposer::composeNonlinearVariables ( out, getNonlinearVariables ( ) );
+	TreeToXMLComposer::composeAlphabet ( out, getAlphabet ( ) );
+	TreeToXMLComposer::composeContent ( out, getContent ( ) );
+	out.emplace_back ( UnrankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
+}
+
+} /* namespace tree */
+
 namespace std {
 
-template < >
-class ComponentConstraint< ::tree::UnrankedNonlinearPattern, alphabet::Symbol, ::tree::GeneralAlphabet > {
+template < class SymbolType >
+class ComponentConstraint< ::tree::UnrankedNonlinearPattern < SymbolType >, SymbolType, ::tree::GeneralAlphabet > {
 public:
-	static bool used ( const ::tree::UnrankedNonlinearPattern & pattern, const alphabet::Symbol & symbol ) {
-		const std::tree<alphabet::Symbol>& content = pattern.getContent ( );
-		return std::find(content.prefix_begin(), content.prefix_end(), symbol) != content.prefix_end() || pattern.accessElement < ::tree::SubtreeWildcard > ( ).get ( ) == symbol || pattern.accessComponent < ::tree::NonlinearAlphabet > ( ).get ( ).count ( symbol );
+	static bool used ( const ::tree::UnrankedNonlinearPattern < SymbolType > & pattern, const SymbolType & symbol ) {
+		const std::tree<SymbolType>& content = pattern.getContent ( );
+		return std::find(content.prefix_begin(), content.prefix_end(), symbol) != content.prefix_end() || pattern.template accessElement < ::tree::SubtreeWildcard > ( ).get ( ) == symbol || pattern.template accessComponent < ::tree::NonlinearAlphabet > ( ).get ( ).count ( symbol );
 	}
 
-	static bool available ( const ::tree::UnrankedNonlinearPattern &, const alphabet::Symbol & ) {
+	static bool available ( const ::tree::UnrankedNonlinearPattern < SymbolType > &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const ::tree::UnrankedNonlinearPattern &, const alphabet::Symbol & ) {
+	static void valid ( const ::tree::UnrankedNonlinearPattern < SymbolType > &, const SymbolType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< ::tree::UnrankedNonlinearPattern, alphabet::Symbol, ::tree::NonlinearAlphabet > {
+template < class SymbolType >
+class ComponentConstraint< ::tree::UnrankedNonlinearPattern < SymbolType >, SymbolType, ::tree::NonlinearAlphabet > {
 public:
-	static bool used ( const ::tree::UnrankedNonlinearPattern &, const alphabet::Symbol & ) {
+	static bool used ( const ::tree::UnrankedNonlinearPattern < SymbolType > &, const SymbolType & ) {
 		return false;
 	}
 
-	static bool available ( const ::tree::UnrankedNonlinearPattern & pattern, const alphabet::Symbol & symbol ) {
-		return pattern.accessComponent < ::tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
+	static bool available ( const ::tree::UnrankedNonlinearPattern < SymbolType > & pattern, const SymbolType & symbol ) {
+		return pattern.template accessComponent < ::tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
 	}
 
-	static void valid ( const ::tree::UnrankedNonlinearPattern & pattern, const alphabet::Symbol & symbol) {
-		if ( pattern.accessElement < ::tree::SubtreeWildcard > ( ).get ( ) == symbol )
+	static void valid ( const ::tree::UnrankedNonlinearPattern < SymbolType > & pattern, const SymbolType & symbol) {
+		if ( pattern.template accessElement < ::tree::SubtreeWildcard > ( ).get ( ) == symbol )
 			throw ::tree::TreeException ( "Symbol " + std::to_string ( symbol ) + "cannot be set as nonlinear variable since it is already subtree wildcard" );
 	}
 };
 
-template < >
-class ElementConstraint< ::tree::UnrankedNonlinearPattern, alphabet::Symbol, ::tree::SubtreeWildcard > {
+template < class SymbolType >
+class ElementConstraint< ::tree::UnrankedNonlinearPattern < SymbolType >, SymbolType, ::tree::SubtreeWildcard > {
 public:
-	static bool available ( const ::tree::UnrankedNonlinearPattern & pattern, const alphabet::Symbol & symbol ) {
-		return pattern.accessComponent < ::tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
+	static bool available ( const ::tree::UnrankedNonlinearPattern < SymbolType > & pattern, const SymbolType & symbol ) {
+		return pattern.template accessComponent < ::tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
 	}
 
-	static void valid ( const ::tree::UnrankedNonlinearPattern & pattern, const alphabet::Symbol & symbol) {
-		if ( pattern.accessComponent < ::tree::NonlinearAlphabet > ( ).get ( ).count ( symbol ) )
+	static void valid ( const ::tree::UnrankedNonlinearPattern < SymbolType > & pattern, const SymbolType & symbol) {
+		if ( pattern.template accessComponent < ::tree::NonlinearAlphabet > ( ).get ( ).count ( symbol ) )
 			throw ::tree::TreeException ( "Symbol " + std::to_string ( symbol ) + "cannot be set as subtree wildcard since it is already nonlinear variable" );
 	}
 };
diff --git a/alib2str/src/tree/TreeFromStringParser.cpp b/alib2str/src/tree/TreeFromStringParser.cpp
index 589d370b98..9344034fa9 100644
--- a/alib2str/src/tree/TreeFromStringParser.cpp
+++ b/alib2str/src/tree/TreeFromStringParser.cpp
@@ -38,7 +38,7 @@ Tree TreeFromStringParser::parseTree ( std::istream & input, const std::set < FE
 		if ( token.type == TreeFromStringLexer::TokenType::BAR ) {
 			alphabet::Symbol subtreeWildcard ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD );
 			alphabet::Symbol nonlinearVariable ( alphabet::NonlinearVariableSymbol ( alphabet::symbolFrom ( token.value ) ) );
-			return Tree ( UnrankedNonlinearPattern ( subtreeWildcard, { nonlinearVariable }, std::tree < alphabet::Symbol > ( subtreeWildcard, { } ) ) );
+			return Tree ( UnrankedNonlinearPattern < > ( subtreeWildcard, { nonlinearVariable }, std::tree < alphabet::Symbol > ( subtreeWildcard, { } ) ) );
 		} else {
 			std::ranked_symbol < > subtreeWildcard ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 );
 			std::ranked_symbol < > nonlinearVariable ( alphabet::Symbol ( alphabet::NonlinearVariableSymbol ( alphabet::symbolFrom ( token.value ) ) ), 0 );
@@ -95,7 +95,7 @@ Tree TreeFromStringParser::parseTree ( std::istream & input, const std::set < FE
 
 			if ( isPattern && nonlinearVariables.size ( ) ) {
 				alphabet::Symbol subtreeWildcard ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD );
-				UnrankedNonlinearPattern tree ( std::move ( subtreeWildcard ), std::move ( nonlinearVariables ), std::tree < alphabet::Symbol > ( std::move ( symbol ), std::move ( childs ) ) );
+				UnrankedNonlinearPattern < > tree ( std::move ( subtreeWildcard ), std::move ( nonlinearVariables ), std::tree < alphabet::Symbol > ( std::move ( symbol ), std::move ( childs ) ) );
 
 				if ( features.count ( FEATURES::UNRANKED_NONLINEAR_PATTERN ) ) return Tree ( std::move ( tree ) );
 			} else if ( isPattern ) {
-- 
GitLab