From 5e4b2fbb90233f7082266086fef2b678623fbde9 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 28 Sep 2015 19:27:33 +0200
Subject: [PATCH] generate random tree patterns

---
 .../src/tree/generate/RandomTreeFactory.cpp   | 337 ++++++++++++------
 .../src/tree/generate/RandomTreeFactory.h     |   8 +-
 arand2/src/arand.cpp                          | 209 ++++++-----
 3 files changed, 341 insertions(+), 213 deletions(-)

diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
index 15186b6a24..ca56b4ccb5 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.cpp
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
@@ -18,168 +18,228 @@
 #include <iostream>
 #include <random>
 
+#include <alphabet/SubtreeWildcardSymbol.h>
+
 namespace tree {
 
 namespace generate {
 
 int c = 0;
 
-
 struct Node {
-	char symbol;
-	int depth;
+	char   symbol;
+	int	   depth;
 	Node * right;
 	Node * child = NULL;
-	int rank = 0;
+	int	   rank	 = 0;
 
-	Node() : depth(0) {}
-	Node(Node * parent) : depth(parent -> depth + 1) {
-		if (parent -> child == NULL) {
-			parent -> child = this;
+	Node ( ) : depth ( 0 ) { }
+	Node ( Node * parent ) : depth ( parent->depth + 1 ) {
+		if ( parent->child == NULL ) {
+			parent->child = this;
 			right = this;
 		} else {
-			right = parent -> child -> right;
-			parent -> child -> right = this;
+			right = parent->child->right;
+			parent->child->right = this;
 		}
-		parent -> rank++;
+
+		parent->rank++;
 	}
-	~Node() {
-		if (child == NULL) return;
+
+	~Node ( ) {
+		if ( child == NULL ) return;
+
 		Node * ch = child;
+
 		do {
-			Node * tmp = ch -> right;
+			Node * tmp = ch->right;
 			delete ch;
 			ch = tmp;
-		} while (ch != child);
+		} while ( ch != child );
 	}
 
-	void rotateLeftBranch() {
-		if (child != NULL) child -> rotateLeftBranch();
-		if (rank > 1) {
-			int angle = std::random_devices::semirandom() % rank;
+	void rotateLeftBranch ( ) {
+		if ( child != NULL ) child->rotateLeftBranch ( );
+
+		if ( rank > 1 ) {
+			int angle = std::random_devices::semirandom ( ) % rank;
 			Node * newChild = child;
-			for (int i = 0; i < angle; i++) {
-				newChild = newChild -> right;
-			}
+
+			for ( int i = 0; i < angle; i++ )
+				newChild = newChild->right;
+
 			child = newChild;
 		}
 	}
 
-	void generateUnrankedSymbols(const std::vector<char> & alphabet) {
-		symbol = alphabet[std::random_devices::semirandom() % alphabet.size()];
+	void generateUnrankedSymbols ( const std::vector < char > & alphabet ) {
+		symbol = alphabet[std::random_devices::semirandom ( ) % alphabet.size ( )];
 		Node * nextChild = child;
-		for(int i = 0; i < rank; i++) {
-				nextChild -> generateUnrankedSymbols(alphabet);
-				nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			nextChild->generateUnrankedSymbols ( alphabet );
+			nextChild = nextChild->right;
 		}
 	}
 
-	void generateRankedSymbols(const std::map<int, std::vector<char> > rankedAlphabet) {
-		const std::vector<char> & alphabet = rankedAlphabet.at(rank);
-		symbol = alphabet[std::random_devices::semirandom() % alphabet.size()];
+	void generateRankedSymbols ( const std::map < int, std::vector < char > > rankedAlphabet ) {
+		const std::vector < char > & alphabet = rankedAlphabet.at ( rank );
+
+		symbol = alphabet[std::random_devices::semirandom ( ) % alphabet.size ( )];
 		Node * nextChild = child;
-		for(int i = 0; i < rank; i++) {
-				nextChild -> generateRankedSymbols(rankedAlphabet);
-				nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			nextChild->generateRankedSymbols ( rankedAlphabet );
+			nextChild = nextChild->right;
 		}
 	}
 
-	void fillRanks(std::map<int, std::vector<char> > & rankedAlphabet) {
+	void fillRanks ( std::map < int, std::vector < char > > & rankedAlphabet ) {
 		rankedAlphabet[rank];
 		Node * nextChild = child;
-		for(int i = 0; i < rank; i++) {
-				nextChild -> fillRanks(rankedAlphabet);
-				nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			nextChild->fillRanks ( rankedAlphabet );
+			nextChild = nextChild->right;
 		}
 	}
 
-	UnrankedNode * createUnrankedNode() {
-		std::vector<UnrankedNode *> children;
+	UnrankedNode * createUnrankedNode ( ) {
+		std::vector < UnrankedNode * > children;
 		Node * nextChild = child;
-		for(int i = 0; i < rank; i++) {
-				children.push_back(nextChild -> createUnrankedNode());
-				nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			children.push_back ( nextChild->createUnrankedNode ( ) );
+			nextChild = nextChild->right;
 		}
-		return new UnrankedNode(alphabet::symbolFrom(symbol), children);
+
+		return new UnrankedNode ( alphabet::symbolFrom ( symbol ), children );
 	}
 
-	RankedNode * createRankedNode() {
-		std::vector<RankedNode *> children;
+	UnrankedNode * createUnrankedPatternNode ( ) {
+		if ( rank == 0 ) {
+			return new UnrankedNode ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), { } );
+		} else {
+			std::vector < UnrankedNode * > children;
+			Node * nextChild = child;
+
+			for ( int i = 0; i < rank; i++ ) {
+				children.push_back ( nextChild->createUnrankedPatternNode ( ) );
+				nextChild = nextChild->right;
+			}
+
+			return new UnrankedNode ( alphabet::symbolFrom ( symbol ), children );
+		}
+	}
+
+	RankedNode * createRankedNode ( ) {
+		std::vector < RankedNode * > children;
 		Node * nextChild = child;
-		for(int i = 0; i < rank; i++) {
-				children.push_back(nextChild -> createRankedNode());
-				nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			children.push_back ( nextChild->createRankedNode ( ) );
+			nextChild = nextChild->right;
+		}
+
+		return new RankedNode ( alphabet::RankedSymbol ( symbol, rank ), children );
+	}
+
+	RankedNode * createRankedPatternNode ( ) {
+		if ( rank == 0 ) {
+			return new RankedNode ( alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 ), { } );
+		} else {
+			std::vector < RankedNode * > children;
+			Node * nextChild = child;
+
+			for ( int i = 0; i < rank; i++ ) {
+				children.push_back ( nextChild->createRankedPatternNode ( ) );
+				nextChild = nextChild->right;
+			}
+
+			return new RankedNode ( alphabet::RankedSymbol ( symbol, rank ), children );
 		}
-		return new RankedNode(alphabet::RankedSymbol(symbol, rank), children);
 	}
 
-	void nicePrint(std::ostream & os = std::cout, const std::string & prefix = "", const bool last = true) const {
+	void nicePrint ( std::ostream & os = std::cout, const std::string & prefix = "", const bool last = true ) const {
 		os << prefix;
 
-		std::string nextPrefix(prefix);
-		if (last) {
+		std::string nextPrefix ( prefix );
+
+		if ( last ) {
 			os << "\\-";
 			nextPrefix += "  ";
 		} else {
 			os << "|-";
 			nextPrefix += "| ";
 		}
+
 		os << symbol << " (" << rank << ")" << std::endl;
 
 		Node * nextChild = child;
-		for (int i = 0; i < rank; i++)
-		{
-			//os << nextPrefix << "|" << std::endl;
-			nextChild -> nicePrint(os, nextPrefix, i == rank-1);
-			nextChild = nextChild -> right;
+
+		for ( int i = 0; i < rank; i++ ) {
+			 // os << nextPrefix << "|" << std::endl;
+			nextChild->nicePrint ( os, nextPrefix, i == rank - 1 );
+			nextChild = nextChild->right;
 		}
 	}
+
 };
 
-std::vector<char> generateUnrankedAlphabet(int maxAlphabetSize, bool randomizedAlphabet) {
-	std::vector<char> symbols (26);
-	for(int i = 0; i < 26; i++) symbols[i] = i + 'a';
-	if(randomizedAlphabet) shuffle(symbols.begin(), symbols.end(), std::random_devices::semirandom);
-	return std::vector<char> (symbols.begin(), symbols.begin() + maxAlphabetSize);
+std::vector < char > generateUnrankedAlphabet ( int maxAlphabetSize, bool randomizedAlphabet ) {
+	std::vector < char > symbols ( 26 );
+
+	for ( int i = 0; i < 26; i++ ) symbols[i] = i + 'a';
+
+	if ( randomizedAlphabet ) shuffle ( symbols.begin ( ), symbols.end ( ), std::random_devices::semirandom );
+
+	return std::vector < char > ( symbols.begin ( ), symbols.begin ( ) + maxAlphabetSize );
 }
 
-void generateRankedAlphabet(std::map<int, std::vector<char> > & rankedAlphabet, int maxAlphabetSize, bool randomizedAlphabet) {
-	int ranksCount = rankedAlphabet.size();
-	std::vector<char> unrankedAlphabet = generateUnrankedAlphabet(maxAlphabetSize > ranksCount ? maxAlphabetSize : ranksCount, randomizedAlphabet);
+void generateRankedAlphabet ( std::map < int, std::vector < char > > & rankedAlphabet, int maxAlphabetSize, bool randomizedAlphabet ) {
+	int ranksCount = rankedAlphabet.size ( );
+	std::vector < char > unrankedAlphabet = generateUnrankedAlphabet ( maxAlphabetSize > ranksCount ? maxAlphabetSize : ranksCount, randomizedAlphabet );
+
+	std::set < int > rankSeparators;
+
+	rankSeparators.insert ( 0 );
+	rankSeparators.insert ( unrankedAlphabet.size ( ) );
+
+	while ( ( int ) rankSeparators.size ( ) != ranksCount + 1 /*&& rankSeparators.size() != maxRank + 2*/ ) rankSeparators.insert ( std::random_devices::semirandom ( ) % unrankedAlphabet.size ( ) );
 
-	std::set<int> rankSeparators;
-	rankSeparators.insert(0);
-	rankSeparators.insert(unrankedAlphabet.size());
-	while ((int)rankSeparators.size() != ranksCount + 1 /*&& rankSeparators.size() != maxRank + 2*/) rankSeparators.insert(std::random_devices::semirandom() % unrankedAlphabet.size());
+	std::set < int >::iterator it = rankSeparators.begin ( );
 
-	std::set<int>::iterator it = rankSeparators.begin();
-	for (std::map<int, std::vector<char> >::iterator i = rankedAlphabet.begin(); i != rankedAlphabet.end(); ++i) {
-		std::set<int>::iterator prevIt = it++;
-		i -> second.insert(i -> second.begin(), unrankedAlphabet.begin() + *prevIt, unrankedAlphabet.begin() + *it);
+	for ( std::map < int, std::vector < char > >::iterator i = rankedAlphabet.begin ( ); i != rankedAlphabet.end ( ); ++i ) {
+		std::set < int >::iterator prevIt = it++;
+		i->second.insert ( i->second.begin ( ), unrankedAlphabet.begin ( ) + * prevIt, unrankedAlphabet.begin ( ) + * it );
 	}
 }
 
-Node * generateTreeStructure(int depth, int nodesCount, int maxRank = INT_MAX) {
-	if(depth >= nodesCount) throw exception::AlibException("number of nodes is too small");
+Node * generateTreeStructure ( int depth, int nodesCount, int maxRank = INT_MAX ) {
+	if ( depth >= nodesCount ) throw exception::AlibException ( "number of nodes is too small" );
+
+	if ( ( maxRank != INT_MAX ) && ( pow ( maxRank, depth + 1 ) - 1 < nodesCount ) ) throw exception::AlibException ( "number of nodes is too small" );
+
+	std::vector < Node * > nodes ( nodesCount );
+
+	 // generate path depth long
+	Node * root = nodes[0] = new Node ( );
+
+	for ( int i = 1; i <= depth; i++ ) nodes[i] = new Node ( nodes[i - 1] );
 
-	if(maxRank != INT_MAX && pow(maxRank, depth + 1) - 1 < nodesCount) throw exception::AlibException("number of nodes is too small");
-	std::vector<Node *> nodes (nodesCount);
+	 // move final leaf to end
+	nodes[nodesCount - 1] = nodes[depth];
 
-	//generate path depth long
-	Node * root = nodes[0] = new Node();
-	for (int i = 1; i <= depth; i++) nodes[i] = new Node(nodes[i-1]);
-	//move final leaf to end
-	nodes[nodesCount-1] = nodes[depth];
-	
 	int availableNodesIndex = depth;
 	int finalNodesIndex = nodesCount - 2;
-	while(finalNodesIndex >= availableNodesIndex) {
-		int randomIndex = std::random_devices::semirandom() % availableNodesIndex;
+
+	while ( finalNodesIndex >= availableNodesIndex ) {
+		int randomIndex = std::random_devices::semirandom ( ) % availableNodesIndex;
 		Node * parent = nodes[randomIndex];
-		Node * node = new Node(parent);
+		Node * node = new Node ( parent );
 
-		//put node to end if it reached depth limit
-		if (node -> depth < depth) {
+		 // put node to end if it reached depth limit
+		if ( node->depth < depth ) {
 			nodes[availableNodesIndex] = node;
 			availableNodesIndex++;
 		} else {
@@ -187,50 +247,97 @@ Node * generateTreeStructure(int depth, int nodesCount, int maxRank = INT_MAX) {
 			finalNodesIndex--;
 		}
 
-		//put parent node to end if it reached rank limit
-		if (parent -> rank >= maxRank) {
-			nodes[randomIndex] = nodes[availableNodesIndex-1];
+		 // put parent node to end if it reached rank limit
+		if ( parent->rank >= maxRank ) {
+			nodes[randomIndex] = nodes[availableNodesIndex - 1];
 			nodes[finalNodesIndex] = parent;
 			availableNodesIndex--;
 			finalNodesIndex--;
 		}
 	}
 
-	//move generated path to random branch
-	root -> rotateLeftBranch();
+	 // move generated path to random branch
+	root->rotateLeftBranch ( );
 
 	return root;
 }
 
-UnrankedTree RandomTreeFactory::generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank) {
-	Node * root = generateTreeStructure(depth, nodesCount, maxRank);
-	std::vector<char> alphabet = generateUnrankedAlphabet(maxAlphabetSize, randomizedAlphabet);
-	root -> generateUnrankedSymbols(alphabet);
+UnrankedTree RandomTreeFactory::generateUnrankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
+	std::vector < char > alphabet = generateUnrankedAlphabet ( maxAlphabetSize, randomizedAlphabet );
+
+	root->generateUnrankedSymbols ( alphabet );
+
+	std::set < alphabet::Symbol > treeAlphabet;
+
+	for ( std::vector < char >::const_iterator it = alphabet.begin ( ); it != alphabet.end ( ); ++it )
+		treeAlphabet.insert ( alphabet::symbolFrom ( * it ) );
+
+	UnrankedTree tree ( treeAlphabet, * std::move ( root->createUnrankedNode ( ) ) );
+	delete root;
+	return tree;
+}
+
+UnrankedPattern RandomTreeFactory::generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
+	std::vector < char > alphabet = generateUnrankedAlphabet ( maxAlphabetSize, randomizedAlphabet );
 
-	std::set<alphabet::Symbol> treeAlphabet;
-	for (std::vector<char>::iterator it = alphabet.begin(); it != alphabet.end(); ++it) {
-		treeAlphabet.insert(alphabet::symbolFrom(*it));
+	root->generateUnrankedSymbols ( alphabet );
+
+	std::set < alphabet::Symbol > treeAlphabet;
+
+	for ( std::vector < char >::const_iterator it = alphabet.begin ( ); it != alphabet.end ( ); ++it )
+		treeAlphabet.insert ( alphabet::symbolFrom ( * it ) );
+
+	alphabet::Symbol subtreeWildcard ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD );
+	treeAlphabet.insert ( subtreeWildcard );
+	UnrankedPattern tree ( std::move ( subtreeWildcard ), treeAlphabet, * std::move ( root->createUnrankedPatternNode ( ) ) );
+	delete root;
+	return tree;
+}
+
+RankedTree RandomTreeFactory::generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
+	std::map < int, std::vector < char > > rankedAlphabet;
+
+	root->fillRanks ( rankedAlphabet );
+	generateRankedAlphabet ( rankedAlphabet, maxAlphabetSize, randomizedAlphabet );
+	root->generateRankedSymbols ( rankedAlphabet );
+
+	std::set < alphabet::RankedSymbol > treeRankedAlphabet;
+
+	for ( std::map < int, std::vector < char > >::const_iterator it = rankedAlphabet.begin ( ); it != rankedAlphabet.end ( ); ++it ) {
+		const std::vector < char > & alphabet = it->second;
+
+		for ( std::vector < char >::const_iterator i = alphabet.begin ( ); i != alphabet.end ( ); ++i )
+			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( * i, it->first ) );
 	}
-	UnrankedTree tree (treeAlphabet, *std::move(root -> createUnrankedNode()));
+
+	RankedTree tree ( treeRankedAlphabet, std::move ( * root->createRankedNode ( ) ) );
 	delete root;
 	return tree;
 }
 
-RankedTree RandomTreeFactory::generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank) {
-	Node * root = generateTreeStructure(depth, nodesCount, maxRank);
-	std::map<int, std::vector<char> > rankedAlphabet;
-	root -> fillRanks(rankedAlphabet);
-	generateRankedAlphabet(rankedAlphabet, maxAlphabetSize, randomizedAlphabet);
-	root -> generateRankedSymbols(rankedAlphabet);
-
-	std::set<alphabet::RankedSymbol> treeRankedAlphabet;
-	for (std::map<int, std::vector<char> >::iterator it = rankedAlphabet.begin(); it != rankedAlphabet.end(); ++it) {
-		std::vector<char> & alphabet = it -> second;
-		for (std::vector<char>::iterator i = alphabet.begin(); i != alphabet.end(); ++i) {
-			treeRankedAlphabet.insert(alphabet::RankedSymbol(*i, it -> first));
-		}
+RankedPattern RandomTreeFactory::generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
+	std::map < int, std::vector < char > > rankedAlphabet;
+
+	root->fillRanks ( rankedAlphabet );
+	generateRankedAlphabet ( rankedAlphabet, maxAlphabetSize, randomizedAlphabet );
+	root->generateRankedSymbols ( rankedAlphabet );
+
+	std::set < alphabet::RankedSymbol > treeRankedAlphabet;
+
+	for ( std::map < int, std::vector < char > >::const_iterator it = rankedAlphabet.begin ( ); it != rankedAlphabet.end ( ); ++it ) {
+		const std::vector < char > & alphabet = it->second;
+
+		for ( std::vector < char >::const_iterator i = alphabet.begin ( ); i != alphabet.end ( ); ++i )
+			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( * i, it->first ) );
 	}
-	RankedTree tree (treeRankedAlphabet, std::move(*root -> createRankedNode()));
+
+	alphabet::RankedSymbol subtreeWildcard ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 );
+	treeRankedAlphabet.insert ( subtreeWildcard );
+	RankedPattern tree ( std::move ( subtreeWildcard ), treeRankedAlphabet, std::move ( * root->createRankedPatternNode ( ) ) );
 	delete root;
 	return tree;
 }
diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.h b/alib2algo/src/tree/generate/RandomTreeFactory.h
index c40e59d39d..2410388c46 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.h
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.h
@@ -16,7 +16,9 @@
 #include <alphabet/RankedSymbol.h>
 #include <alphabet/LabeledSymbol.h>
 #include <tree/ranked/RankedTree.h>
+#include <tree/ranked/RankedPattern.h>
 #include <tree/unranked/UnrankedTree.h>
+#include <tree/unranked/UnrankedPattern.h>
 
 namespace tree {
 
@@ -24,8 +26,10 @@ namespace generate {
 
 class RandomTreeFactory {
 public:
-	static tree::RankedTree generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX);
-	static tree::UnrankedTree generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX);
+	static tree::RankedTree generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+	static tree::RankedPattern generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+	static tree::UnrankedTree generateUnrankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+	static tree::UnrankedPattern generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 
 private:
 };
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index 63117b7c08..206c781726 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -14,149 +14,166 @@
 #include "string/generate/RandomStringFactory.h"
 #include "tree/generate/RandomTreeFactory.h"
 
-int main(int argc, char* argv[]) {
+int main ( int argc, char * argv[] ) {
 	try {
-		TCLAP::CmdLine cmd("Random generator binary", ' ', "0.01");
+		TCLAP::CmdLine cmd ( "Random generator binary", ' ', "0.01" );
 
-		std::vector<std::string> allowed;
-		allowed.push_back("FSM");
-		allowed.push_back("CFG");
-		allowed.push_back("RE");
-		allowed.push_back("ST");
-		allowed.push_back("UT");
-		allowed.push_back("RT");
-		TCLAP::ValuesConstraint<std::string> allowedVals( allowed );
+		std::vector < std::string > allowed;
+		allowed.push_back ( "FSM" );
+		allowed.push_back ( "CFG" );
+		allowed.push_back ( "RE" );
+		allowed.push_back ( "ST" );
+		allowed.push_back ( "UT" );
+		allowed.push_back ( "UP" );
+		allowed.push_back ( "RT" );
+		allowed.push_back ( "RP" );
+		TCLAP::ValuesConstraint < std::string > allowedVals ( allowed );
 
-		TCLAP::ValueArg<std::string> type(	"t",	"type",			"Type of generated structure",			true,	"FSM",	&allowedVals);
-		cmd.add( type );
+		TCLAP::ValueArg < std::string > type ( "t", "type", "Type of generated structure", true, "FSM", & allowedVals );
+		cmd.add ( type );
 
-		TCLAP::ValueArg<int> alphabetSize(	"",	"terminals",		"Number of terminals/alphabet size",		false,	3,	"integer");
-		cmd.add( alphabetSize );
+		TCLAP::ValueArg < int > alphabetSize ( "", "terminals", "Number of terminals/alphabet size", false, 3, "integer" );
+		cmd.add ( alphabetSize );
 
-		TCLAP::SwitchArg randomizedAlphabet(	"",	"randomizedTerminals",	"Number of terminals/alphabet size",		false);
-		cmd.add( randomizedAlphabet );
+		TCLAP::SwitchArg randomizedAlphabet ( "", "randomizedTerminals", "Number of terminals/alphabet size", false );
+		cmd.add ( randomizedAlphabet );
 
-		TCLAP::ValueArg<double> density(	"",	"density",		"Automaton's/grammar's transition density",	false,	10,	"double");
-		cmd.add( density );
+		TCLAP::ValueArg < double > density ( "", "density", "Automaton's/grammar's transition density", false, 10, "double" );
+		cmd.add ( density );
 
-		TCLAP::ValueArg<int> nonterminals(	"",	"nonterminals",		"Number of grammar's nononterminals",		false,	5,	"integer");
-		cmd.add( nonterminals );
+		TCLAP::ValueArg < int > nonterminals ( "", "nonterminals", "Number of grammar's nononterminals", false, 5, "integer" );
+		cmd.add ( nonterminals );
 
-		TCLAP::ValueArg<int> nodes(		"",	"nodes",		"Number of automaton's or tree nodes",		false,	6,	"integer");
-		cmd.add( nodes );
+		TCLAP::ValueArg < int > nodes ( "", "nodes", "Number of automaton's or tree nodes", false, 6, "integer" );
+		cmd.add ( nodes );
 
-		TCLAP::ValueArg<int> states(		"",	"states",		"Number of automaton's states",			false,	5,	"integer");
-		cmd.add( states );
+		TCLAP::ValueArg < int > states ( "", "states", "Number of automaton's states", false, 5, "integer" );
+		cmd.add ( states );
 
-		TCLAP::ValueArg<int> terminalNodes(	"",	"leaves",		"Number of tree's/regexp's terminal nodes",	false,	5,	"integer");
-		cmd.add( terminalNodes );
+		TCLAP::ValueArg < int > terminalNodes ( "", "leaves", "Number of tree's/regexp's terminal nodes", false, 5, "integer" );
+		cmd.add ( terminalNodes );
 
-		TCLAP::ValueArg<int> height(		"",	"height",		"Height of the tree/regexp",			false,	5,	"integer");
-		cmd.add( height );
+		TCLAP::ValueArg < int > height ( "", "height", "Height of the tree/regexp", false, 5, "integer" );
+		cmd.add ( height );
 
-		TCLAP::ValueArg<int> length(		"",	"length",		"Length of the string",				false,	5,	"integer");
-		cmd.add( length );
+		TCLAP::ValueArg < int > length ( "", "length", "Length of the string", false, 5, "integer" );
+		cmd.add ( length );
 
-		TCLAP::ValueArg<int> maxRank(		"",	"rank",			"Maximal rank of tree nodes",			false,	5,	"integer");
-		cmd.add( maxRank );
+		TCLAP::ValueArg < int > maxRank ( "", "rank", "Maximal rank of tree nodes", false, 5, "integer" );
+		cmd.add ( maxRank );
 
-		TCLAP::SwitchArg measure(		"m",	"measure",	"Measure times",		false);
-		cmd.add( measure );
+		TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false );
+		cmd.add ( measure );
 
-		TCLAP::SwitchArg verbose(		"v",	"verbose",	"Be verbose",			false);
-		cmd.add( verbose );
+		TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false );
+		cmd.add ( verbose );
 
-		cmd.parse(argc,argv);
+		cmd.parse ( argc, argv );
 
-		std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL);
+		std::chrono::measurements::start ( "Overal", std::chrono::measurements::Type::OVERALL );
 
-		if(!type.isSet()) throw exception::AlibException("Type is not defined.");
-		if( type.getValue() == "FSM" ) {
-			if( density.getValue() < 1 || density.getValue() > 100 )
-			{
-				//TODO: floating point arithmetic
-				throw exception::AlibException("You must specify density as a number between 1 and 100.");
-			}
+		if ( !type.isSet ( ) ) throw exception::AlibException ( "Type is not defined." );
 
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+		if ( type.getValue ( ) == "FSM" ) {
+			if ( ( density.getValue ( ) < 1 ) || ( density.getValue ( ) > 100 ) )
+				 // TODO: floating point arithmetic
+				throw exception::AlibException ( "You must specify density as a number between 1 and 100." );
 
-			automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA( states.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue(), density.getValue() );
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA ( states.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
-		} else if( type.getValue() == "CFG" ) {
-			if( density.getValue() < 1 || density.getValue() > 100 )
-			{
-				//TODO: floating point arithmetic
-				throw exception::AlibException("You must specify density as a number between 1 and 100.");
-			}
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "CFG" ) {
+			if ( ( density.getValue ( ) < 1 ) || ( density.getValue ( ) > 100 ) )
+				 // TODO: floating point arithmetic
+				throw exception::AlibException ( "You must specify density as a number between 1 and 100." );
 
-			grammar::CFG res = grammar::generate::RandomGrammarFactory::generateCFG( nonterminals.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue(), density.getValue() );
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			grammar::CFG res = grammar::generate::RandomGrammarFactory::generateCFG ( nonterminals.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
-		} else if( type.getValue() == "RE" ) {
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-			regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp(terminalNodes.getValue(), height.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue() );
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "RE" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp ( terminalNodes.getValue ( ), height.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
-		} else if( type.getValue() == "ST" ) {
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-			string::LinearString res = string::generate::RandomStringFactory::generateLinearString(length.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue() );
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "ST" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			string::LinearString res = string::generate::RandomStringFactory::generateLinearString ( length.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
-		} else if( type.getValue() == "UT" ) {
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-			tree::UnrankedTree res = tree::generate::RandomTreeFactory::generateUnrankedTree(height.getValue(), nodes.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue(), maxRank.getValue());
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "UT" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			tree::UnrankedTree res = tree::generate::RandomTreeFactory::generateUnrankedTree ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
-		} else if( type.getValue() == "RT" ) {
-			std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-			tree::RankedTree res = tree::generate::RandomTreeFactory::generateRankedTree(height.getValue(), nodes.getValue(), alphabetSize.getValue(), randomizedAlphabet.getValue(), maxRank.getValue());
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "UP" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+			tree::UnrankedPattern res = tree::generate::RandomTreeFactory::generateUnrankedPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
 
-			alib::XmlDataFactory::toStdout(res);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
+
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "RT" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
+
+			tree::RankedTree res = tree::generate::RandomTreeFactory::generateRankedTree ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
+
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "RP" ) {
+			std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN );
+
+			tree::RankedPattern res = tree::generate::RandomTreeFactory::generateRankedPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
+
+			alib::XmlDataFactory::toStdout ( res );
 		} else {
-			throw exception::AlibException("Invalid type.");
+			throw exception::AlibException ( "Invalid type." );
 		}
 
-		std::chrono::measurements::end();
-		std::chrono::measurements::end();
+		std::chrono::measurements::end ( );
+		std::chrono::measurements::end ( );
 
-		if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl;
+		if ( measure.getValue ( ) ) std::clog << std::chrono::measurements::results ( ) << std::endl;
 
 		return 0;
-	} catch( const exception::AlibException & exception ) {
-		alib::XmlDataFactory::toStdout( exception );
+	} catch ( const exception::AlibException & exception ) {
+		alib::XmlDataFactory::toStdout ( exception );
 		return 1;
-	} catch(const TCLAP::ArgException& exception) {
-		std::cout << exception.error() << std::endl;
+	} catch ( const TCLAP::ArgException & exception ) {
+		std::cout << exception.error ( ) << std::endl;
 		return 2;
-	} catch (const std::exception& exception) {
-		std::cerr << "Exception caught: " << exception.what() << std::endl;
+	} catch ( const std::exception & exception ) {
+		std::cerr << "Exception caught: " << exception.what ( ) << std::endl;
 		return 3;
-	} catch(...) {
+	} catch ( ... ) {
 		std::cerr << "Unknown exception caught." << std::endl;
 		return 127;
 	}
-- 
GitLab