/*
 * Translate.h
 *
 *  Created on: 12. 5. 2016
 *      Author: Jakub Doupal
 */

#ifndef _AUTOMATON_TRANSLATE_H__
#define _AUTOMATON_TRANSLATE_H__

#include <string/LinearString.h>

#include "Run.h"
#include <automaton/PDA/NPDTA.h>

#include <alib/deque>
#include <alib/set>

namespace automaton {

namespace run {

/**
 * \brief
 * Implementation of transducer run over its input.
 */
class Translate {
public:
	/**
	 * Implementation of a run of an automaton that is producing output.
	 *
	 * \tparam InputSymbolType type of input symbols of the string and terminal symbols of the runned automaton
	 * \tparam OutputSymbolType type of output symbols of the runned automaton
	 * \tparam PushdownStoreSymbolType type of pushdown store symbols of the runned automaton
	 * \tparam StateType type of states of the runned automaton
	 *
	 * \param automaton the runned automaton
	 * \param string the input of the automaton
	 *
	 * \return set of strings representing the translations
	 */
	template < class InputSymbolType, class OutputSymbolType, class PushdownStoreSymbolType, class StateType >
	static ext::set < string::LinearString < OutputSymbolType > > translate ( const automaton::NPDTA < InputSymbolType, OutputSymbolType, PushdownStoreSymbolType, StateType > & automaton, const string::LinearString < InputSymbolType > & string );

};

template < class InputSymbolType, class OutputSymbolType, class PushdownStoreSymbolType, class StateType >
ext::set < string::LinearString < OutputSymbolType > > Translate::translate ( const automaton::NPDTA < InputSymbolType, OutputSymbolType, PushdownStoreSymbolType, StateType > & automaton, const string::LinearString < InputSymbolType > & string ) {
	ext::tuple < bool, ext::set < StateType >, ext::set < ext::vector < OutputSymbolType > > > res = Run::calculateStates ( automaton, string );
	ext::set < string::LinearString < OutputSymbolType > > strings;

	for ( const auto & rawString : std::get < 2 > ( res ) )
		strings . insert ( string::LinearString < OutputSymbolType > ( rawString ) );

	return strings;
}

} /* namespace run */

} /* namespace automaton */

#endif /* _AUTOMATON_TRANSLATE_H__ */
