/*
 * Determinize.cpp
 *
 *  Created on: 16. 1. 2014
 *	  Author: Jan Vesely
 */

#include "Determinize.h"
#include "../transform/PDAToRHPDA.h"
#include "../transform/RHPDAToPDA.h"
#include <automaton/FSM/DFA.h>
#include <automaton/FSM/MultiInitialStateNFA.h>
#include <automaton/PDA/DPDA.h>
#include <automaton/PDA/NPDA.h>
#include <automaton/PDA/InputDrivenDPDA.h>
#include <automaton/PDA/InputDrivenNPDA.h>
#include <automaton/PDA/SinglePopDPDA.h>
#include <automaton/PDA/VisiblyPushdownDPDA.h>
#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h>
#include <automaton/TM/OneTapeDTM.h>
#include <automaton/TA/DFTA.h>
#include "automaton/PDA/RealTimeHeightDeterministicNPDA.h"

namespace automaton {

namespace determinize {

automaton::Automaton Determinize::determinize(const automaton::Automaton& automaton) {
	automaton::Automaton res = dispatch(automaton.getData());
	res.normalize ( );
	return res;
}

DFA<> Determinize::determinize(const automaton::DFA<>& automaton) {
	return automaton;
}

auto DeterminizeDFA = Determinize::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Determinize::determinize);

DPDA < > Determinize::determinize(const automaton::DPDA < > & automaton) {
	return automaton;
}

auto DeterminizeDPDA = Determinize::RegistratorWrapper<automaton::DPDA < >, automaton::DPDA < > >(Determinize::determinize);

SinglePopDPDA < > Determinize::determinize(const automaton::SinglePopDPDA < > & automaton) {
	return automaton;
}

auto DeterminizeSinglePopDPDA = Determinize::RegistratorWrapper<automaton::SinglePopDPDA < >, automaton::SinglePopDPDA < > >(Determinize::determinize);

InputDrivenDPDA < > Determinize::determinize(const automaton::InputDrivenDPDA < > & automaton) {
	return automaton;
}

auto DeterminizeInputDrivenDPDA = Determinize::RegistratorWrapper<automaton::InputDrivenDPDA < >, automaton::InputDrivenDPDA < > >(Determinize::determinize);

VisiblyPushdownDPDA < > Determinize::determinize(const automaton::VisiblyPushdownDPDA < > & automaton) {
	return automaton;
}

auto DeterminizeVisiblyPushdownDPDA = Determinize::RegistratorWrapper<automaton::VisiblyPushdownDPDA < >, automaton::VisiblyPushdownDPDA < > >(Determinize::determinize);

RealTimeHeightDeterministicDPDA < > Determinize::determinize(const automaton::RealTimeHeightDeterministicDPDA < > & automaton) {
	return automaton;
}

auto DeterminizeRealTimeHeightDeterministicDPDA = Determinize::RegistratorWrapper<automaton::RealTimeHeightDeterministicDPDA < >, automaton::RealTimeHeightDeterministicDPDA < > >(Determinize::determinize);

DPDA < > Determinize::determinize(const automaton::NPDA < > & automaton) {
	automaton::RealTimeHeightDeterministicNPDA < > rhpda = automaton::PDAToRHPDA::convert(automaton);
	automaton::RealTimeHeightDeterministicDPDA < > dpda = Determinize::determinize(rhpda);
	return automaton::RHPDAToPDA::convert(dpda);
}

auto DeterminizeNPDA = Determinize::RegistratorWrapper<automaton::DPDA < >, automaton::NPDA < > >(Determinize::determinize);

OneTapeDTM<> Determinize::determinize(const automaton::OneTapeDTM<>& automaton) {
	return automaton;
}

auto DeterminizeOneTapeDTM = Determinize::RegistratorWrapper<automaton::OneTapeDTM<>, automaton::OneTapeDTM<>>(Determinize::determinize);

DFTA < > Determinize::determinize(const automaton::DFTA < > & automaton) {
	return automaton;
}

auto DeterminizeDFTA = Determinize::RegistratorWrapper<automaton::DFTA < >, automaton::DFTA < > >(Determinize::determinize);



auto DeterminizeMultiInitialStateNFA = Determinize::RegistratorWrapper < automaton::DFA < DefaultSymbolType, std::set < DefaultStateType > >, automaton::MultiInitialStateNFA < > > ( Determinize::determinize );
auto DeterminizeNFA = Determinize::RegistratorWrapper < automaton::DFA < DefaultSymbolType, std::set < DefaultStateType > >, automaton::NFA < > > ( Determinize::determinize );

} /* namespace determinize */

} /* namespace automaton */

#include "DeterminizeIDPDAPart.cxx"
#include "DeterminizeVPAPart.cxx"
#include "DeterminizeRHDPDAPart.cxx"
#include "DeterminizeNFTAPart.cxx"