#include <catch2/catch.hpp>

#include <automaton/FSM/DFA.h>

#include "automaton/properties/SynchronizingWordExistence.h"

TEST_CASE ( "Synchronizing Word Existence", "[unit][algo][automaton]" ) {
	SECTION ( "Test 1" ) {
		DefaultStateType q1 = DefaultStateType ("q1");
		DefaultStateType q2 = DefaultStateType ("q2");
		DefaultStateType q3 = DefaultStateType ("q3");

		DefaultSymbolType a = DefaultSymbolType ("a");
		DefaultSymbolType b = DefaultSymbolType ("b");

		automaton::DFA< > automaton(q1);
		automaton.addInputSymbols({a, b});
		automaton.setStates({q1, q2, q3});

		automaton.addTransition(q1, a, q1);
		automaton.addTransition(q2, a, q2);
		automaton.addTransition(q3, a, q3);
		automaton.addTransition(q1, b, q2);
		automaton.addTransition(q2, b, q3);
		automaton.addTransition(q3, b, q1);

		CHECK(! automaton::properties::SynchronizingWordExistence::exists(automaton));
	}

	SECTION ( "Test 2" ) {
		DefaultStateType q0 = DefaultStateType ("q0");
		DefaultStateType q1 = DefaultStateType ("q1");
		DefaultStateType q2 = DefaultStateType ("q2");
		DefaultStateType q3 = DefaultStateType ("q3");
		DefaultStateType q4 = DefaultStateType ("q4");

		DefaultSymbolType a = DefaultSymbolType ("a");
		DefaultSymbolType b = DefaultSymbolType ("b");

		automaton::DFA< > automaton(q0);
		automaton.addInputSymbols({a, b});
		automaton.setStates({q0, q1, q2, q3, q4});

		automaton.addTransition(q0, a, q1);
		automaton.addTransition(q1, a, q1);
		automaton.addTransition(q2, a, q2);
		automaton.addTransition(q3, a, q3);
		automaton.addTransition(q4, a, q4);

		automaton.addTransition(q0, b, q1);
		automaton.addTransition(q1, b, q2);
		automaton.addTransition(q2, b, q3);
		automaton.addTransition(q3, b, q4);
		automaton.addTransition(q4, b, q0);

		CHECK(automaton::properties::SynchronizingWordExistence::exists(automaton));
	}
}
