#include <catch2/catch.hpp>

#include <automaton/FSM/DFA.h>

#include "automaton/simplify/Total.h"
#include "automaton/simplify/Normalize.h"
#include "automaton/simplify/Trim.h"

TEST_CASE ( "Total automaton", "[unit][algo][automaton][simplify]" ) {
	SECTION ( "DFA to DFA with total transition function" ) {
		DefaultStateType q0 = DefaultStateType ("q0");
		DefaultStateType q1 = DefaultStateType ("q1");
		DefaultStateType q2 = DefaultStateType ("q2");

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

		automaton::DFA<> automaton(q0);
		automaton.setStates({q0, q1, q2});
		automaton.setFinalStates({q0, q1, q2});
		automaton.setInputAlphabet({a, b, c});

		automaton.addTransition(q0, a, q0);
		automaton.addTransition(q0, b, q1);
		automaton.addTransition(q0, c, q2);
		automaton.addTransition(q1, b, q1);
		automaton.addTransition(q1, c, q2);
		automaton.addTransition(q2, c, q2);

		automaton::DFA<> totalAutomaton = automaton::simplify::Total::total(automaton);
		CHECK(totalAutomaton.isTotal());

		automaton::DFA<> trimmedAutomaton = automaton::simplify::Trim::trim(automaton);
		automaton::DFA<> trimmedTotalAutomaton = automaton::simplify::Trim::trim(totalAutomaton);

		CHECK(automaton::simplify::Normalize::normalize(trimmedAutomaton) == automaton::simplify::Normalize::normalize(trimmedTotalAutomaton));
	}
}
