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.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 {
	
	/**
	 * 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);
	
	/**
	 * 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);

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

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

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