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

#ifndef _EXACT_SUBSEQUENCE_AUTOMATON__H_
#define _EXACT_SUBSEQUENCE_AUTOMATON__H_

#include <automaton/FSM/DFA.h>
#include <string/LinearString.h>

namespace stringology {

namespace indexing {

class ExactSubsequenceAutomaton {
public:
	/**
	 * Performs conversion.
	 * @return left regular grammar equivalent to source automaton.
	 */
	template < class SymbolType >
	static automaton::DFA < SymbolType, unsigned > construct ( const string::LinearString < SymbolType > & text );
};

template < class SymbolType >
automaton::DFA < SymbolType, unsigned > ExactSubsequenceAutomaton::construct ( const string::LinearString < SymbolType > & text ) {
	ext::map < SymbolType, unsigned > f;
	for(const SymbolType & symbol : text.getAlphabet ( ) ) {
		f[symbol] = 0;
	}

	automaton::DFA < SymbolType, unsigned > res ( 0 );
	res.addFinalState ( 0 );
	res.setInputAlphabet ( text.getAlphabet ( ) );

	unsigned i = 1;
	for ( const SymbolType & symbol : text.getContent ( ) ) {
		res.addState ( i );
		res.addFinalState ( i );

		for ( unsigned j = f [ symbol ]; j < i; j++ ) {
			res.addTransition ( j, symbol, i );
		}
		f[symbol] = i;
		i++;
	}

	return res;
}

} /* namespace indexing */

} /* namespace stringology */

#endif /* _EXACT_SUBSEQUENCE_AUTOMATON__H_ */
