From a31d0ca7681bc09b56c4b12199d13e496109b706 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Plach=C3=BD?= <plachste@fit.cvut.cz>
Date: Fri, 20 Mar 2015 19:42:43 +0100
Subject: [PATCH] random tree generator

---
 .../src/tree/generate/RandomTreeFactory.cpp   | 233 ++++++++++++++++++
 .../src/tree/generate/RandomTreeFactory.h     |  37 +++
 alib2data/src/tree/RankedTree/RankedNode.h    |   2 +-
 alib2data/src/tree/RankedTree/RankedTree.cpp  |   4 +
 alib2data/src/tree/RankedTree/RankedTree.h    |   4 +
 .../src/tree/UnrankedTree/UnrankedNode.h      |   4 +-
 .../src/tree/UnrankedTree/UnrankedTree.cpp    |   4 +
 .../src/tree/UnrankedTree/UnrankedTree.h      |   4 +
 makefile                                      |   2 +
 tniceprint/makefile                           | 128 ++++++++++
 tniceprint/src/tniceprint.cpp                 |  58 +++++
 trand/makefile                                | 128 ++++++++++
 trand/src/trand.cpp                           |  71 ++++++
 13 files changed, 676 insertions(+), 3 deletions(-)
 create mode 100644 alib2algo/src/tree/generate/RandomTreeFactory.cpp
 create mode 100644 alib2algo/src/tree/generate/RandomTreeFactory.h
 create mode 100644 tniceprint/makefile
 create mode 100644 tniceprint/src/tniceprint.cpp
 create mode 100644 trand/makefile
 create mode 100644 trand/src/trand.cpp

diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
new file mode 100644
index 0000000000..b0a4876c56
--- /dev/null
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
@@ -0,0 +1,233 @@
+/*
+ * RandomTreeFactory.cpp
+ *
+ *  Created on: 18. 3. 2015
+ *	  Author: Stepan Plachy
+ */
+
+#include "RandomTreeFactory.h"
+
+#include <vector>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <cstdlib>
+#include <ctime>
+#include <cmath>
+
+#include <iostream>
+
+namespace tree {
+
+namespace generate {
+
+
+struct Node {
+	char symbol;
+	int depth;
+	Node * right;
+	Node * child = NULL;
+	int rank = 0;
+
+	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;
+		}
+		parent -> rank++;
+	}
+
+	void rotateLeftBranch() {
+		if (child != NULL) child -> rotateLeftBranch();
+		if (rank > 1) {
+			int angle = rand() % rank;
+			Node * newChild = child;
+			for (int i = 0; i < angle; i++) {
+				newChild = newChild -> right;
+			}
+			child = newChild;
+		}
+	}
+
+	void generateUnrankedSymbols(const std::vector<char> & alphabet) {
+		symbol = alphabet[rand() % alphabet.size()];
+		Node * nextChild = child;
+		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[rand() % alphabet.size()];
+		Node * nextChild = child;
+		for(int i = 0; i < rank; i++) {
+				nextChild -> generateRankedSymbols(rankedAlphabet);
+				nextChild = nextChild -> right;
+		}
+	}
+
+	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;
+		}
+	}
+
+	UnrankedNode * createUnrankedNode() {
+		std::list<UnrankedNode *> children;
+		Node * nextChild = child;
+		for(int i = 0; i < rank; i++) {
+				children.push_back(nextChild -> createUnrankedNode());
+				nextChild = nextChild -> right;
+		}
+		return new UnrankedNode(alphabet::LabeledSymbol(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;
+		}
+		return new RankedNode(alphabet::RankedSymbol(symbol, rank), children);
+	}
+
+	void nicePrint(std::ostream & os = std::cout, const std::string & prefix = "", const bool last = true) const {
+		os << prefix;
+
+		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;
+		}
+	}
+};
+
+std::vector<char> generateUnrankedAlphabet(int maxAlphabetSize) {
+	std::vector<char> symbols (26);
+	for(int i = 0; i < 26; i++) symbols[i] = i + 'a';
+	random_shuffle(symbols.begin(), symbols.end());
+	return std::vector<char> (symbols.begin(), symbols.begin() + maxAlphabetSize);
+}
+
+void generateRankedAlphabet(std::map<int, std::vector<char> > & rankedAlphabet, int maxAlphabetSize) {
+	int ranksCount = rankedAlphabet.size();
+	std::vector<char> unrankedAlphabet = generateUnrankedAlphabet(maxAlphabetSize > ranksCount ? maxAlphabetSize : ranksCount);
+
+	std::set<int> rankSeparators;
+	rankSeparators.insert(0);
+	rankSeparators.insert(unrankedAlphabet.size());
+	while ((int)rankSeparators.size() != ranksCount + 1 /*&& rankSeparators.size() != maxRank + 2*/) rankSeparators.insert(rand() % unrankedAlphabet.size());
+
+	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);
+	}
+}
+
+Node * generateTreeStructure(int depth, int nodesCount, int maxRank = INT_MAX) {
+	if(maxRank != INT_MAX && pow(maxRank, depth + 1) - 1 < nodesCount) throw exception::AlibException("number of nodes is too small");
+	srand(time(NULL));
+	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]);
+	//move final leaf to end
+	nodes[nodesCount-1] = nodes[depth];
+	
+	int availableNodesIndex = depth;
+	int finalNodesIndex = nodesCount - 2;
+	while(finalNodesIndex >= availableNodesIndex) {
+		int randomIndex = rand() % availableNodesIndex;
+		Node * parent = nodes[randomIndex];
+		Node * node = new Node(parent);
+
+		//put node to end if it reached depth limit
+		if (node -> depth < depth) {
+			nodes[availableNodesIndex] = node;
+			availableNodesIndex++;
+		} else {
+			nodes[finalNodesIndex] = node;
+			finalNodesIndex--;
+		}
+
+		//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();
+
+	return root;
+}
+
+UnrankedTree RandomTreeFactory::generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank) {
+	Node * root = generateTreeStructure(depth, nodesCount, maxRank);
+	std::vector<char> alphabet = generateUnrankedAlphabet(maxAlphabetSize);
+	root -> generateUnrankedSymbols(alphabet);
+
+	std::set<alphabet::LabeledSymbol> treeAlphabet;
+	for (std::vector<char>::iterator it = alphabet.begin(); it != alphabet.end(); ++it) {
+		treeAlphabet.insert(alphabet::LabeledSymbol(*it));
+	}
+	return UnrankedTree(treeAlphabet, root -> createUnrankedNode());
+}
+
+RankedTree RandomTreeFactory::generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank) {
+	Node * root = generateTreeStructure(depth, nodesCount, maxRank);
+	std::map<int, std::vector<char> > rankedAlphabet;
+	root -> fillRanks(rankedAlphabet);
+	generateRankedAlphabet(rankedAlphabet, maxAlphabetSize);
+	root -> generateRankedSymbols(rankedAlphabet);
+/*
+	for (std::map<int, std::vector<char> >::iterator i = rankedAlphabet.begin(); i != rankedAlphabet.end(); ++i) {
+		std::vector<char> & tmp = i -> second;
+		std::cout << i -> first << " ";
+		for (std::vector<char>::iterator it = tmp.begin(); it != tmp.end(); ++it) {
+			std::cout << *it << " ";
+		}
+		std::cout << std::endl;
+	}
+*/
+
+	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));
+		}
+	}
+	return RankedTree(treeRankedAlphabet, root -> createRankedNode());
+}
+
+} /* namespace generate */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.h b/alib2algo/src/tree/generate/RandomTreeFactory.h
new file mode 100644
index 0000000000..89112bb39f
--- /dev/null
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.h
@@ -0,0 +1,37 @@
+/*
+ * RandomTreeFactory.h
+ *
+ *  Created on: 18. 3. 2015
+ *	  Author: Stepan Plachy
+ */
+
+#ifndef RANDOM_TREE_FACTORY_H_
+#define RANDOM_TREE_FACTORY_H_
+
+#include <deque>
+#include <set>
+#include <climits>
+
+#include <exception/AlibException.h>
+#include <alphabet/RankedSymbol.h>
+#include <alphabet/LabeledSymbol.h>
+#include <tree/RankedTree/RankedTree.h>
+#include <tree/UnrankedTree/UnrankedTree.h>
+
+namespace tree {
+
+namespace generate {
+
+class RandomTreeFactory {
+public:
+	static tree::RankedTree generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank = INT_MAX);
+	static tree::UnrankedTree generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank = INT_MAX);
+
+private:
+};
+
+} /* namespace generate */
+
+} /* namespace tree */
+
+#endif /* RANDOM_TREE_FACTORY_H_ */
diff --git a/alib2data/src/tree/RankedTree/RankedNode.h b/alib2data/src/tree/RankedTree/RankedNode.h
index 0e58648cd9..7cfbb4a6e9 100644
--- a/alib2data/src/tree/RankedTree/RankedNode.h
+++ b/alib2data/src/tree/RankedTree/RankedNode.h
@@ -56,7 +56,7 @@ public:
 
 	operator std::string () const;
 
-	void nicePrint(std::ostream &, const std::string & = "", const bool = true) const;
+	void nicePrint(std::ostream & = std::cout, const std::string & = "", const bool = true) const;
 
 	friend class RankedTree;
 };
diff --git a/alib2data/src/tree/RankedTree/RankedTree.cpp b/alib2data/src/tree/RankedTree/RankedTree.cpp
index 45757c0157..09ee5dd2e7 100644
--- a/alib2data/src/tree/RankedTree/RankedTree.cpp
+++ b/alib2data/src/tree/RankedTree/RankedTree.cpp
@@ -81,6 +81,10 @@ int RankedTree::compare(const RankedTree & other) const {
 	else return 1; 
 }
 
+void RankedTree::nicePrint(std::ostream & os) const {
+	root -> nicePrint(os);
+}
+
 RankedTree::operator std::string () const {
 	std::stringstream ss;
 	ss << *this;
diff --git a/alib2data/src/tree/RankedTree/RankedTree.h b/alib2data/src/tree/RankedTree/RankedTree.h
index 4b6f94314d..93379d24d0 100644
--- a/alib2data/src/tree/RankedTree/RankedTree.h
+++ b/alib2data/src/tree/RankedTree/RankedTree.h
@@ -8,6 +8,8 @@
 #ifndef RANKEDTREE_H_
 #define RANKEDTREE_H_
 
+#include <iostream>
+
 #include "../TreeBase.h"
 #include "RankedNode.h"
 #include "../../alphabet/RankedSymbol.h"
@@ -65,6 +67,8 @@ public:
 		return typeId<RankedTree>();
 	}
 
+	void nicePrint(std::ostream & os = std::cout) const;
+
 	friend class RankedNode;
 };
 
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedNode.h b/alib2data/src/tree/UnrankedTree/UnrankedNode.h
index 3b3f73082c..201f9b31fe 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedNode.h
+++ b/alib2data/src/tree/UnrankedTree/UnrankedNode.h
@@ -9,7 +9,7 @@
 #define UNRANKED_NODE_H_
 
 #include <string>
-#include <ostream>
+#include <iostream>
 #include <list>
 
 #include "../../label/Label.h"
@@ -60,7 +60,7 @@ public:
 
 	operator std::string () const;
 
-	void nicePrint(std::ostream &, const std::string & = "", const bool = true) const;
+	void nicePrint(std::ostream & = std::cout, const std::string & = "", const bool = true) const;
 
 	friend class UnrankedTree;
 };
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
index 27a4e78f44..7faa8b02af 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
+++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
@@ -81,6 +81,10 @@ int UnrankedTree::compare(const UnrankedTree & other) const {
 	else return 1; 
 }
 
+void UnrankedTree::nicePrint(std::ostream & os) const {
+	root -> nicePrint(os);
+}
+
 UnrankedTree::operator std::string () const {
 	std::stringstream ss;
 	ss << *this;
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.h b/alib2data/src/tree/UnrankedTree/UnrankedTree.h
index 12064e2eb0..35164f6b83 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedTree.h
+++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.h
@@ -13,6 +13,8 @@
 #include "../../alphabet/LabeledSymbol.h"
 #include "../../std/set.hpp"
 
+#include <iostream>
+
 namespace tree {
 
 	class UnrankedNode;
@@ -65,6 +67,8 @@ public:
 		return typeId<UnrankedTree>();
 	}
 
+	void nicePrint(std::ostream & os = std::cout) const;
+	
 	friend class UnrankedNode;
 };
 
diff --git a/makefile b/makefile
index d0e3ea11e8..b6e0f53fb8 100644
--- a/makefile
+++ b/makefile
@@ -23,6 +23,8 @@ SUBDIRS_BINS = acat2 \
 		astat2 \
 		astringology2 \
 		atrim2 \
+		trand \
+		tniceprint \
 
 
 ifneq (3.81, $(firstword $(sort $(MAKE_VERSION) 3.81)))
diff --git a/tniceprint/makefile b/tniceprint/makefile
new file mode 100644
index 0000000000..be57cd2434
--- /dev/null
+++ b/tniceprint/makefile
@@ -0,0 +1,128 @@
+SHELL:=/bin/bash
+EXECUTABLE:=tniceprint
+
+define NEW_LINE
+
+
+endef
+
+export NEW_LINE
+
+LDFLAGS_DEBUG:=-L../alib2data/lib-debug -L../alib2algo/lib-debug -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+LDFLAGS_RELEASE:=-L../alib2data/lib-release -L../alib2algo/lib-release -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+OBJECTS_DEBUG:=$(patsubst src/%.cpp, obj-debug/%.o, $(shell find src/ -name *cpp))
+
+OBJECTS_RELEASE:=$(patsubst src/%.cpp, obj-release/%.o, $(shell find src/ -name *cpp))
+
+.PHONY: all build-debug clean-debug doc
+
+all:
+	@echo "What to do master?"
+
+obj%/makefile: makefile
+	mkdir -p $(dir $@)
+	echo "\
+	SHELL:=/bin/bash$${NEW_LINE}\
+	SRCDIR:=$${NEW_LINE}\
+	DEPTH:=$${NEW_LINE}\
+	OBJECTS_BASE_DIR:=$${NEW_LINE}\
+	$${NEW_LINE}\
+	define NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	$${NEW_LINE}\
+	endef$${NEW_LINE}\
+	$${NEW_LINE}\
+	export NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	CXXFLAGS:= -std=c++11 \$$(CXX_OTHER_FLAGS) -c -Wall -pedantic -Wextra -fPIC -I/usr/include/libxml2/ -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src/$${NEW_LINE}\
+	$${NEW_LINE}\
+	SOURCES:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")$${NEW_LINE}\
+	DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d, \$$(SOURCES))$${NEW_LINE}\
+	OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))$${NEW_LINE}\
+	SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)$${NEW_LINE}\
+	OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))$${NEW_LINE}\
+	OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))$${NEW_LINE}\
+	$${NEW_LINE}\
+	.PHONY: all$${NEW_LINE}\
+	.PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)$${NEW_LINE}\
+	$${NEW_LINE}\
+	all: \$$(OBJECTS_DIRS) \$$(OBJECTS)$${NEW_LINE}\
+	$${NEW_LINE}\
+	%.d: makefile$${NEW_LINE}\
+		@echo \"\\$${NEW_LINE}\
+		\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\")) makefile\$$\$${NEW_LINE}\\$${NEW_LINE}\
+			\\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\" > \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/makefile: makefile$${NEW_LINE}\
+		mkdir -p \$$(dir \$$@)$${NEW_LINE}\
+		cp makefile \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/: FORCE | %/makefile$${NEW_LINE}\
+		@accesstime=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		\$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ OBJECTS_BASE_DIR=\$$(OBJECTS_BASE_DIR) SOURCES_BASE_DIR=\$$(SOURCES_BASE_DIR) CXX_OTHER_FLAGS=\"\$$(CXX_OTHER_FLAGS)\" && \\$${NEW_LINE}\
+		accesstime2=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\$${NEW_LINE}\
+			touch .; \\$${NEW_LINE}\
+		fi$${NEW_LINE}\
+	$${NEW_LINE}\
+	FORCE:$${NEW_LINE}\
+	$${NEW_LINE}\
+	-include \$$(DEPENDENCIES)" > $@
+
+debug: build-debug
+
+release: build-release
+
+clean: clean-debug clean-release
+	$(RM) -r doc
+
+
+
+bin-debug/$(EXECUTABLE): obj-debug/ $(OBJECTS_DEBUG)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_DEBUG) -o $@ $(LDFLAGS_DEBUG)
+
+bin-release/$(EXECUTABLE): obj-release/ $(OBJECTS_RELEASE)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_RELEASE) -o $@ $(LDFLAGS_RELEASE)
+
+
+
+obj-debug/: FORCE | obj-debug/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-debug SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-g -O0"
+
+obj-release/: FORCE | obj-release/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-release SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-O3"
+
+
+
+$(OBJECTS_DEBUG): obj-debug/
+
+$(OBJECTS_RELEASE): obj-release/
+
+
+build-debug: bin-debug/$(EXECUTABLE)
+
+build-release: bin-release/$(EXECUTABLE)
+
+
+
+clean-debug:
+	$(RM) -r *.o *.d bin-debug obj-debug
+
+clean-release:
+	$(RM) -r *.o *.d bin-release obj-release
+
+
+
+FORCE:
+
+
+
+doc:
+	doxygen
+
diff --git a/tniceprint/src/tniceprint.cpp b/tniceprint/src/tniceprint.cpp
new file mode 100644
index 0000000000..16c108617a
--- /dev/null
+++ b/tniceprint/src/tniceprint.cpp
@@ -0,0 +1,58 @@
+/*
+ * acat.cpp
+ *
+ *  Created on: 24. 2. 2014
+ *      Author: Martin Zak
+ */
+
+#include <tclap/CmdLine.h>
+#include <string>
+#include <exception/AlibException.h>
+#include <factory/DataFactory.hpp>
+#include <sax/SaxParseInterface.h>
+#include <sax/ParserException.h>
+#include <tree/Tree.h>
+
+int main(int argc, char** argv) {
+	try {
+		TCLAP::CmdLine cmd("Tree nice print binary", ' ', "0.01");
+
+		TCLAP::ValueArg<std::string> input(	"i",	"input",	"Input to nice print",		false,	"-",		"file");
+		cmd.add( input );
+
+		cmd.parse(argc, argv);
+
+		std::list<sax::Token> tokens;
+		if(input.isSet()) {
+			if(input.getValue() == "-") {
+				sax::SaxParseInterface::parseStdin(tokens);
+			} else {
+				sax::SaxParseInterface::parseFile(input.getValue(), tokens);
+			}
+		} else {
+			sax::SaxParseInterface::parseStdin(tokens);
+		}
+
+		if (alib::DataFactory::first<tree::RankedTree>(tokens)) {
+			const tree::RankedTree & tree = alib::DataFactory::fromTokens<tree::RankedTree>(tokens);
+			tree.nicePrint();
+		} else if (alib::DataFactory::first<tree::UnrankedTree>(tokens)) {
+			const tree::UnrankedTree & tree = alib::DataFactory::fromTokens<tree::UnrankedTree>(tokens);
+			tree.nicePrint();
+		} else throw exception::AlibException("no tree on input");
+
+		return 0;
+	} catch(const exception::AlibException& exception) {
+		alib::DataFactory::toStdout(exception);
+		return 1;
+	} catch(const TCLAP::ArgException& exception) {
+		std::cerr << exception.error() << std::endl;
+		return 2;
+	} catch (const std::exception& exception) {
+		std::cerr << "Exception caught: " << exception.what() << std::endl;
+		return 3;
+	} catch(...) {
+		std::cerr << "Unknown exception caught." << std::endl;
+		return 127;
+	}
+}
diff --git a/trand/makefile b/trand/makefile
new file mode 100644
index 0000000000..2e073cb393
--- /dev/null
+++ b/trand/makefile
@@ -0,0 +1,128 @@
+SHELL:=/bin/bash
+EXECUTABLE:=trand
+
+define NEW_LINE
+
+
+endef
+
+export NEW_LINE
+
+LDFLAGS_DEBUG:=-L../alib2data/lib-debug -L../alib2algo/lib-debug -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+LDFLAGS_RELEASE:=-L../alib2data/lib-release -L../alib2algo/lib-release -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,.
+
+OBJECTS_DEBUG:=$(patsubst src/%.cpp, obj-debug/%.o, $(shell find src/ -name *cpp))
+
+OBJECTS_RELEASE:=$(patsubst src/%.cpp, obj-release/%.o, $(shell find src/ -name *cpp))
+
+.PHONY: all build-debug clean-debug doc
+
+all:
+	@echo "What to do master?"
+
+obj%/makefile: makefile
+	mkdir -p $(dir $@)
+	echo "\
+	SHELL:=/bin/bash$${NEW_LINE}\
+	SRCDIR:=$${NEW_LINE}\
+	DEPTH:=$${NEW_LINE}\
+	OBJECTS_BASE_DIR:=$${NEW_LINE}\
+	$${NEW_LINE}\
+	define NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	$${NEW_LINE}\
+	endef$${NEW_LINE}\
+	$${NEW_LINE}\
+	export NEW_LINE$${NEW_LINE}\
+	$${NEW_LINE}\
+	CXXFLAGS:= -std=c++11 \$$(CXX_OTHER_FLAGS) -c -Wall -pedantic -Wextra -fPIC -I/usr/include/libxml2/ -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src/$${NEW_LINE}\
+	$${NEW_LINE}\
+	SOURCES:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")$${NEW_LINE}\
+	DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d, \$$(SOURCES))$${NEW_LINE}\
+	OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))$${NEW_LINE}\
+	SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)$${NEW_LINE}\
+	OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))$${NEW_LINE}\
+	OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))$${NEW_LINE}\
+	$${NEW_LINE}\
+	.PHONY: all$${NEW_LINE}\
+	.PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)$${NEW_LINE}\
+	$${NEW_LINE}\
+	all: \$$(OBJECTS_DIRS) \$$(OBJECTS)$${NEW_LINE}\
+	$${NEW_LINE}\
+	%.d: makefile$${NEW_LINE}\
+		@echo \"\\$${NEW_LINE}\
+		\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\")) makefile\$$\$${NEW_LINE}\\$${NEW_LINE}\
+			\\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\$$\$${NEW_LINE}\\$${NEW_LINE}\
+		\" > \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/makefile: makefile$${NEW_LINE}\
+		mkdir -p \$$(dir \$$@)$${NEW_LINE}\
+		cp makefile \$$@$${NEW_LINE}\
+	$${NEW_LINE}\
+	%/: FORCE | %/makefile$${NEW_LINE}\
+		@accesstime=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		\$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ OBJECTS_BASE_DIR=\$$(OBJECTS_BASE_DIR) SOURCES_BASE_DIR=\$$(SOURCES_BASE_DIR) CXX_OTHER_FLAGS=\"\$$(CXX_OTHER_FLAGS)\" && \\$${NEW_LINE}\
+		accesstime2=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
+		if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\$${NEW_LINE}\
+			touch .; \\$${NEW_LINE}\
+		fi$${NEW_LINE}\
+	$${NEW_LINE}\
+	FORCE:$${NEW_LINE}\
+	$${NEW_LINE}\
+	-include \$$(DEPENDENCIES)" > $@
+
+debug: build-debug
+
+release: build-release
+
+clean: clean-debug clean-release
+	$(RM) -r doc
+
+
+
+bin-debug/$(EXECUTABLE): obj-debug/ $(OBJECTS_DEBUG)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_DEBUG) -o $@ $(LDFLAGS_DEBUG)
+
+bin-release/$(EXECUTABLE): obj-release/ $(OBJECTS_RELEASE)
+	mkdir -p $(dir $@)
+	$(CXX) $(OBJECTS_RELEASE) -o $@ $(LDFLAGS_RELEASE)
+
+
+
+obj-debug/: FORCE | obj-debug/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-debug SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-g -O0"
+
+obj-release/: FORCE | obj-release/makefile
+	$(MAKE) -C $@ OBJECTS_BASE_DIR=obj-release SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-O3"
+
+
+
+$(OBJECTS_DEBUG): obj-debug/
+
+$(OBJECTS_RELEASE): obj-release/
+
+
+build-debug: bin-debug/$(EXECUTABLE)
+
+build-release: bin-release/$(EXECUTABLE)
+
+
+
+clean-debug:
+	$(RM) -r *.o *.d bin-debug obj-debug
+
+clean-release:
+	$(RM) -r *.o *.d bin-release obj-release
+
+
+
+FORCE:
+
+
+
+doc:
+	doxygen
+
diff --git a/trand/src/trand.cpp b/trand/src/trand.cpp
new file mode 100644
index 0000000000..b82757e3b9
--- /dev/null
+++ b/trand/src/trand.cpp
@@ -0,0 +1,71 @@
+/*
+ * trand.cpp
+ *
+ *  Created on: 18. 3. 2015
+ *	  Author: Stepan Plachy
+ */
+
+#include <tclap/CmdLine.h>
+#include <climits>
+
+#include <tree/RankedTree/RankedTree.h>
+#include <tree/UnrankedTree/UnrankedTree.h>
+#include <factory/DataFactory.hpp>
+#include "tree/generate/RandomTreeFactory.h"
+
+int main(int argc, char* argv[]) {
+	try {
+		TCLAP::CmdLine cmd("Random tree generator binary", ' ', "0.01");
+
+		std::vector<std::string> allowed;
+		allowed.push_back("unranked");
+		allowed.push_back("ranked");
+		TCLAP::ValuesConstraint<std::string> allowedVals( allowed );
+
+		TCLAP::ValueArg<std::string> type(	"t",	"type",		"Type of generated tree",	true,	"unranked",	&allowedVals);
+		cmd.add( type );
+
+		TCLAP::ValueArg<int> alphabetSize(	"a",	"alphabetSize",	"Alphabet size, not guaranteed in ranked tree",		false,	3,	"integer");
+		cmd.add( alphabetSize );
+
+		TCLAP::ValueArg<double> maxRank(	"r",	"maxRank",	"Max rank of tree nodes",	false,	INT_MAX,	"integer");
+		cmd.add( maxRank );
+
+		TCLAP::ValueArg<int> nodes(		"n",	"nodes",	"Number of tree nodes",		false,	5,	"integer");
+		cmd.add( nodes );
+
+		TCLAP::ValueArg<int> depth(		"d",	"depth",	"Depth of the tree",	false,	3,	"integer");
+		cmd.add( depth );
+
+		cmd.parse(argc,argv);
+
+		if(!type.isSet()) throw exception::AlibException("Type is not defined.");
+		//if(!maxRank.isSet()) throw exception::AlibException("Rank is not defined.");
+		//if(!nodes.isSet()) throw exception::AlibException("Number of nodes is not defined.");
+		//if(!alphabetSize.isSet()) throw exception::AlibException("Alphabet size is not defined.");
+
+		if( type.getValue() == "unranked" ) {
+			tree::UnrankedTree res = tree::generate::RandomTreeFactory::generateUnrankedTree(depth.getValue(), nodes.getValue(), alphabetSize.getValue(), maxRank.getValue());
+			alib::DataFactory::toStdout(res);
+		} else if( type.getValue() == "ranked" ) {
+			tree::RankedTree res = tree::generate::RandomTreeFactory::generateRankedTree(depth.getValue(), nodes.getValue(), alphabetSize.getValue(), maxRank.getValue());
+			alib::DataFactory::toStdout(res);
+		} else {
+			throw exception::AlibException("Invalid type.");
+		}
+
+		return 0;
+	} catch( const exception::AlibException & exception ) {
+		alib::DataFactory::toStdout( exception );
+		return 1;
+	} 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;
+		return 3;
+	} catch(...) {
+		std::cerr << "Unknown exception caught." << std::endl;
+		return 127;
+	}
+}
-- 
GitLab