#include <catch2/catch.hpp>

#include <alib/list>

#include "automaton/simplify/MinimizeBrzozowski.h"
#include "automaton/simplify/Minimize.h"
#include "automaton/simplify/Trim.h"
#include "automaton/simplify/Normalize.h"

TEST_CASE ( "Brzozowski minimization", "[unit][algo][automaton][simplify]" ) {
	SECTION ( "Test DFA" ) {
		automaton::DFA < > automaton(DefaultStateType(1));

		automaton.addState(DefaultStateType(1));
		automaton.addState(DefaultStateType(2));
		automaton.addState(DefaultStateType(3));
		automaton.addInputSymbol(DefaultSymbolType("a"));
		automaton.addInputSymbol(DefaultSymbolType("b"));

		automaton.addTransition(DefaultStateType(1), DefaultSymbolType("a"), DefaultStateType(2));
		automaton.addTransition(DefaultStateType(2), DefaultSymbolType("b"), DefaultStateType(1));

		automaton.addFinalState(DefaultStateType(3));

		automaton::DFA < > minimizedHopcroft = automaton::simplify::Minimize::minimize(automaton);
		automaton::DFA < DefaultSymbolType, ext::set < ext::set < DefaultStateType > > > minimizedBrzozowski = automaton::simplify::MinimizeBrzozowski::minimize(automaton);

		CHECK(minimizedHopcroft.getStates().size() == 3);
		CHECK(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedHopcroft)) == automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedBrzozowski)));
	}
}
