/*
 * RandomGrammarFactory.cpp
 *
 *  Created on: 27. 3. 2014
 *	  Author: Tomas Pecka
 */

#include "RandomGrammarFactory.h"
#include <registration/AlgoRegistration.hpp>

namespace grammar {

namespace generate {

grammar::CFG < std::string, std::string > grammar::generate::RandomGrammarFactory::generateCFG ( size_t nonterminalsCount, size_t terminalsCount, bool randomizedAlphabet, double density ) {
	if(terminalsCount > 26)
		throw exception::CommonException("Too big terminals count.");

	ext::deque < std::string > terminals;
	for ( char i = 'a'; i <= 'z'; i ++ )
		terminals.push_back ( std::string ( 1, i ) );

	if(randomizedAlphabet)
		shuffle ( terminals.begin ( ), terminals.end ( ), ext::random_devices::semirandom );

	terminals.resize ( terminalsCount );

	if(nonterminalsCount > 26)
		throw exception::CommonException("Too big nonterminals count.");

	ext::deque < std::string > nonterminals;
	for ( char i = 'A'; i <= 'Z'; i ++ )
		nonterminals.push_back ( std::string ( 1, i ) );

	if ( randomizedAlphabet )
		shuffle ( nonterminals.begin ( ), nonterminals.end ( ), ext::random_devices::semirandom );

	nonterminals.resize ( nonterminalsCount);

	return grammar::generate::RandomGrammarFactory::randomCFG ( nonterminals, terminals, density );
}

} /* namespace generate */

} /* namespace grammar */

namespace {

auto GenerateCFG1 = registration::AbstractRegister < grammar::generate::RandomGrammarFactory, grammar::CFG < >, ext::set < DefaultSymbolType >, ext::set < DefaultSymbolType >, double > ( grammar::generate::RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminals", "terminals", "density" ).setDocumentation (
"Generates a random context free grammar.\n\
\n\
@param nonterminals the nonterminals in the generated grammar\n\
@param terminals the terminals in the generated grammar\n\
@param density density of the rule set of the generated grammar\n\
@return random context free grammar" );

auto GenerateCFG2 = registration::AbstractRegister < grammar::generate::RandomGrammarFactory, grammar::CFG < std::string, std::string >, size_t, size_t, bool, double> ( grammar::generate::RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminalsCount", "terminalsCount", "randomizedAlphabet", "density" ).setDocumentation (
"Generates a random context free grammar.\n\
\n\
@param nonterminalsCount number of nonterminals in the generated grammar\n\
@param terminalsSize the number of terminals used in the generated grammar\n\
@param randomizedAlphabet selects random symbols from a-z range for terminal and A-Z for nonterminal alphabet if true\n\
@param density density of the rule set of the generated grammar\n\
@return random context free grammar" );

} /* namespace */
