package ec.gp.semantic.library;

import ec.gp.GPNode;
import ec.gp.semantic.DesiredSemanticsBase;
import ec.gp.semantic.ISemantics;
import ec.util.MersenneTwisterFast;
import library.space.SearchResult;

import java.util.List;

public interface ILibrary<SemType> {

	/**
	 * Returns a program that produces as close as possible semantics to the given one.
	 * 
	 * @param desired
	 * @param forbidden
	 * @param maxHeight
	 *            Maximum height of returned program.
	 * @return
	 */
	SearchResult<GPNode> getProgram(DesiredSemanticsBase<SemType> desired, DesiredSemanticsBase<SemType>[] forbidden, int maxHeight);

	/**
	 * Returns a collection of at most k programs that are the closest to the given desired semantics.
	 * 
	 * @param desired
	 * @param forbidden
	 * @param k
	 * @param maxHeight
	 *            Maximum height of returned program.
	 * @return
	 */
	List<SearchResult<GPNode>> getPrograms(DesiredSemanticsBase<SemType> desired, DesiredSemanticsBase<SemType>[] forbidden, int k, int maxHeight);

	/**
	 * Returns k-closest program in library to the given desired semantics.
	 * 
	 * @param desired
	 * @param forbidden
	 * @param k
	 * @return
	 */
	SearchResult<GPNode> getKthProgram(DesiredSemanticsBase<SemType> desired, DesiredSemanticsBase<SemType>[] forbidden, int k, int maxHeight);

	/**
	 * 
	 * @param random
	 * @param maxHeight
	 *            Maximum height of returned program.
	 * @return
	 */
	GPNode getRandom(MersenneTwisterFast random, int maxHeight);

	double calculateError(DesiredSemanticsBase<SemType> desired, DesiredSemanticsBase<SemType>[] forbidden, ISemantics semantics);

	int size();

	int size(int maxDepth);
}
