/*
 * ExactSubtreeAutomaton.h
 *
 *  Created on: 7. 4. 2015
 *      Author: Jan Travnicek
 */

#ifndef _EXACT_SUBTREE_AUTOMATON_H__
#define _EXACT_SUBTREE_AUTOMATON_H__

#include <tree/ranked/PrefixRankedTree.h>
#include <automaton/PDA/InputDrivenNPDA.h>

namespace arbology {

namespace exact {

class ExactSubtreeAutomaton {
public:
	/**
	 * Performs conversion.
	 * @return left regular grammar equivalent to source automaton.
	 */
	template < class SymbolType >
	static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, unsigned > construct ( const tree::PrefixRankedTree < SymbolType > & tree );

};

template < class SymbolType >
automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, unsigned > ExactSubtreeAutomaton::construct ( const tree::PrefixRankedTree < SymbolType > & tree ) {
	automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, unsigned > res ( 0, 'S' );

	for ( const common::ranked_symbol < SymbolType > & symbol : tree.getAlphabet ( ) ) {
		res.addInputSymbol ( symbol );
		res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, 'S' ), ext::vector < char > ( ( size_t ) symbol.getRank ( ), 'S' ) );
	}

	unsigned i = 1;

	for ( const common::ranked_symbol < SymbolType > & symbol : tree.getContent ( ) ) {
		res.addState ( i );
		res.addTransition ( i - 1, symbol, i );
		res.addTransition ( 0, std::move ( symbol ), i );
		i++;
	}

	return res;
}

} /* namespace exact */

} /* namespace arbology */

#endif /* _EXACT_SUBTREE_AUTOMATON_H__ */
