package de.dhbwstuttgart.typeinference.unify.interfaces;

import java.util.Optional;
import java.util.Set;

import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;

/**
 * 
 * @author Florian Steurer
 */
public interface IFiniteClosure {
	
	public void setLogTrue();
	/**
	 * Returns all types of the finite closure that are subtypes of the argument.
	 * @return The set of subtypes of the argument.
	 */
	public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
	
	/**
	 * Returns all types of the finite closure that are supertypes of the argument.
	 * @return The set of supertypes of the argument.
	 */
	public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);

	/**
	 * Wo passt Type rein?
	 * @param type
	 * @return
	 */
	public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
	
	/**
	 * Was passt in Type rein?
	 * @param type
	 * @return
	 */
	public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
	
	public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
	public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
	
	public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
	public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
	
	public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
	public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);

	public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
	public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);

	public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
	public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
	
	public Optional<UnifyType> getLeftHandedType(String typeName);
	public Set<UnifyType> getAncestors(UnifyType t);
	public Set<UnifyType> getChildren(UnifyType t);
	public Set<UnifyType> getAllTypesByName(String typeName);

	public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop);
}
