#include "FSMSingleInitialStateTest.h"

#include "automaton/simplify/FSMSingleInitialState.h"
#include "automaton/determinize/nfa/NFADeterminizer.h"
#include "automaton/simplify/NormalizeDFA.h"

#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))

CPPUNIT_TEST_SUITE_REGISTRATION( FSMSingleInitialStateTest );

void FSMSingleInitialStateTest::setUp() {
}

void FSMSingleInitialStateTest::tearDown() {
}

void FSMSingleInitialStateTest::testSingleInitialState() {
	automaton::State q("q");
	automaton::State q0("q0");
	automaton::State q1("q1");
	automaton::State q2("q2");
	automaton::State q3("q3");

	alphabet::Symbol a = alphabet::symbolFrom('a');
	alphabet::Symbol b = alphabet::symbolFrom('b');

	automaton::MultiInitialStateNFA automaton1;
	automaton1.setStates({q0, q1, q2, q3});
	automaton1.setInitialStates({q0, q1, q2});
	automaton1.setFinalStates({q3});
	automaton1.setInputSymbols({a, b});
	automaton1.addTransition(q0, a, q1);
	automaton1.addTransition(q1, b, q2);
	automaton1.addTransition(q2, a, q3);

	automaton::NFA automaton2 = automaton::FSMSingleInitialState::convert(automaton1);

	automaton::NFA automaton3(q);
	automaton3.setStates({q, q1, q2, q3});
	automaton3.setFinalStates({q3});
	automaton3.setInputSymbols({a, b});
	automaton3.addTransition(q, a, q3);
	automaton3.addTransition(q, b, q2);
	automaton3.addTransition(q, a, q1);
	automaton3.addTransition(q1, b, q2);
	automaton3.addTransition(q2, a, q3);

	automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(automaton2);
	automaton::DFA dfa3 = determinize::NFADeterminizer::determinize(automaton3);

	CPPUNIT_ASSERT(normalize::NormalizeDFA::normalize(dfa3) == normalize::NormalizeDFA::normalize(dfa3));
}