commenting and refactoring
This commit is contained in:
parent
ba636e1da0
commit
27f6abefe8
@ -8,20 +8,35 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
|
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The finite closure for the type unification
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
public class FiniteClosure implements IFiniteClosure {
|
public class FiniteClosure implements IFiniteClosure {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map that maps every type to the node in the inheritance graph that contains that type.
|
||||||
|
*/
|
||||||
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
|
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
|
||||||
private HashMap<String, HashSet<Node<UnifyType>>> strInheritanceGraph;
|
|
||||||
private Set<UnifyPair> pairs;
|
|
||||||
//private Set<UnifyType> basicTypes;
|
|
||||||
//TODO im konstruktor mitgeben um typenabzuhandeln die keine extends beziehung haben. (Damit die FC diese Typen auch kennt)
|
|
||||||
//(ALternative: immer die extends zu object beziehung einfügen)
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
|
||||||
|
*/
|
||||||
|
private HashMap<String, HashSet<Node<UnifyType>>> strInheritanceGraph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initial pairs of that define the inheritance tree
|
||||||
|
*/
|
||||||
|
private Set<UnifyPair> pairs;
|
||||||
|
|
||||||
|
//TODO Prüfen: Typen ohne Kante im Graph als extra Menge im Konstruktor mitgeben?
|
||||||
|
/**
|
||||||
|
* Creates a new instance using the inheritance tree defined in the pairs.
|
||||||
|
*/
|
||||||
public FiniteClosure(Set<UnifyPair> pairs) {
|
public FiniteClosure(Set<UnifyPair> pairs) {
|
||||||
this.pairs = new HashSet<>(pairs);
|
this.pairs = new HashSet<>(pairs);
|
||||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||||
@ -49,7 +64,6 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build the alternative representation with strings as keys
|
// Build the alternative representation with strings as keys
|
||||||
|
|
||||||
strInheritanceGraph = new HashMap<>();
|
strInheritanceGraph = new HashMap<>();
|
||||||
for(UnifyType key : inheritanceGraph.keySet()) {
|
for(UnifyType key : inheritanceGraph.keySet()) {
|
||||||
if(!strInheritanceGraph.containsKey(key.getName()))
|
if(!strInheritanceGraph.containsKey(key.getName()))
|
||||||
@ -71,7 +85,12 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return computeSmaller(type);
|
return computeSmaller(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the smaller functions for every type except FunNTypes.
|
||||||
|
*/
|
||||||
private Set<UnifyType> computeSmaller(UnifyType type) {
|
private Set<UnifyType> computeSmaller(UnifyType type) {
|
||||||
|
// Base Case: The type is in the inheritance tree. Add all children.
|
||||||
|
// This is Case 1 in the definition of the subtyping relation.
|
||||||
if(inheritanceGraph.containsKey(type)) {
|
if(inheritanceGraph.containsKey(type)) {
|
||||||
Set<UnifyType> result = new HashSet<>();
|
Set<UnifyType> result = new HashSet<>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
@ -85,22 +104,22 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
// if T = T' then T <=* T'
|
// if T = T' then T <=* T'
|
||||||
result1.add(type);
|
result1.add(type);
|
||||||
|
|
||||||
|
// Permute all params with values that are in smArg() of that type.
|
||||||
|
// This corresponds to Case 3 in the definition of the subtyping relation.
|
||||||
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
for (UnifyType param : type.getTypeParams())
|
for (UnifyType param : type.getTypeParams())
|
||||||
paramCandidates.add(smArg(param));
|
paramCandidates.add(smArg(param));
|
||||||
|
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}
|
||||||
|
|
||||||
Set<TypeParams> permResult = permuteParams(paramCandidates);
|
// This is case 2 of the definition of the subtyping relation.
|
||||||
|
|
||||||
for (TypeParams newParams : permResult)
|
|
||||||
result1.add(type.setTypeParams(newParams));}
|
|
||||||
|
|
||||||
Set<UnifyType> result2 = new HashSet<>();
|
Set<UnifyType> result2 = new HashSet<>();
|
||||||
if (strInheritanceGraph.containsKey(type.getName())) {
|
if (strInheritanceGraph.containsKey(type.getName())) {
|
||||||
HashSet<UnifyType> candidates = new HashSet<>();
|
HashSet<UnifyType> candidates = new HashSet<>();
|
||||||
|
// All types with the same name
|
||||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
|
|
||||||
for(UnifyType typePrime : result1) {
|
for(UnifyType typePrime : result1) {
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
|
// Find the substitution
|
||||||
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
||||||
if (!sigma2Opt.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
@ -120,6 +139,8 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
else
|
else
|
||||||
result2 = result1;
|
result2 = result1;
|
||||||
|
|
||||||
|
// Permute the params again.
|
||||||
|
// This corresponds again to Case 3 of the definition of the subtyping relation.
|
||||||
Set<UnifyType> result3 = new HashSet<>();
|
Set<UnifyType> result3 = new HashSet<>();
|
||||||
for(UnifyType t : result2) {
|
for(UnifyType t : result2) {
|
||||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
@ -141,22 +162,23 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return result3;
|
return result3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the smaller-Function for FunNTypes.
|
||||||
|
*/
|
||||||
private Set<UnifyType> computeSmallerFunN(FunNType type) {
|
private Set<UnifyType> computeSmallerFunN(FunNType type) {
|
||||||
Set<UnifyType> result = new HashSet<>();
|
Set<UnifyType> result = new HashSet<>();
|
||||||
|
|
||||||
// if T = T' then T <=* T'
|
// if T = T' then T <=* T'
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
|
// Because real function types are implicitly variant
|
||||||
|
// it is enough to permute the params with the values of greater / smaller.
|
||||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
paramCandidates.add(smaller(type.getTypeParams().get(0)));
|
paramCandidates.add(smaller(type.getTypeParams().get(0)));
|
||||||
for (int i = 1; i < type.getTypeParams().size(); i++)
|
for (int i = 1; i < type.getTypeParams().size(); i++)
|
||||||
paramCandidates.add(greater(type.getTypeParams().get(i)));
|
paramCandidates.add(greater(type.getTypeParams().get(i)));
|
||||||
|
|
||||||
Set<TypeParams> permResult = permuteParams(paramCandidates);
|
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
|
||||||
|
|
||||||
for (TypeParams newParams : permResult)
|
|
||||||
result.add(type.setTypeParams(newParams));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,39 +193,43 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return computeGreater(type);
|
return computeGreater(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the greater function for all types except function types.
|
||||||
|
*/
|
||||||
protected Set<UnifyType> computeGreater(UnifyType type) {
|
protected Set<UnifyType> computeGreater(UnifyType type) {
|
||||||
IUnify unify = new MartelliMontanariUnify();
|
IUnify unify = new MartelliMontanariUnify();
|
||||||
Set<UnifyType> result1 = new HashSet<>();
|
Set<UnifyType> result1 = new HashSet<>();
|
||||||
|
|
||||||
|
// The type is in the inheritance tree. Add all children.
|
||||||
|
// This is Case 1 in the definition of the subtyping relation.
|
||||||
if(inheritanceGraph.containsKey(type))
|
if(inheritanceGraph.containsKey(type))
|
||||||
result1.addAll(inheritanceGraph.get(type).getContentOfPredecessors());
|
result1.addAll(inheritanceGraph.get(type).getContentOfPredecessors());
|
||||||
|
|
||||||
// if T = T' then T <=* T'
|
// if T = T' then T <=* T'
|
||||||
result1.add(type);
|
result1.add(type);
|
||||||
|
|
||||||
|
// Permute all params with values that are in smArg() of that type.
|
||||||
|
// This corresponds to Case 3 in the definition of the subtyping relation.
|
||||||
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
for (UnifyType param : type.getTypeParams())
|
for (UnifyType param : type.getTypeParams())
|
||||||
paramCandidates.add(grArg(param));
|
paramCandidates.add(grArg(param));
|
||||||
|
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}
|
||||||
|
|
||||||
Set<TypeParams> permResult = new HashSet<>();
|
// This is case 2 of the definition of the subtyping relation.
|
||||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
|
||||||
|
|
||||||
for (TypeParams newParams : permResult)
|
|
||||||
result1.add(type.setTypeParams(newParams));}
|
|
||||||
|
|
||||||
Set<UnifyType> result2 = new HashSet<>();
|
Set<UnifyType> result2 = new HashSet<>();
|
||||||
if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) {
|
if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) {
|
||||||
HashSet<UnifyType> candidates = new HashSet<>();
|
HashSet<UnifyType> candidates = new HashSet<>();
|
||||||
|
// All types with the same name
|
||||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
|
|
||||||
for(UnifyType typePrime : result1) {
|
for(UnifyType typePrime : result1) {
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
|
// Find the substitution
|
||||||
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
||||||
if (!sigma2Opt.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
if(type.equals(theta2))
|
if(type.equals(theta2))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Unifier sigma2 = sigma2Opt.get();
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams());
|
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams());
|
||||||
Set<UnifyType> theta1s = greater(theta2);
|
Set<UnifyType> theta1s = greater(theta2);
|
||||||
@ -218,16 +244,15 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
|
|
||||||
result2.addAll(result1);
|
result2.addAll(result1);
|
||||||
|
|
||||||
|
// Permute the params again.
|
||||||
|
// This corresponds again to Case 3 of the definition of the subtyping relation.
|
||||||
Set<UnifyType> result3 = new HashSet<>();
|
Set<UnifyType> result3 = new HashSet<>();
|
||||||
for(UnifyType t : result2) {
|
for(UnifyType t : result2) {
|
||||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
for (UnifyType param : t.getTypeParams())
|
for (UnifyType param : t.getTypeParams())
|
||||||
paramCandidates.add(grArg(param));
|
paramCandidates.add(grArg(param));
|
||||||
|
|
||||||
Set<TypeParams> permResult = new HashSet<>();
|
for (TypeParams newParams : permuteParams(paramCandidates)) {
|
||||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
|
||||||
|
|
||||||
for (TypeParams newParams : permResult) {
|
|
||||||
UnifyType tPrime = t.setTypeParams(newParams);
|
UnifyType tPrime = t.setTypeParams(newParams);
|
||||||
if(tPrime.equals(t))
|
if(tPrime.equals(t))
|
||||||
result3.add(t);
|
result3.add(t);
|
||||||
@ -240,22 +265,22 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return result3;
|
return result3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the greater function for FunN-Types
|
||||||
|
*/
|
||||||
protected Set<UnifyType> computeGreaterFunN(FunNType type) {
|
protected Set<UnifyType> computeGreaterFunN(FunNType type) {
|
||||||
Set<UnifyType> result = new HashSet<>();
|
Set<UnifyType> result = new HashSet<>();
|
||||||
|
|
||||||
// if T = T' then T <=* T'
|
// if T = T' then T <=* T'
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
|
// Because real function types are implicitly variant
|
||||||
|
// it is enough to permute the params with the values of greater / smaller.
|
||||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
paramCandidates.add(greater(type.getTypeParams().get(0)));
|
paramCandidates.add(greater(type.getTypeParams().get(0)));
|
||||||
for (int i = 1; i < type.getTypeParams().size(); i++)
|
for (int i = 1; i < type.getTypeParams().size(); i++)
|
||||||
paramCandidates.add(smaller(type.getTypeParams().get(i)));
|
paramCandidates.add(smaller(type.getTypeParams().get(i)));
|
||||||
|
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
|
||||||
Set<TypeParams> permResult = permuteParams(paramCandidates);
|
|
||||||
|
|
||||||
for (TypeParams newParams : permResult)
|
|
||||||
result.add(type.setTypeParams(newParams));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,28 +293,28 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> grArg(ReferenceType type) {
|
public Set<UnifyType> grArg(ReferenceType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
|
|
||||||
result.add(type);
|
result.add(type);
|
||||||
smaller(type).forEach(x -> result.add(new SuperType(x)));
|
smaller(type).forEach(x -> result.add(new SuperType(x)));
|
||||||
greater(type).forEach(x -> result.add(new ExtendsType(x)));
|
greater(type).forEach(x -> result.add(new ExtendsType(x)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> grArg(FunNType type) {
|
public Set<UnifyType> grArg(FunNType type) {
|
||||||
throw new NotImplementedException();
|
// TODO ist das richtig?
|
||||||
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
|
result.add(type);
|
||||||
|
smaller(type).forEach(x -> result.add(new SuperType(x)));
|
||||||
|
greater(type).forEach(x -> result.add(new ExtendsType(x)));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> grArg(ExtendsType type) {
|
public Set<UnifyType> grArg(ExtendsType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
UnifyType t = type.getExtendedType();
|
UnifyType t = type.getExtendedType();
|
||||||
|
|
||||||
greater(t).forEach(x -> result.add(new ExtendsType(x)));
|
greater(t).forEach(x -> result.add(new ExtendsType(x)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,11 +322,8 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
public Set<UnifyType> grArg(SuperType type) {
|
public Set<UnifyType> grArg(SuperType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
UnifyType t = type.getSuperedType();
|
UnifyType t = type.getSuperedType();
|
||||||
|
|
||||||
smaller(t).forEach(x -> result.add(new SuperType(x)));
|
smaller(t).forEach(x -> result.add(new SuperType(x)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +331,6 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
public Set<UnifyType> grArg(PlaceholderType type) {
|
public Set<UnifyType> grArg(PlaceholderType type) {
|
||||||
HashSet<UnifyType> result = new HashSet<>();
|
HashSet<UnifyType> result = new HashSet<>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
//result.add(new SuperType(type));
|
|
||||||
//result.add(new ExtendsType(type));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,29 +342,28 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> smArg(ReferenceType type) {
|
public Set<UnifyType> smArg(ReferenceType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
|
|
||||||
result.add(type);
|
result.add(type);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> smArg(FunNType type) {
|
public Set<UnifyType> smArg(FunNType type) {
|
||||||
throw new NotImplementedException();
|
// TODO ist das richtig?
|
||||||
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
|
result.add(type);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> smArg(ExtendsType type) {
|
public Set<UnifyType> smArg(ExtendsType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
UnifyType t = type.getExtendedType();
|
UnifyType t = type.getExtendedType();
|
||||||
|
|
||||||
result.add(t);
|
result.add(t);
|
||||||
smaller(t).forEach(x -> {
|
smaller(t).forEach(x -> {
|
||||||
result.add(new ExtendsType(x));
|
result.add(new ExtendsType(x));
|
||||||
result.add(x);
|
result.add(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,15 +372,12 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
public Set<UnifyType> smArg(SuperType type) {
|
public Set<UnifyType> smArg(SuperType type) {
|
||||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
|
|
||||||
UnifyType t = type.getSuperedType();
|
UnifyType t = type.getSuperedType();
|
||||||
|
|
||||||
result.add(t);
|
result.add(t);
|
||||||
greater(t).forEach(x -> {
|
greater(t).forEach(x -> {
|
||||||
result.add(new SuperType(x));
|
result.add(new SuperType(x));
|
||||||
result.add(x);
|
result.add(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,12 +425,25 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a set of candidates for each position and computes all possible permutations.
|
||||||
|
* @param candidates The length of the list determines the number of type params. Each set
|
||||||
|
* contains the candidates for the corresponding position.
|
||||||
|
*/
|
||||||
protected Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
|
protected Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
|
||||||
Set<TypeParams> result = new HashSet<>();
|
Set<TypeParams> result = new HashSet<>();
|
||||||
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
|
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a set of candidates for each position and computes all possible permutations.
|
||||||
|
* @param candidates The length of the list determines the number of type params. Each set
|
||||||
|
* contains the candidates for the corresponding position.
|
||||||
|
* @param idx Idx for the current permutatiton.
|
||||||
|
* @param result Set of all permutations found so far
|
||||||
|
* @param current The permutation of type params that is currently explored
|
||||||
|
*/
|
||||||
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||||
if(candidates.size() == idx) {
|
if(candidates.size() == idx) {
|
||||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||||
|
Loading…
Reference in New Issue
Block a user