package de.dhbwstuttgart.typeinference.unify.interfaces;

import java.util.Arrays;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.Unifier;

/**
 * Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari)
 * @author Florian Steurer
 */
public interface IUnify {
	
	/**
	 * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
	 * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn'). 
	 * @param terms The set of terms to be unified
	 * @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
	 */
	public Optional<Unifier> unify(Set<UnifyType> terms);
	
	/**
	 * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
	 * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn'). 
	 * @param terms The set of terms to be unified
	 * @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
	 */
	default public Optional<Unifier> unify(UnifyType... terms) {
		return unify(Arrays.stream(terms).collect(Collectors.toSet()));
	}

}
