/*
 * GrammarCompare.h
 *
 *  Created on: Apr 1, 2013
 *      Author: honza
 */

#pragma once

#include "grammar/Regular/LeftLG.h"
#include "grammar/Regular/LeftRG.h"
#include "grammar/Regular/RightLG.h"
#include "grammar/Regular/RightRG.h"
#include "grammar/ContextFree/LG.h"
#include "grammar/ContextFree/CFG.h"
#include "grammar/ContextFree/EpsilonFreeCFG.h"
#include "grammar/ContextFree/CNF.h"
#include "grammar/ContextFree/GNF.h"
#include "grammar/ContextSensitive/CSG.h"
#include "grammar/ContextSensitive/NonContractingGrammar.h"
#include "grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h"
#include "grammar/Unrestricted/UnrestrictedGrammar.h"

namespace compare {

class GrammarCompare {
public:
	template < class SymbolType >
	static bool compare(const grammar::LeftLG < SymbolType > & a, const grammar::LeftLG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::LeftRG < SymbolType > & a, const grammar::LeftRG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::RightLG < SymbolType > & a, const grammar::RightLG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::RightRG < SymbolType > & a, const grammar::RightRG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::LG < SymbolType > & a, const grammar::LG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::CFG < SymbolType > & a, const grammar::CFG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::EpsilonFreeCFG < SymbolType > & a, const grammar::EpsilonFreeCFG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::CNF < SymbolType > & a, const grammar::CNF < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::GNF < SymbolType > & a, const grammar::GNF < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::CSG < SymbolType > & a, const grammar::CSG < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::NonContractingGrammar < SymbolType > & a, const grammar::NonContractingGrammar < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::ContextPreservingUnrestrictedGrammar < SymbolType > & a, const grammar::ContextPreservingUnrestrictedGrammar < SymbolType > & b);

	template < class SymbolType >
	static bool compare(const grammar::UnrestrictedGrammar < SymbolType > & a, const grammar::UnrestrictedGrammar < SymbolType > & b);
};

template < class SymbolType >
bool GrammarCompare::compare(const grammar::LeftLG < SymbolType > & a, const grammar::LeftLG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::LeftRG < SymbolType > & a, const grammar::LeftRG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::RightLG < SymbolType > & a, const grammar::RightLG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::RightRG < SymbolType > & a, const grammar::RightRG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::LG < SymbolType > & a, const grammar::LG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::CFG < SymbolType > & a, const grammar::CFG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::EpsilonFreeCFG < SymbolType > & a, const grammar::EpsilonFreeCFG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::CNF < SymbolType > & a, const grammar::CNF < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::GNF < SymbolType > & a, const grammar::GNF < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::CSG < SymbolType > & a, const grammar::CSG < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::NonContractingGrammar < SymbolType > & a, const grammar::NonContractingGrammar < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::ContextPreservingUnrestrictedGrammar < SymbolType > & a, const grammar::ContextPreservingUnrestrictedGrammar < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

template < class SymbolType >
bool GrammarCompare::compare(const grammar::UnrestrictedGrammar < SymbolType > & a, const grammar::UnrestrictedGrammar < SymbolType > & b) {
	return  	a.getNonterminalAlphabet() == b.getNonterminalAlphabet() &&
			a.getRules()               == b.getRules()               &&
//			a.getTerminalAlphabet()    == b.getTerminalAlphabet()    &&
			a.getInitialSymbol()       == b.getInitialSymbol()       ;
}

} /* namespace compare */

