#include <catch2/catch.hpp>
#include <common/createUnique.hpp>

#include "grammar/ContextFree/CFG.h"
#include "grammar/transform/GrammarIteration.h"

TEST_CASE ( "Grammar Iteration", "[unit][algo][grammar][transform]" ) {
	SECTION ( "Test CFG" ) {
		{
			DefaultSymbolType S = DefaultSymbolType ( "S" );
			DefaultSymbolType A = DefaultSymbolType ( "A" );

			DefaultSymbolType a = DefaultSymbolType ( 'a' );
			DefaultSymbolType b = DefaultSymbolType ( 'b' );

			grammar::CFG < DefaultSymbolType, DefaultSymbolType > grammar1 ( { S, A }, { a, b }, S );

			DefaultSymbolType S0 = common::createUnique ( label::InitialStateLabel::instance < DefaultSymbolType > ( ), grammar1.getNonterminalAlphabet ( ) );
			grammar::CFG < DefaultSymbolType, DefaultSymbolType > grammar3 ( { S0, S, A }, { a, b }, S0 );

			grammar1.addRule ( S, { } );
			grammar1.addRule ( S, { a, A } );
			grammar1.addRule ( S, { a, S } );
			grammar1.addRule ( A, { a, A } );
			grammar1.addRule ( A, { } );

			grammar3.addRule ( S0, { } );
			grammar3.addRule ( S0, { S, S0 } );

			grammar3.addRule ( S, { } );
			grammar3.addRule ( S, { a, A } );
			grammar3.addRule ( S, { a, S } );
			grammar3.addRule ( A, { a, A } );
			grammar3.addRule ( A, { } );

			CHECK ( grammar3 == grammar::transform::GrammarIteration::iteration ( grammar1 ) );
		}
	}
}
