/*
 * RandomAutomatonFactory.h
 *
 *  Created on: 27. 3. 2014
 *      Author: Jan Travnicek
 */

#ifndef RANDOM_REG_EXP_FACTORY_H_
#define RANDOM_REG_EXP_FACTORY_H_

#include <alib/set>
#include <alib/ptr_vector>

#include <regexp/unbounded/UnboundedRegExp.h>

namespace regexp {

namespace generate {

/**
 * Generator of random regexps.
 *
 * The algorithm tries to generate a random regular expression with given number of leaf nodes and height.
 */
class RandomRegExpFactory {
public:
	/**
	 * Generates a random regular expression.
	 *
	 * \param leafNodes number of leaf nodes in the generated regexp
	 * \param height the height of the generated regular expression
	 * \param alphabetSize size of the alphabet (1-26)
	 * \param randomizedAlphabet selects random symbols from a-z range if true
	 *
	 * \return random regular expression
	 */
	static regexp::UnboundedRegExp < std::string > generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet );

	/**
	 * Generates a random regular expression.
	 *
	 * \tparam SymbolType the type of terminal symbols of the random automaton
	 *
	 * \param leafNodes number of leaf nodes in the generated regexp
	 * \param height the height of the generated regular expression
	 * \param alphabet the alphabet of the regular expression
	 *
	 * \return random regular expression
	 */
	template < class SymbolType >
	static regexp::UnboundedRegExp < SymbolType > generateUnboundedRegExp( size_t leafNodes, size_t height, ext::set < SymbolType > alphabet);

private:
	template < class SymbolType >
	static regexp::UnboundedRegExp < SymbolType > SimpleUnboundedRegExp( size_t n, size_t h, const ext::ptr_vector < regexp::UnboundedRegExpElement < SymbolType > > & elems);

	template < class SymbolType >
	static ext::ptr_value < regexp::UnboundedRegExpElement < SymbolType > > SimpleUnboundedRegExpElement(size_t n, size_t h, const ext::ptr_vector < regexp::UnboundedRegExpElement < SymbolType > > & elems);
};

} /* namespace generate */

} /* namespace regexp */

#endif /* RANDOM_REG_EXP_FACTORY_H_ */
