From ad0372b1f7c448dfd1145ee00a8bc5edd81fba32 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 11 Sep 2017 19:03:13 +0200
Subject: [PATCH] use cli in rand binary

---
 .../automaton/generate/RandomizeAutomaton.cpp |  12 +-
 .../automaton/generate/RandomizeAutomaton.h   |   7 +-
 .../grammar/generate/RandomGrammarFactory.cpp |   5 +-
 .../src/grammar/generate/RandomizeGrammar.cpp |  15 +-
 .../src/grammar/generate/RandomizeGrammar.h   |   6 +-
 .../regexp/generate/RandomRegExpFactory.cpp   |   6 +
 .../string/generate/RandomStringFactory.cpp   |   8 +
 .../generate/RandomSubstringFactory.cpp       |   6 +-
 .../string/generate/RandomSubstringFactory.h  |   8 +-
 .../src/tree/generate/RandomTreeFactory.cpp   |  22 +-
 .../src/tree/generate/RandomTreeFactory.h     |  22 +-
 .../src/abstraction/PrimitiveRegistrator.cpp  |   1 +
 arand2/makefile.conf                          |   6 +-
 arand2/src/arand.cpp                          | 197 +++++++-----------
 14 files changed, 147 insertions(+), 174 deletions(-)

diff --git a/alib2algo/src/automaton/generate/RandomizeAutomaton.cpp b/alib2algo/src/automaton/generate/RandomizeAutomaton.cpp
index bb02784f74..7439113ffd 100644
--- a/alib2algo/src/automaton/generate/RandomizeAutomaton.cpp
+++ b/alib2algo/src/automaton/generate/RandomizeAutomaton.cpp
@@ -13,14 +13,10 @@ namespace automaton {
 
 namespace generate {
 
-auto RandomizeAutomatonDFA = registration::OverloadRegister < RandomizeAutomaton, automaton::DFA < >, automaton::DFA < > > ( RandomizeAutomaton::randomize );
-auto RandomizeAutomatonMultiInitialStateNFA = registration::OverloadRegister < RandomizeAutomaton, automaton::MultiInitialStateNFA < >, automaton::MultiInitialStateNFA < > > ( RandomizeAutomaton::randomize );
-auto RandomizeAutomatonNFA = registration::OverloadRegister < RandomizeAutomaton, automaton::NFA < >, automaton::NFA < > > ( RandomizeAutomaton::randomize );
-auto RandomizeAutomatonEpsilonNFA = registration::OverloadRegister < RandomizeAutomaton, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( RandomizeAutomaton::randomize );
-
-automaton::Automaton RandomizeAutomaton::randomize ( const automaton::Automaton & automaton ) {
-	return dispatch ( automaton.getData ( ) );
-}
+auto RandomizeAutomatonDFA = registration::AbstractRegister < RandomizeAutomaton, automaton::DFA < >, const automaton::DFA < > & > ( RandomizeAutomaton::randomize );
+auto RandomizeAutomatonMultiInitialStateNFA = registration::AbstractRegister < RandomizeAutomaton, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( RandomizeAutomaton::randomize );
+auto RandomizeAutomatonNFA = registration::AbstractRegister < RandomizeAutomaton, automaton::NFA < >, const automaton::NFA < > & > ( RandomizeAutomaton::randomize );
+auto RandomizeAutomatonEpsilonNFA = registration::AbstractRegister < RandomizeAutomaton, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( RandomizeAutomaton::randomize );
 
 } /* namespace generate */
 
diff --git a/alib2algo/src/automaton/generate/RandomizeAutomaton.h b/alib2algo/src/automaton/generate/RandomizeAutomaton.h
index 3b962f1fd2..33b0b05ee2 100644
--- a/alib2algo/src/automaton/generate/RandomizeAutomaton.h
+++ b/alib2algo/src/automaton/generate/RandomizeAutomaton.h
@@ -8,9 +8,6 @@
 #ifndef AUTOMATON_RANDOMIZE_H_
 #define AUTOMATON_RANDOMIZE_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 #include <automaton/FSM/MultiInitialStateNFA.h>
 #include <automaton/FSM/NFA.h>
@@ -22,10 +19,8 @@ namespace automaton {
 
 namespace generate {
 
-class RandomizeAutomaton : public alib::SingleDispatch < RandomizeAutomaton, automaton::Automaton, const automaton::AutomatonBase & > {
+class RandomizeAutomaton {
 public:
-	static automaton::Automaton randomize ( const automaton::Automaton & automaton );
-
 	template < class SymbolType, class EpsilonType, class StateType >
 	static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > randomize( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm );
 	template < class SymbolType, class StateType >
diff --git a/alib2algo/src/grammar/generate/RandomGrammarFactory.cpp b/alib2algo/src/grammar/generate/RandomGrammarFactory.cpp
index cb20f83085..0a76d5309d 100644
--- a/alib2algo/src/grammar/generate/RandomGrammarFactory.cpp
+++ b/alib2algo/src/grammar/generate/RandomGrammarFactory.cpp
@@ -7,7 +7,6 @@
 
 #include "RandomGrammarFactory.h"
 #include <exception/CommonException.h>
-#include <grammar/Grammar.h>
 
 #include <algorithm>
 #include <random>
@@ -23,6 +22,8 @@ grammar::CFG < > RandomGrammarFactory::generateCFG( ext::set<DefaultSymbolType>
 	return RandomGrammarFactory::randomCFG( nonterminals2, terminals2, density );
 }
 
+auto GenerateCFG1 = registration::AbstractRegister < RandomGrammarFactory, grammar::CFG < >, ext::set < DefaultSymbolType >, ext::set < DefaultSymbolType >, double > ( RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminals", "terminals", "density" );
+
 grammar::CFG < > RandomGrammarFactory::generateCFG( size_t nonterminalsCount, size_t terminalsCount, bool randomizedAlphabet, double density ) {
 	if(terminalsCount > 26)
 		throw exception::CommonException("Too big terminals count.");
@@ -43,6 +44,8 @@ grammar::CFG < > RandomGrammarFactory::generateCFG( size_t nonterminalsCount, si
 	return RandomGrammarFactory::randomCFG( nonterminals, terminals, density );
 }
 
+auto GenerateCFG2 = registration::AbstractRegister < RandomGrammarFactory, grammar::CFG < >, size_t, size_t, bool, double> ( RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminalsCount", "terminalsCount", "randomizedAlphabet", "density" );
+
 grammar::CFG < > RandomGrammarFactory::randomCFG( const ext::deque<DefaultSymbolType>& nonterminals, const ext::deque<DefaultSymbolType> & terminals, double density ) {
 	if( terminals.size( ) <= 0 )
 		throw exception::CommonException( "Terminals count must be greater than 0." );
diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.cpp b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp
index b349b0d339..e8b69b1254 100644
--- a/alib2algo/src/grammar/generate/RandomizeGrammar.cpp
+++ b/alib2algo/src/grammar/generate/RandomizeGrammar.cpp
@@ -6,22 +6,17 @@
  */
 
 #include "RandomizeGrammar.h"
-#include <grammar/Grammar.h>
 #include <registration/AlgoRegistration.hpp>
 
 namespace grammar {
 
 namespace generate {
 
-auto RandomizeGrammarLeftRG = registration::OverloadRegister < RandomizeGrammar, grammar::LeftRG < >, grammar::LeftRG < > > ( RandomizeGrammar::randomize );
-auto RandomizeGrammarLeftLG = registration::OverloadRegister < RandomizeGrammar, grammar::LeftLG < >, grammar::LeftLG < > > ( RandomizeGrammar::randomize );
-auto RandomizeGrammarRightRG = registration::OverloadRegister < RandomizeGrammar, grammar::RightRG < >, grammar::RightRG < > > ( RandomizeGrammar::randomize );
-auto RandomizeGrammarRightLG = registration::OverloadRegister < RandomizeGrammar, grammar::RightLG < >, grammar::RightLG < > > ( RandomizeGrammar::randomize );
-auto RandomizeGrammarCFG = registration::OverloadRegister < RandomizeGrammar, grammar::CFG < >, grammar::CFG < > > ( RandomizeGrammar::randomize );
-
-grammar::Grammar RandomizeGrammar::randomize ( const grammar::Grammar & grammar ) {
-	return dispatch ( grammar.getData ( ) );
-}
+auto RandomizeGrammarLeftRG = registration::AbstractRegister < RandomizeGrammar, grammar::LeftRG < >, const grammar::LeftRG < > & > ( RandomizeGrammar::randomize );
+auto RandomizeGrammarLeftLG = registration::AbstractRegister < RandomizeGrammar, grammar::LeftLG < >, const grammar::LeftLG < > & > ( RandomizeGrammar::randomize );
+auto RandomizeGrammarRightRG = registration::AbstractRegister < RandomizeGrammar, grammar::RightRG < >, const grammar::RightRG < > & > ( RandomizeGrammar::randomize );
+auto RandomizeGrammarRightLG = registration::AbstractRegister < RandomizeGrammar, grammar::RightLG < >, const grammar::RightLG < > & > ( RandomizeGrammar::randomize );
+auto RandomizeGrammarCFG = registration::AbstractRegister < RandomizeGrammar, grammar::CFG < >, const grammar::CFG < > & > ( RandomizeGrammar::randomize );
 
 } /* namespace generate */
 
diff --git a/alib2algo/src/grammar/generate/RandomizeGrammar.h b/alib2algo/src/grammar/generate/RandomizeGrammar.h
index f963347ed6..ef927fea94 100644
--- a/alib2algo/src/grammar/generate/RandomizeGrammar.h
+++ b/alib2algo/src/grammar/generate/RandomizeGrammar.h
@@ -8,8 +8,6 @@
 #ifndef GRAMMAR_RANDOMIZE_H_
 #define GRAMMAR_RANDOMIZE_H_
 
-#include <core/multipleDispatch.hpp>
-
 #include <grammar/Grammar.h>
 #include <grammar/Regular/LeftLG.h>
 #include <grammar/Regular/LeftRG.h>
@@ -23,10 +21,8 @@ namespace grammar {
 
 namespace generate {
 
-class RandomizeGrammar : public alib::SingleDispatch < RandomizeGrammar, grammar::Grammar, const grammar::GrammarBase & > {
+class RandomizeGrammar {
 public:
-	static grammar::Grammar randomize ( const grammar::Grammar & grammar );
-
 	template < class SymbolType >
 	static grammar::LeftRG < SymbolType > randomize ( const grammar::LeftRG < SymbolType > & gram );
 	template < class SymbolType >
diff --git a/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
index d4adb6d836..8b176d58b9 100644
--- a/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
+++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
@@ -12,6 +12,8 @@
 #include <algorithm>
 #include <random>
 
+#include <registration/AlgoRegistration.hpp>
+
 namespace regexp {
 
 namespace generate {
@@ -31,6 +33,8 @@ regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t
 	return RandomRegExpFactory::generateUnboundedRegExp( leafNodes, height, alphabet );
 }
 
+auto GenerateUnboundedRegExp1 = registration::AbstractRegister < RandomRegExpFactory, regexp::UnboundedRegExp < >, size_t, size_t, size_t, bool > ( RandomRegExpFactory::generateUnboundedRegExp, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "leafNodes", "height", "alphabetSize", "randomizedAlphabet" );
+
 regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, ext::set<DefaultSymbolType> alphabet) {
 
 	if( alphabet.size() > 26)
@@ -66,6 +70,8 @@ regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t
 	return res;
 }
 
+auto GenerateUnboundedRegExp2 = registration::AbstractRegister < RandomRegExpFactory, regexp::UnboundedRegExp < >, size_t, size_t, size_t, bool > ( RandomRegExpFactory::generateUnboundedRegExp, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "leafNodes", "height", "alphabet" );
+
 regexp::UnboundedRegExp < > RandomRegExpFactory::SimpleUnboundedRegExp( size_t n, size_t h, const ext::vector<const regexp::UnboundedRegExpElement < DefaultSymbolType > * > & elems) {
 	return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < DefaultSymbolType > ( SimpleUnboundedRegExpElement (n, h, elems)));
 }
diff --git a/alib2algo/src/string/generate/RandomStringFactory.cpp b/alib2algo/src/string/generate/RandomStringFactory.cpp
index 122eced2f8..71f3f67e68 100644
--- a/alib2algo/src/string/generate/RandomStringFactory.cpp
+++ b/alib2algo/src/string/generate/RandomStringFactory.cpp
@@ -13,6 +13,8 @@
 
 #include <exception/CommonException.h>
 
+#include <registration/AlgoRegistration.hpp>
+
 namespace string {
 
 namespace generate {
@@ -31,6 +33,8 @@ string::LinearString < > RandomStringFactory::generateLinearString ( size_t size
 	return string::LinearString < > ( elems );
 }
 
+auto GenerateLinearString1 = registration::AbstractRegister < RandomStringFactory, string::LinearString < >, size_t, size_t, bool, bool > ( RandomStringFactory::generateLinearString, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "size", "alphabetSize", "randomizedAlphabet", "integerSymbols" );
+
 string::LinearString < > RandomStringFactory::generateLinearString ( size_t size, size_t alphabetSize, bool randomizedAlphabet ) {
 	if ( alphabetSize > 26 )
 		throw exception::CommonException ( "Too big alphabet." );
@@ -49,6 +53,8 @@ string::LinearString < > RandomStringFactory::generateLinearString ( size_t size
 	return RandomStringFactory::generateLinearString ( size, alphabet );
 }
 
+auto GenerateLinearString2 = registration::AbstractRegister < RandomStringFactory, string::LinearString < >, size_t, size_t, bool > ( RandomStringFactory::generateLinearString, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "size", "alphabetSize", "randomizedAlphabet" );
+
 string::LinearString < > RandomStringFactory::generateLinearString ( size_t size, ext::set < DefaultSymbolType > alphabet ) {
 
 	if ( alphabet.size ( ) > 26 )
@@ -66,6 +72,8 @@ string::LinearString < > RandomStringFactory::generateLinearString ( size_t size
 	return string::LinearString < > ( elems );
 }
 
+auto GenerateLinearString3 = registration::AbstractRegister < RandomStringFactory, string::LinearString < >, size_t, ext::set < DefaultSymbolType > > ( RandomStringFactory::generateLinearString, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "size", "alphabet" );
+
 } /* namespace generate */
 
 } /* namespace string */
diff --git a/alib2algo/src/string/generate/RandomSubstringFactory.cpp b/alib2algo/src/string/generate/RandomSubstringFactory.cpp
index be69bb6f0d..68646544e5 100644
--- a/alib2algo/src/string/generate/RandomSubstringFactory.cpp
+++ b/alib2algo/src/string/generate/RandomSubstringFactory.cpp
@@ -12,11 +12,7 @@ namespace string {
 
 namespace generate {
 
-string::String RandomSubstringFactory::generateSubstring ( size_t size, const string::String & v ) {
-	return dispatch ( size, v.getData ( ) );
-}
-
-auto RandomSubstringFactoryLinearString = registration::OverloadRegister < RandomSubstringFactory, string::LinearString < >, string::LinearString < > > ( RandomSubstringFactory::generateSubstring );
+auto RandomSubstringFactoryLinearString = registration::AbstractRegister < RandomSubstringFactory, string::LinearString < >, size_t, const string::LinearString < > & > ( RandomSubstringFactory::generateSubstring );
 
 } /* namespace generate */
 
diff --git a/alib2algo/src/string/generate/RandomSubstringFactory.h b/alib2algo/src/string/generate/RandomSubstringFactory.h
index 1048c0ec66..2dc698991c 100644
--- a/alib2algo/src/string/generate/RandomSubstringFactory.h
+++ b/alib2algo/src/string/generate/RandomSubstringFactory.h
@@ -8,10 +8,6 @@
 #ifndef RANDOM_SUBSTRING_FACTORY_H_
 #define RANDOM_SUBSTRING_FACTORY_H_
 
-#include <core/multipleDispatch.hpp>
-#include <string/String.h>
-#include <string/StringFeatures.h>
-
 #include <algorithm>
 #include <random>
 #include <exception/CommonException.h>
@@ -22,10 +18,8 @@ namespace string {
 
 namespace generate {
 
-class RandomSubstringFactory : public alib::SingleDispatchFirstStaticParam < RandomSubstringFactory, string::String, size_t, const string::StringBase & > {
+class RandomSubstringFactory {
 public:
-	static string::String generateSubstring ( size_t size, const string::String & );
-
 	template < class SymbolType >
 	static string::LinearString < SymbolType > generateSubstring ( size_t size, const string::LinearString < SymbolType > & );
 
diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
index 173ecb5921..0944eb1baa 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.cpp
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
@@ -23,6 +23,8 @@
 #include <exception/CommonException.h>
 #include <alphabet/RankedSymbol.h>
 
+#include <registration/AlgoRegistration.hpp>
+
 namespace tree {
 
 namespace generate {
@@ -282,7 +284,7 @@ Node * generateTreeStructure ( int depth, int nodesCount, int maxRank = INT_MAX
 	return root;
 }
 
-UnrankedTree < > RandomTreeFactory::generateUnrankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+UnrankedTree < > RandomUnrankedTreeFactory::generateUnrankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
 	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
 	ext::vector < char > alphabet = generateUnrankedAlphabet ( maxAlphabetSize, randomizedAlphabet );
 
@@ -298,7 +300,9 @@ UnrankedTree < > RandomTreeFactory::generateUnrankedTree ( int depth, int nodesC
 	return tree;
 }
 
-UnrankedPattern < > RandomTreeFactory::generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+auto GenerateUnrankedTree = registration::AbstractRegister < RandomUnrankedTreeFactory, tree::UnrankedTree < >, int, int, int, bool, int > ( RandomUnrankedTreeFactory::generateUnrankedTree, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "depth", "nodesCount", "maxAlphabetSize", "randomizedAlphabet", "maxRank" );
+
+UnrankedPattern < > RandomUnrankedPatternFactory::generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
 	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
 	ext::vector < char > alphabet = generateUnrankedAlphabet ( maxAlphabetSize, randomizedAlphabet );
 
@@ -316,7 +320,9 @@ UnrankedPattern < > RandomTreeFactory::generateUnrankedPattern ( int depth, int
 	return tree;
 }
 
-RankedTree < > RandomTreeFactory::generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+auto GenerateUnrankedPattern = registration::AbstractRegister < RandomUnrankedPatternFactory, tree::UnrankedPattern < >, int, int, int, bool, int > ( RandomUnrankedPatternFactory::generateUnrankedPattern, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "depth", "nodesCount", "maxAlphabetSize", "randomizedAlphabet", "maxRank" );
+
+RankedTree < > RandomRankedTreeFactory::generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
 	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
 	ext::map < int, ext::vector < char > > rankedAlphabet;
 
@@ -335,7 +341,9 @@ RankedTree < > RandomTreeFactory::generateRankedTree ( int depth, int nodesCount
 	return tree;
 }
 
-RankedPattern < > RandomTreeFactory::generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+auto GenerateRankedTree = registration::AbstractRegister < RandomRankedTreeFactory, tree::RankedTree < >, int, int, int, bool, int > ( RandomRankedTreeFactory::generateRankedTree, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "depth", "nodesCount", "maxAlphabetSize", "randomizedAlphabet", "maxRank" );
+
+RankedPattern < > RandomRankedPatternFactory::generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
 	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
 	ext::map < int, ext::vector < char > > rankedAlphabet;
 
@@ -356,7 +364,9 @@ RankedPattern < > RandomTreeFactory::generateRankedPattern ( int depth, int node
 	return tree;
 }
 
-RankedNonlinearPattern < > RandomTreeFactory::generateRankedNonlinearPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, bool singleNonlinearVariable, int maxRank ) {
+auto GenerateRankedPattern = registration::AbstractRegister < RandomRankedPatternFactory, tree::RankedPattern < >, int, int, int, bool, int > ( RandomRankedPatternFactory::generateRankedPattern, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "depth", "nodesCount", "randomizedAlphabet", "maxAlphabetSize", "maxRank" );
+
+RankedNonlinearPattern < > RandomRankedNonlinearPatternFactory::generateRankedNonlinearPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, bool singleNonlinearVariable, int maxRank ) {
 	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
 	ext::map < int, ext::vector < char > > rankedAlphabet;
 
@@ -385,6 +395,8 @@ RankedNonlinearPattern < > RandomTreeFactory::generateRankedNonlinearPattern ( i
 	return tree;
 }
 
+auto GenerateRankedNonlinearPattern = registration::AbstractRegister < RandomRankedNonlinearPatternFactory, tree::RankedNonlinearPattern < >, int, int, int, bool, bool, int > ( RandomRankedNonlinearPatternFactory::generateRankedNonlinearPattern, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "depth", "nodesCount", "maxAlphabetSize", "randomizedAlphabet", "singleNonlinearVariable", "maxRank" );
+
 } /* namespace generate */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.h b/alib2algo/src/tree/generate/RandomTreeFactory.h
index 10f8d86709..08831a54cb 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.h
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.h
@@ -8,8 +8,6 @@
 #ifndef RANDOM_TREE_FACTORY_H_
 #define RANDOM_TREE_FACTORY_H_
 
-#include <deque>
-#include <set>
 #include <climits>
 
 #include <tree/ranked/RankedTree.h>
@@ -22,15 +20,29 @@ namespace tree {
 
 namespace generate {
 
-class RandomTreeFactory {
+class RandomRankedTreeFactory {
 public:
 	static tree::RankedTree < > generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+};
+
+class RandomRankedPatternFactory {
+public:
 	static tree::RankedPattern < > generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+};
+
+class RandomRankedNonlinearPatternFactory {
+public:
 	static tree::RankedNonlinearPattern < > generateRankedNonlinearPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, bool singleNonlinearVariable, int maxRank = INT_MAX );
+};
+
+class RandomUnrankedTreeFactory {
+public:
 	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:
+class RandomUnrankedPatternFactory {
+public:
+	static tree::UnrankedPattern < > generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 };
 
 } /* namespace generate */
diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
index 9fbc139828..fa16f2a902 100644
--- a/alib2common/src/abstraction/PrimitiveRegistrator.cpp
+++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
@@ -37,6 +37,7 @@ public:
 		abstraction::CastRegistry::registerCast < bool, int > ( false );
 		abstraction::CastRegistry::registerCastAlgorithm < bool, std::string > ( ( bool ( * ) ( std::string ) ) ext::from_string < bool >, false );
 		abstraction::CastRegistry::registerCastAlgorithm < unsigned, std::string > ( "unsigned", ext::to_string < std::string > ( ), ( unsigned ( * ) ( std::string ) ) ext::from_string < unsigned >, false );
+		abstraction::CastRegistry::registerCastAlgorithm < double, std::string > ( ( double ( * ) ( std::string ) ) ext::from_string < double >, false );
 
 		abstraction::CastRegistry::registerCast < size_t, int > ( "size_t", ext::to_string < int > ( ), false );
 		abstraction::CastRegistry::registerCast < size_t, int > ( false );
diff --git a/arand2/makefile.conf b/arand2/makefile.conf
index 49c99c7c05..0abaa7509b 100644
--- a/arand2/makefile.conf
+++ b/arand2/makefile.conf
@@ -1,4 +1,4 @@
 EXECUTABLE:=arand2
-LINK_PATHS=../alib2elgo/ ../alib2algo/ ../alib2data/ ../alib2common/ ../alib2std/
-LINK_LIBRARIES=alib2elgo alib2algo alib2data alib2common alib2std xml2
-INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2elgo/src/ \$$(SOURCES_BASE_DIR)/../../alib2algo/src/ \$$(SOURCES_BASE_DIR)/../../alib2data/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/
+LINK_PATHS=../alib2cli/ ../alib2elgo/ ../alib2algo/ ../alib2data/ ../alib2common/ ../alib2std/
+LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2data alib2common alib2std xml2
+INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2cli/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index a063600b88..d8c2651b6f 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -9,18 +9,10 @@
 #include <global/GlobalData.h>
 #include <measure>
 #include <random>
-#include <sax/FromXMLParserHelper.h>
-
-#include <string/String.h>
-#include <factory/XmlDataFactory.hpp>
-#include "automaton/generate/RandomAutomatonFactory.h"
-#include "grammar/generate/RandomGrammarFactory.h"
-#include "regexp/generate/RandomRegExpFactory.h"
-#include "string/generate/RandomStringFactory.h"
-#include "string/generate/RandomSubstringFactory.h"
-#include "tree/generate/RandomTreeFactory.h"
-#include <automaton/generate/RandomizeAutomaton.h>
-#include <grammar/generate/RandomizeGrammar.h>
+
+#include <exception/CommonException.h>
+#include <lexer/Lexer.h>
+#include <parser/Parser.h>
 
 int main ( int argc, char * argv[] ) {
 	try {
@@ -71,8 +63,8 @@ int main ( int argc, char * argv[] ) {
 		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 > leaves ( "", "leaves", "Number of tree's/regexp's terminal nodes", false, 5, "integer" );
+		cmd.add ( leaves );
 
 		TCLAP::ValueArg < int > height ( "", "height", "Height of the tree/regexp", false, 3, "integer" );
 		cmd.add ( height );
@@ -80,8 +72,8 @@ int main ( int argc, char * argv[] ) {
 		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 > rank ( "", "rank", "Maximal rank of tree nodes", false, 5, "integer" );
+		cmd.add ( rank );
 
 		TCLAP::SwitchArg singleNonlinearVariable ( "", "single_nonlinear_variable", "Generate single nonlinear variable", false );
 		cmd.add ( singleNonlinearVariable );
@@ -106,136 +98,103 @@ int main ( int argc, char * argv[] ) {
 		if ( seed.isSet ( ) )
 			ext::random_devices::semirandom.seed ( seed.getValue ( ) );
 
-		measurements::start ( "Overal", measurements::Type::OVERALL );
-
-		if ( !type.isSet ( ) ) throw exception::CommonException ( "Type is not defined." );
-
-		if ( type.getValue ( ) == "FSM" ) {
-			if ( ( density.getValue ( ) < 1 ) || ( density.getValue ( ) > 100 ) )
-				 // TODO: floating point arithmetic
-				throw exception::CommonException ( "You must specify density as a number between 1 and 100." );
-
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
+		cli::Environment environment;
+		environment.setBinding ( "stdout", "-" );
 
-			automaton::NFA < > res = automaton::generate::RandomAutomatonFactory::generateNFA ( states.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
+		environment.setBinding ( "alphabetSize", ext::to_string ( alphabetSize.getValue ( ) ) );
 
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+		if ( integerSymbols.isSet ( ) )
+			environment.setBinding ( "integerSymbols", "true" );
+		else
+			environment.setBinding ( "integerSymbols", "false" );
 
-			alib::XmlDataFactory::toStdout ( res );
-		} else if ( type.getValue ( ) == "RFSM" ) {
-			automaton::Automaton baseAutomaton = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput ( input ) );
+		if ( randomizedAlphabet.isSet ( ) )
+			environment.setBinding ( "randomizedAlphabet", "true" );
+		else
+			environment.setBinding ( "randomizedAlphabet", "false" );
 
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
+		if ( ( density.getValue ( ) < 1 ) || ( density.getValue ( ) > 100 ) )
+			throw exception::CommonException ( "You must specify density as a number between 1 and 100." );
+		else
+			environment.setBinding ( "density", ext::to_string ( density.getValue ( ) ) );
 
-			automaton::Automaton res = automaton::generate::RandomizeAutomaton::randomize ( baseAutomaton );
+		environment.setBinding ( "nonterminals", ext::to_string ( nonterminals.getValue ( ) ) );
 
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+		environment.setBinding ( "nodes", ext::to_string ( nodes.getValue ( ) ) );
 
-			alib::XmlDataFactory::toStdout ( res );
-		} else if ( type.getValue ( ) == "CFG" ) {
-			if ( ( density.getValue ( ) < 1 ) || ( density.getValue ( ) > 100 ) )
-				 // TODO: floating point arithmetic
-				throw exception::CommonException ( "You must specify density as a number between 1 and 100." );
+		environment.setBinding ( "states", ext::to_string ( states.getValue ( ) ) );
 
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
+		environment.setBinding ( "leaves", ext::to_string ( leaves.getValue ( ) ) );
 
-			grammar::CFG < > res = grammar::generate::RandomGrammarFactory::generateCFG ( nonterminals.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
+		environment.setBinding ( "height", ext::to_string ( height.getValue ( ) ) );
 
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+		environment.setBinding ( "length", ext::to_string ( length.getValue ( ) ) );
 
-			alib::XmlDataFactory::toStdout ( res );
-		} else if ( type.getValue ( ) == "RCFG" ) {
-			grammar::Grammar baseGrammar = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput ( input ) );
+		environment.setBinding ( "rank", ext::to_string ( rank.getValue ( ) ) );
 
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
+		if ( singleNonlinearVariable.isSet ( ) )
+			environment.setBinding ( "singleNonlinearVariable", "true" );
+		else
+			environment.setBinding ( "singleNonlinearVariable", "false" );
 
-			grammar::Grammar res = grammar::generate::RandomizeGrammar::randomize ( baseGrammar );
+		measurements::start ( "Overal", measurements::Type::OVERALL );
+		measurements::start ( "Input read", measurements::Type::AUXILIARY );
+
+		if ( type.getValue ( ) == "RFSM"
+		  || type.getValue ( ) == "RCFG"
+		  || type.getValue ( ) == "SST" ) {
+			std::string inputFile;
+			if ( ! input.isSet ( ) )
+				inputFile = "-";
+			else
+				inputFile = input.getValue ( );
+
+			environment.setBinding ( "input", inputFile );
+			cli::Parser parser ( cli::Lexer ( "execute <#input > $input" ) );
+			parser.parse ( )->run ( environment );
+		}
 
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+		measurements::end ( );
+		measurements::start ( "Algorithm", measurements::Type::MAIN );
 
-			alib::XmlDataFactory::toStdout ( res );
+		std::string cliCommand;
+		if ( type.getValue ( ) == "FSM" ) {
+			cliCommand = "execute automaton::generate::RandomAutomatonFactory (int) #states (int) #alphabetSize (bool) #randomizedAlphabet (double) #density > $output";
+		} else if ( type.getValue ( ) == "RFSM" ) {
+			cliCommand = "execute automaton::generate::RandomizeAutomaton (int) #baseAutomaton > $output";
+		} else if ( type.getValue ( ) == "CFG" ) {
+			cliCommand = "execute grammar::generate::RandomGrammarFactory (int) #nonterminals (int) #alphabetSize (bool) #randomizedAlphabet (double) #density > $output";
+		} else if ( type.getValue ( ) == "RCFG" ) {
+			cliCommand = "execute grammar::generate::RandomizeGrammar (int) #baseGrammar > $output";
 		} else if ( type.getValue ( ) == "RE" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			regexp::UnboundedRegExp < > res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp ( terminalNodes.getValue ( ), height.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute regexp::generate::RandomRegExpFactory (int) #leaves (int) #height (int) #alphabetSize (bool) #randomizedAlphabet > $output";
 		} else if ( type.getValue ( ) == "ST" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			string::LinearString < > res = string::generate::RandomStringFactory::generateLinearString ( length.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), integerSymbols.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute string::generate::RandomStringFactory (int) #length (int) #alphabetSize (bool) #randomizedAlphabet (bool) #integerSymbols > $output";
 		} else if ( type.getValue ( ) == "SST" ) {
-			string::String baseString = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput ( input ) );
-
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			string::String res = string::generate::RandomSubstringFactory::generateSubstring ( length.getValue ( ), baseString );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute string::generate::RandomSubstringFactory (int) #length (int) #baseString > $output";
 		} else if ( type.getValue ( ) == "UT" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			tree::UnrankedTree < > res = tree::generate::RandomTreeFactory::generateUnrankedTree ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute tree::generate::RandomUnrankedTreeFactory (int) #height (int) #nodes (int) #alphabetSize (bool) #randomizedAlphabet (int) #rank > $output";
 		} else if ( type.getValue ( ) == "UP" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			tree::UnrankedPattern < > res = tree::generate::RandomTreeFactory::generateUnrankedPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute tree::generate::RandomUnrankedPatternFactory (int) #height (int) #nodes (int) #alphabetSize (bool) #randomizedAlphabet (int) #rank > $output";
 		} else if ( type.getValue ( ) == "RT" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			tree::RankedTree < > res = tree::generate::RandomTreeFactory::generateRankedTree ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute tree::generate::RandomRankedTreeFactory (int) #height (int) #nodes (int) #alphabetSize (bool) #randomizedAlphabet (int) #rank > $output";
 		} else if ( type.getValue ( ) == "RP" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			tree::RankedPattern < > res = tree::generate::RandomTreeFactory::generateRankedPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute tree::generate::RandomRankedPatternFactory (int) #height (int) #nodes (int) #alphabetSize (bool) #randomizedAlphabet (int) #rank > $output";
 		} else if ( type.getValue ( ) == "RNP" ) {
-			measurements::start ( "Algorithm", measurements::Type::MAIN );
-
-			tree::RankedNonlinearPattern < > res = tree::generate::RandomTreeFactory::generateRankedNonlinearPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), singleNonlinearVariable.getValue ( ), maxRank.getValue ( ) );
-
-			measurements::end ( );
-			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-
-			alib::XmlDataFactory::toStdout ( res );
+			cliCommand = "execute tree::generate::RandomRankedNonlinearPatternFactory (int) #height (int) #nodes (int) #alphabetSize (bool) #randomizedAlphabet (bool) #singleNonlinearVariable (int) #rank > $output";
 		} else {
 			throw exception::CommonException ( "Invalid type." );
 		}
 
+		cli::Parser parser = cli::Parser ( cli::Lexer ( cliCommand ) );
+		parser.parse ( )->run ( environment );
+
+		measurements::end ( );
+		measurements::start ( "Output write", measurements::Type::AUXILIARY );
+
+		parser = cli::Parser ( cli::Lexer ( "execute $output >#stdout" ) );
+		parser.parse ( )->run ( environment );
+
 		measurements::end ( );
 		measurements::end ( );
 
-- 
GitLab