Merge mit refactoring
This commit is contained in:
commit
a3e7b4567a
@ -339,7 +339,7 @@ public class Pair implements Serializable, DeepCloneable
|
||||
*/
|
||||
public boolean OperatorEqual()
|
||||
{
|
||||
return eOperator == PairOperator.EQUALS;
|
||||
return eOperator == PairOperator.EQUALSDOT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
|
||||
public class Mapping {
|
||||
@ -39,13 +40,13 @@ public class Mapping {
|
||||
return irreversible.contains(type) ? Optional.of(backwardMap.get(type)) : Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<de.dhbwstuttgart.typeinference.Pair> unmap(de.dhbwstuttgart.typeinference.unify.model.MPair mpair) {
|
||||
public Optional<Pair> unmap(de.dhbwstuttgart.typeinference.unify.model.MPair mpair) {
|
||||
de.dhbwstuttgart.typeinference.unify.model.UnifyType lhs = mpair.getLhsType();
|
||||
de.dhbwstuttgart.typeinference.unify.model.UnifyType rhs = mpair.getRhsType();
|
||||
|
||||
if(irreversible.contains(lhs) || irreversible.contains(rhs))
|
||||
return Optional.empty();
|
||||
return Optional.of(new de.dhbwstuttgart.typeinference.Pair(backwardMap.get(lhs), backwardMap.get(rhs), unmapOp(mpair.getPairOp())));
|
||||
return Optional.of(new Pair(backwardMap.get(lhs), backwardMap.get(rhs), unmapOp(mpair.getPairOp())));
|
||||
}
|
||||
|
||||
public Optional<Set<de.dhbwstuttgart.syntaxtree.type.Type>> unmapTypeSet(Set<de.dhbwstuttgart.typeinference.unify.model.UnifyType> types) {
|
||||
@ -57,7 +58,7 @@ public class Mapping {
|
||||
Set<de.dhbwstuttgart.typeinference.Pair> result = pairs.stream().map(this::unmap).filter(x -> x.isPresent()).map(x -> x.get()).collect(Collectors.toCollection(HashSet::new));
|
||||
return result.size() == pairs.size() ? Optional.of(result) : Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
private PairOperator mapOp(PairOperator op) {
|
||||
//TODO: Methode kann entfernt werden:
|
||||
return op;
|
||||
|
@ -31,9 +31,9 @@ public class MartelliMontanariUnify implements IUnify {
|
||||
ArrayList<MPair> termsQ = new ArrayList<MPair>();
|
||||
Iterator<UnifyType> iter = terms.iterator();
|
||||
UnifyType prev = iter.next();
|
||||
while(iter.hasNext()) {
|
||||
while(iter.hasNext()) {
|
||||
UnifyType next = iter.next();
|
||||
termsQ.add(new MPair(prev, next, PairOperator.EQUALS));
|
||||
termsQ.add(new MPair(prev, next, PairOperator.EQUALSDOT));
|
||||
prev = next;
|
||||
}
|
||||
|
||||
|
@ -84,11 +84,15 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<Set<MPair>> reduceExt(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
UnifyType x = pair.getLhsType();
|
||||
|
||||
if(!(x instanceof SimpleType) && !(x instanceof ExtendsType))
|
||||
UnifyType sTypeX;
|
||||
|
||||
if(x instanceof SimpleType)
|
||||
sTypeX = x;
|
||||
else if(x instanceof ExtendsType)
|
||||
sTypeX = ((ExtendsType) x).getExtendedType();
|
||||
else
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType extY = pair.getRhsType();
|
||||
@ -99,17 +103,31 @@ public class RuleSet implements IRuleSet{
|
||||
if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
int[] pi = pi(x, extY);
|
||||
UnifyType xFromFc = finiteClosure.getLeftHandedType(sTypeX).orElse(null);
|
||||
|
||||
if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
if(x instanceof ExtendsType)
|
||||
xFromFc = new ExtendsType(xFromFc);
|
||||
|
||||
UnifyType extYFromFc = finiteClosure.grArg(xFromFc).stream().filter(t -> t.getName().equals(extY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
|
||||
|
||||
if(extYFromFc == null || extYFromFc.getTypeParams() != xFromFc.getTypeParams())
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams extYParams = extY.getTypeParams();
|
||||
TypeParams xParams = x.getTypeParams();
|
||||
|
||||
int[] pi = pi(xParams, extYParams);
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams rhsTypeParams = extY.getTypeParams();
|
||||
TypeParams lhsTypeParams = x.getTypeParams();
|
||||
Set<MPair> result = new HashSet<>();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
|
||||
result.add(new MPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC));
|
||||
for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++)
|
||||
result.add(new MPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
@ -118,31 +136,49 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<Set<MPair>> reduceSup(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType x = pair.getLhsType();
|
||||
UnifyType sTypeX;
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
|
||||
if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType))
|
||||
if(x instanceof SimpleType)
|
||||
sTypeX = x;
|
||||
else if(x instanceof SuperType)
|
||||
sTypeX = ((SuperType) x).getSuperedType();
|
||||
else
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType supY = pair.getRhsType();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
|
||||
if(!(rhsType instanceof SuperType))
|
||||
if(!(supY instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size())
|
||||
if(x.getTypeParams().empty() || supY.getTypeParams().size() != x.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
int[] pi = pi(lhsType, rhsType);
|
||||
UnifyType xFromFc = finiteClosure.getLeftHandedType(sTypeX).orElse(null);
|
||||
|
||||
if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
if(x instanceof SuperType)
|
||||
xFromFc = new SuperType(xFromFc);
|
||||
|
||||
UnifyType supYFromFc = finiteClosure.grArg(xFromFc).stream().filter(t -> t.getName().equals(supY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
|
||||
|
||||
if(supYFromFc == null || supYFromFc.getTypeParams() != xFromFc.getTypeParams())
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams supYParams = supY.getTypeParams();
|
||||
TypeParams xParams = x.getTypeParams();
|
||||
Set<MPair> result = new HashSet<>();
|
||||
|
||||
int[] pi = pi(xParams, supYParams);
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
Set<MPair> result = new HashSet<>();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
|
||||
result.add(new MPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC));
|
||||
for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++)
|
||||
result.add(new MPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
@ -167,7 +203,7 @@ public class RuleSet implements IRuleSet{
|
||||
if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
// TODO Permutation?
|
||||
// Keine Permutation wie im Paper nötig
|
||||
Set<MPair> result = new HashSet<>();
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||
@ -182,28 +218,38 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<Set<MPair>> reduce1(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(!(lhsType instanceof SimpleType))
|
||||
|
||||
UnifyType c = pair.getLhsType();
|
||||
if(!(c instanceof SimpleType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof SimpleType))
|
||||
UnifyType d = pair.getRhsType();
|
||||
if(!(d instanceof SimpleType))
|
||||
return Optional.empty();
|
||||
|
||||
SimpleType lhsSType = (SimpleType) lhsType;
|
||||
SimpleType rhsSType = (SimpleType) rhsType;
|
||||
SimpleType lhsSType = (SimpleType) c;
|
||||
SimpleType rhsSType = (SimpleType) d;
|
||||
|
||||
if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
int[] pi = pi(lhsSType, rhsSType);
|
||||
UnifyType cFromFc = finiteClosure.getLeftHandedType(c).orElse(null);
|
||||
|
||||
if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType dFromFc = finiteClosure.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null);
|
||||
|
||||
if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams());
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
TypeParams rhsTypeParams = d.getTypeParams();
|
||||
TypeParams lhsTypeParams = c.getTypeParams();
|
||||
Set<MPair> result = new HashSet<>();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
|
||||
@ -458,36 +504,11 @@ public class RuleSet implements IRuleSet{
|
||||
* Finds the permutation pi of the type arguments of two types based on the finite closure
|
||||
* @param C The type which arguments are permuted
|
||||
* @param D The other type
|
||||
* @return An array containing the values of pi for every type argument of C or an empty array if the search failed.
|
||||
*/
|
||||
private int[] pi(UnifyType C, UnifyType D) {
|
||||
String simpleTypeDName = D.getName();
|
||||
if(D instanceof ExtendsType)
|
||||
simpleTypeDName = ((ExtendsType) D).getExtendedType().getName();
|
||||
else if(D instanceof SuperType)
|
||||
simpleTypeDName = ((SuperType) D).getSuperedType().getName();
|
||||
|
||||
String simpleTypeCName = C.getName();
|
||||
if(C instanceof ExtendsType)
|
||||
simpleTypeCName = ((ExtendsType) C).getExtendedType().getName();
|
||||
if(C instanceof SuperType)
|
||||
simpleTypeCName = ((SuperType) C).getSuperedType().getName();
|
||||
|
||||
Optional<UnifyType[]> typesFromFc = Optional.empty(); //TODO reduce regeln
|
||||
//finiteClosure.findCandD(simpleTypeCName, simpleTypeDName);
|
||||
|
||||
if(typesFromFc == null)
|
||||
return new int[0];
|
||||
|
||||
UnifyType cFromFc = typesFromFc.get()[0];
|
||||
UnifyType dFromFc = typesFromFc.get()[1];
|
||||
|
||||
Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size());
|
||||
Assert.assertTrue(dFromFc.getTypeParams().size() > 0);
|
||||
|
||||
TypeParams cArgs = cFromFc.getTypeParams();
|
||||
TypeParams dArgs = dFromFc.getTypeParams();
|
||||
|
||||
* @return An array containing the values of pi for every type argument of C or an empty array if the search failed.
|
||||
*/
|
||||
private int[] pi(TypeParams cArgs, TypeParams dArgs) {
|
||||
Assert.assertEquals(cArgs.size(), dArgs.size());
|
||||
|
||||
int[] permutation = new int[dArgs.size()];
|
||||
|
||||
boolean succ = true;
|
||||
@ -501,9 +522,8 @@ public class RuleSet implements IRuleSet{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(succ) return permutation;
|
||||
return new int[0];
|
||||
|
||||
return succ ? permutation : new int[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -521,12 +541,12 @@ public class RuleSet implements IRuleSet{
|
||||
typeMap.put(t2, typeMap.get(t2)+1);
|
||||
}
|
||||
|
||||
ArrayList<MPair> result = new ArrayList<MPair>(pairs);
|
||||
|
||||
Queue<MPair> result1 = new LinkedList<MPair>(pairs);
|
||||
ArrayList<MPair> result = new ArrayList<MPair>();
|
||||
boolean applied = false;
|
||||
|
||||
for(int i = 0; i < result.size(); i++) {
|
||||
MPair pair = result.get(i);
|
||||
while(!result1.isEmpty()) {
|
||||
MPair pair = result1.poll();
|
||||
PlaceholderType lhsType = null;
|
||||
UnifyType rhsType;
|
||||
|
||||
@ -539,8 +559,11 @@ public class RuleSet implements IRuleSet{
|
||||
&& !rhsType.getTypeParams().occurs(lhsType)) {
|
||||
Unifier uni = new Unifier(lhsType, rhsType);
|
||||
result = result.stream().map(uni::apply).collect(Collectors.toCollection(ArrayList::new));
|
||||
result1 = result1.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new));
|
||||
applied = true;
|
||||
}
|
||||
|
||||
result.add(pair);
|
||||
}
|
||||
|
||||
return applied ? Optional.of(new HashSet<>(result)) : Optional.empty();
|
||||
@ -563,10 +586,10 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<MPair> reduceWildcardLowRight(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if((lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType))
|
||||
if(!(lhsType instanceof SimpleType) || !(rhsType instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT));
|
||||
@ -589,13 +612,13 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<MPair> reduceWildcardUpRight(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if((lhsType instanceof SuperType) || !(rhsType instanceof SuperType))
|
||||
if(!(lhsType instanceof SimpleType) || !(rhsType instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOT));
|
||||
return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -628,9 +651,9 @@ public class RuleSet implements IRuleSet{
|
||||
public Optional<MPair> reduceWildcardLeft(MPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if((rhsType instanceof SuperType) || (rhsType instanceof ExtendsType))
|
||||
if(!(rhsType instanceof SimpleType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
|
@ -49,13 +49,12 @@ public interface IFiniteClosure {
|
||||
|
||||
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(UnifyType t);
|
||||
public Set<UnifyType> getAncestors(UnifyType t);
|
||||
|
||||
public Set<UnifyType> getAllTypesByName(String typeName);
|
||||
|
||||
public Set<UnifyType> getChildren(UnifyType t);
|
||||
public Set<UnifyType> getAllTypesByName(String typeName);
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
if (strInheritanceGraph.containsKey(type.getName())) {
|
||||
HashSet<UnifyType> candidates = new HashSet<>();
|
||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||
|
||||
|
||||
for(UnifyType typePrime : result1) {
|
||||
for (UnifyType theta2 : candidates) {
|
||||
for (UnifyType theta2 : candidates) {
|
||||
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
|
||||
if (!sigma2.isPresent())
|
||||
continue;
|
||||
@ -135,7 +135,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
|
||||
return result3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all types of the finite closure that are supertypes of the argument.
|
||||
* @return The set of supertypes of the argument.
|
||||
@ -358,7 +358,18 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
public Set<UnifyType> getAncestors(UnifyType t) {
|
||||
if(!inheritanceGraph.containsKey(t))
|
||||
return new HashSet<>();
|
||||
return inheritanceGraph.get(t).getContentOfPredecessors();
|
||||
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfPredecessors();
|
||||
result.add(t);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> getChildren(UnifyType t) {
|
||||
if(!inheritanceGraph.containsKey(t))
|
||||
return new HashSet<>();
|
||||
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfDescendants();
|
||||
result.add(t);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package de.dhbwstuttgart.typeinference.unify.model;
|
||||
|
||||
public class MPair {
|
||||
public class MPair {
|
||||
|
||||
private UnifyType lhs;
|
||||
private UnifyType rhs;
|
||||
|
@ -4,7 +4,6 @@ public enum PairOperator {
|
||||
SMALLER,
|
||||
SMALLERDOT,
|
||||
SMALLERDOTWC,
|
||||
EQUALS,
|
||||
EQUALSDOT;
|
||||
|
||||
@Override
|
||||
@ -16,8 +15,6 @@ public enum PairOperator {
|
||||
return "<.";
|
||||
case SMALLERDOTWC:
|
||||
return "<.?";
|
||||
case EQUALS:
|
||||
return "=";
|
||||
default:
|
||||
return "=.";
|
||||
}
|
||||
|
@ -12,9 +12,6 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
import de.dhbwstuttgart.typeinference.Pair;
|
||||
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
|
||||
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
|
||||
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
||||
@ -71,7 +68,7 @@ public class Unify {
|
||||
}
|
||||
|
||||
// Add the set of [a =. Theta | (a=. Theta) in Eq2']
|
||||
Set<MPair> bufferSet = eq2s.stream()
|
||||
Set<MPair> bufferSet = eq2s.stream()
|
||||
.filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
@ -136,15 +133,29 @@ public class Unify {
|
||||
* b) Build the union over everything
|
||||
*/
|
||||
|
||||
for(Set<MPair> eqss : changed) {
|
||||
for(Set<MPair> eqss : changed)
|
||||
eqPrimePrimeSet.addAll(this.unify(eqss, fc));
|
||||
|
||||
/*
|
||||
* Step 7: Filter empty sets;
|
||||
*/
|
||||
return eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x)).collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
}
|
||||
|
||||
protected boolean isSolvedForm(Set<MPair> eqPrimePrime) {
|
||||
for(MPair pair : eqPrimePrime) {
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
|
||||
if(!(lhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
|
||||
if(pair.getPairOp() != PairOperator.EQUALSDOT && !(rhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 7: Filter result for solved pairs
|
||||
*/
|
||||
return eqPrimePrimeSet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Set<MPair> applyTypeUnificationRules(Set<MPair> eq, IFiniteClosure fc) {
|
||||
@ -291,7 +302,8 @@ public class Unify {
|
||||
result.get(7).add(unifyCase8(lhsType, (PlaceholderType) rhsType, fc));
|
||||
}
|
||||
|
||||
return result.stream().filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new));
|
||||
return result.stream().map(x -> x.stream().filter(y -> y.size() > 0).collect(Collectors.toCollection(HashSet::new)))
|
||||
.filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
protected Set<MPair> unifyCase1(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) {
|
||||
@ -302,8 +314,8 @@ public class Unify {
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
@ -349,8 +361,8 @@ public class Unify {
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
@ -424,8 +436,8 @@ public class Unify {
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
|
@ -7,7 +7,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
|
||||
public class FiniteClosureBuilder {
|
||||
|
||||
@ -27,11 +27,13 @@ public class FiniteClosureBuilder {
|
||||
|
||||
public IFiniteClosure getCollectionExample() {
|
||||
TypeFactory tf = new TypeFactory();
|
||||
|
||||
/* Collection */
|
||||
|
||||
<<<<<<< HEAD
|
||||
UnifyType collection = tf.getSimpleType("Collection");
|
||||
UnifyType set = tf.getSimpleType("Set", "T");
|
||||
UnifyType sortedSet = tf.getSimpleType("Set", "T");
|
||||
//Type sortedSet = tf.getSimpleType("SortedSet", "T"); Sorted set bei den Unit-Tests vergessen
|
||||
// nachträgliches einfügen zu aufwendig
|
||||
UnifyType TreeSet = tf.getSimpleType("TreeSet", "T");
|
||||
UnifyType hashSet = tf.getSimpleType("HashSet", "T");
|
||||
UnifyType linkedHashSet = tf.getSimpleType("LinkedHashSet", "T");
|
||||
@ -41,25 +43,7 @@ public class FiniteClosureBuilder {
|
||||
UnifyType list = tf.getSimpleType("List", "T");
|
||||
UnifyType vector = tf.getSimpleType("Vector", "T");
|
||||
UnifyType stack = tf.getSimpleType("Stack", "T");
|
||||
UnifyType arrayList = tf.getSimpleType("ArrayList", "T");
|
||||
=======
|
||||
/* Collection */
|
||||
|
||||
Type collection = tf.getSimpleType("Collection");
|
||||
Type set = tf.getSimpleType("Set", "T");
|
||||
//Type sortedSet = tf.getSimpleType("SortedSet", "T"); Sorted set bei den Unit-Tests vergessen
|
||||
// nachträgliches einfügen zu aufwendig
|
||||
Type TreeSet = tf.getSimpleType("TreeSet", "T");
|
||||
Type hashSet = tf.getSimpleType("HashSet", "T");
|
||||
Type linkedHashSet = tf.getSimpleType("LinkedHashSet", "T");
|
||||
Type queue = tf.getSimpleType("Queue", "T");
|
||||
Type deque = tf.getSimpleType("Deque", "T");
|
||||
Type linkedList = tf.getSimpleType("LinkedList", "T");
|
||||
Type list = tf.getSimpleType("List", "T");
|
||||
Type vector = tf.getSimpleType("Vector", "T");
|
||||
Type stack = tf.getSimpleType("Stack", "T");
|
||||
Type arrayList = tf.getSimpleType("ArrayList", "T");
|
||||
>>>>>>> unify
|
||||
UnifyType arrayList = tf.getSimpleType("ArrayList", "T");
|
||||
|
||||
add(set, collection);
|
||||
//add(sortedSet, set);
|
||||
@ -77,13 +61,13 @@ public class FiniteClosureBuilder {
|
||||
add(stack, vector);
|
||||
|
||||
/* Map */
|
||||
Type map = tf.getSimpleType("Map", "K", "V");
|
||||
Type sortedMap = tf.getSimpleType("SortedMap", "K", "V");
|
||||
Type navigableMap = tf.getSimpleType("NavigableMap", "K", "V");
|
||||
Type treeMap = tf.getSimpleType("TreeMap", "K", "V");
|
||||
Type hashMap = tf.getSimpleType("HashMap", "K", "V");
|
||||
Type hashtable = tf.getSimpleType("Hashtable", "K", "V");
|
||||
Type linkedHashMap = tf.getSimpleType("LinkedHashMap", "K", "V");
|
||||
UnifyType map = tf.getSimpleType("Map", "K", "V");
|
||||
UnifyType sortedMap = tf.getSimpleType("SortedMap", "K", "V");
|
||||
UnifyType navigableMap = tf.getSimpleType("NavigableMap", "K", "V");
|
||||
UnifyType treeMap = tf.getSimpleType("TreeMap", "K", "V");
|
||||
UnifyType hashMap = tf.getSimpleType("HashMap", "K", "V");
|
||||
UnifyType hashtable = tf.getSimpleType("Hashtable", "K", "V");
|
||||
UnifyType linkedHashMap = tf.getSimpleType("LinkedHashMap", "K", "V");
|
||||
|
||||
add(sortedMap, map);
|
||||
add(hashMap, map);
|
||||
|
@ -100,12 +100,11 @@ public class FiniteClosureTest {
|
||||
|
||||
/*
|
||||
* Test Case 4:
|
||||
* TODO ist das ergebnis korrekt oder müssen die ? ext Ts raus weil der allgemeienste Typ T ausreicht?
|
||||
* smaller(Set<T>) =
|
||||
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T> }
|
||||
*/
|
||||
|
||||
<<<<<<< HEAD
|
||||
UnifyType t = tf.getPlaceholderType("T");
|
||||
UnifyType setT = tf.getSimpleType("Set", t);
|
||||
UnifyType hashSetT = tf.getSimpleType("HashSet", t);
|
||||
@ -119,6 +118,16 @@ public class FiniteClosureTest {
|
||||
expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] {
|
||||
setT, hashSetT, treeSetT, linkedHashSetT,
|
||||
setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT
|
||||
=======
|
||||
Type t = tf.getPlaceholderType("T");
|
||||
Type setT = tf.getSimpleType("Set", t);
|
||||
Type hashSetT = tf.getSimpleType("HashSet", t);
|
||||
Type treeSetT = tf.getSimpleType("TreeSet", t);
|
||||
Type linkedHashSetT = tf.getSimpleType("LinkedHashSet", t);
|
||||
|
||||
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||
setT, hashSetT, treeSetT, linkedHashSetT
|
||||
>>>>>>> d89d06797e17a7a95f007fe24e9b6133b3b13179
|
||||
}).collect(Collectors.toSet()));
|
||||
|
||||
Assert.assertEquals(expectedResult, fc.smaller(setT));
|
||||
@ -155,19 +164,35 @@ public class FiniteClosureTest {
|
||||
|
||||
/*
|
||||
* Test Case 6:
|
||||
*
|
||||
* smaller(Set<? ext T) =
|
||||
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||
* TODO probleme wenn Set<? extends T> weil T auch in der Klassendeklaration class Set<T> verwendet wird.
|
||||
* smaller(Set<? ext T1) =
|
||||
* { HashSet<T1>, Set<T1>, TreeSet<T1>, LinkedHashSet<T1>,
|
||||
* HashSet<? ext T1>, Set<? ext T1>, TreeSet<? ext T1>, LinkedHashSet<? ext T1> }
|
||||
*
|
||||
*/
|
||||
<<<<<<< HEAD
|
||||
|
||||
expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] {
|
||||
setT, hashSetT, treeSetT, linkedHashSetT,
|
||||
setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT
|
||||
=======
|
||||
Type t1 = tf.getPlaceholderType("T1");
|
||||
Type extT1 = tf.getExtendsType(t1);
|
||||
Type setExtT1 = tf.getSimpleType("Set", extT1);
|
||||
Type hashSetExtT1 = tf.getSimpleType("HashSet", extT1);
|
||||
Type treeSetExtT1 = tf.getSimpleType("TreeSet", extT1);
|
||||
Type linkedHashSetExtT1 = tf.getSimpleType("LinkedHashSet", extT1);
|
||||
Type setT1 = tf.getSimpleType("Set", t1);
|
||||
Type hashSetT1 = tf.getSimpleType("HashSet", t1);
|
||||
Type treeSetT1 = tf.getSimpleType("TreeSet", t1);
|
||||
Type linkedHashSetT1 = tf.getSimpleType("LinkedHashSet", t1);
|
||||
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||
setT1, hashSetT1, treeSetT1, linkedHashSetT1,
|
||||
setExtT1, hashSetExtT1, treeSetExtT1, linkedHashSetExtT1
|
||||
>>>>>>> d89d06797e17a7a95f007fe24e9b6133b3b13179
|
||||
}).collect(Collectors.toSet()));
|
||||
|
||||
Assert.assertEquals(expectedResult, fc.smaller(setExtT));
|
||||
Assert.assertEquals(expectedResult, fc.smaller(setExtT1));
|
||||
|
||||
/*
|
||||
* Test Case 7:
|
||||
@ -658,7 +683,6 @@ public class FiniteClosureTest {
|
||||
|
||||
@Test
|
||||
public void testGetGenericType() {
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.SimpleType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
|
||||
|
||||
public class RuleSetTest {
|
||||
|
@ -7,27 +7,29 @@ import org.junit.Test;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyPairMengenBuilder;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.Unify_FC_TTO_Builder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ObjectType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Type;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Type;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
import de.dhbwstuttgart.typeinference.Pair;
|
||||
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.Unify;
|
||||
|
||||
public class UnifyOldTest {
|
||||
|
||||
@Test
|
||||
public void unifyTestSimpleTypes() {
|
||||
public void unifyTest1() {
|
||||
// Init Factories and Builders
|
||||
Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
|
||||
UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
|
||||
UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
|
||||
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
* Test a <. Boolean
|
||||
*/
|
||||
@ -330,5 +332,317 @@ public class UnifyOldTest {
|
||||
private TypePlaceholder GetTypePlaceholder(String name) {
|
||||
return TypePlaceholder.backdoorCreate(name);
|
||||
}
|
||||
=======
|
||||
TypePlaceholder a = typeFactory.GetTypePlaceholder("a");
|
||||
ExtendsWildcardType extA = typeFactory.GetExtendsType(a);
|
||||
TypePlaceholder b = typeFactory.GetTypePlaceholder("b");
|
||||
ExtendsWildcardType extB = typeFactory.GetExtendsType(b);
|
||||
RefType integer = typeFactory.GetSimpleType("Integer");
|
||||
SuperWildcardType supInt = typeFactory.GetSuperType(integer);
|
||||
RefType listsupint = typeFactory.GetSimpleType("List", supInt);
|
||||
RefType number = typeFactory.GetSimpleType("Number");
|
||||
RefType object = typeFactory.GetSimpleType("XObjectX");
|
||||
ExtendsWildcardType extNum = typeFactory.GetExtendsType(number);
|
||||
RefType intlist = typeFactory.GetSimpleType("List", integer);
|
||||
RefType alist = typeFactory.GetSimpleType("List", a);
|
||||
RefType extBlist = typeFactory.GetSimpleType("List", extB);
|
||||
RefType blist = typeFactory.GetSimpleType("List", b);
|
||||
RefType extNumlist = typeFactory.GetSimpleType("List", extNum);
|
||||
|
||||
fcBuilder.AddInheritance(number, object);
|
||||
fcBuilder.AddInheritance(integer, number);
|
||||
|
||||
|
||||
assumptionBuilder.addPair(alist, extBlist, PairOperator.Smaller);
|
||||
assumptionBuilder.addPair(blist, extNumlist, PairOperator.Smaller);
|
||||
|
||||
System.out.println(Unify.unify(assumptionBuilder.getPairMenge(),
|
||||
fcBuilder.Get_FC_TTO()));
|
||||
}
|
||||
//
|
||||
// @Test
|
||||
// public void unifyTestSimpleTypes() {
|
||||
// // Init Factories and Builders
|
||||
// UnifyTypeFactory typeFactory = new UnifyTypeFactory();
|
||||
// Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
|
||||
// UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
|
||||
// UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
|
||||
//
|
||||
// /*
|
||||
// * Test a <. Boolean
|
||||
// */
|
||||
//
|
||||
// // Init Types
|
||||
// RefType boolT = typeFactory.GetSimpleType("java.lang.Boolean");
|
||||
// TypePlaceholder aTph = typeFactory.GetTypePlaceholder("a");
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// resultBuilder.addPair(aTph, boolT, PairOperator.Equal);
|
||||
// resultBuilder.addPair(aTph, typeFactory.GetExtendsType(boolT),
|
||||
// PairOperator.Equal);
|
||||
// Menge<Menge<Pair>> expectedResult = resultBuilder.getNestedPairMenge();
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(aTph, boolT);
|
||||
// Menge<Menge<Pair>> actualResult = Unify.unify(
|
||||
// assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(expectedResult);
|
||||
// // System.out.println(actualResult);
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// /*
|
||||
// * Test b <. a, a <. Boolean
|
||||
// */
|
||||
//
|
||||
// // Init Types
|
||||
// boolT = typeFactory.GetSimpleType("java.lang.Boolean");
|
||||
// aTph = typeFactory.GetTypePlaceholder("a");
|
||||
// TypePlaceholder bTph = typeFactory.GetTypePlaceholder("b");
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// resultBuilder.addPair(aTph, boolT, PairOperator.Equal);
|
||||
// resultBuilder.addPair(aTph, typeFactory.GetExtendsType(boolT),
|
||||
// PairOperator.Equal);
|
||||
// resultBuilder.addPair(bTph, boolT, PairOperator.Equal);
|
||||
// resultBuilder.addPair(bTph, typeFactory.GetExtendsType(boolT),
|
||||
// PairOperator.Equal);
|
||||
// expectedResult = resultBuilder.getNestedPairMenge();
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(bTph, aTph);
|
||||
// assumptionBuilder.addPair(aTph, boolT);
|
||||
// actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
|
||||
// fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(expectedResult);
|
||||
// // System.out.println(actualResult);
|
||||
//
|
||||
// // NOTE: Elemente im actualResult sind nicht unique
|
||||
// // Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// /*
|
||||
// * Test b <. a, a <. b
|
||||
// */
|
||||
//
|
||||
// aTph = typeFactory.GetTypePlaceholder("a");
|
||||
// bTph = typeFactory.GetTypePlaceholder("b");
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// resultBuilder.addPair(bTph, aTph);
|
||||
// resultBuilder.addPair(aTph, bTph);
|
||||
//
|
||||
// Menge<Pair> buffer = resultBuilder.getPairMenge();
|
||||
// expectedResult = new Menge<Menge<Pair>>();
|
||||
// expectedResult.add(buffer);
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(bTph, aTph);
|
||||
// assumptionBuilder.addPair(aTph, bTph);
|
||||
// actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
|
||||
// fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(expectedResult);
|
||||
// // System.out.println(actualResult);
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// /*
|
||||
// * Test Integer <. a, a <. Boolean
|
||||
// */
|
||||
//
|
||||
// RefType intT = typeFactory.GetSimpleType("java.lang.Integer");
|
||||
// boolT = typeFactory.GetSimpleType("java.lang.Boolean");
|
||||
// aTph = typeFactory.GetTypePlaceholder("a");
|
||||
// bTph = typeFactory.GetTypePlaceholder("b");
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// expectedResult = resultBuilder.getNestedPairMenge();
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(intT, aTph);
|
||||
// assumptionBuilder.addPair(aTph, boolT);
|
||||
// actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
|
||||
// fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(expectedResult);
|
||||
// // System.out.println(actualResult);
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void unifyTestGenerics() {
|
||||
//
|
||||
// // Init Factories and Builders
|
||||
// UnifyTypeFactory typeFactory = new UnifyTypeFactory();
|
||||
// Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
|
||||
// UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
|
||||
// UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
|
||||
//
|
||||
// /*
|
||||
// * Test a <. MyClass<T, F>
|
||||
// */
|
||||
//
|
||||
// TypePlaceholder aTph = typeFactory.GetTypePlaceholder("a");
|
||||
// RefType myType = typeFactory.GetSimpleType("MyClass",
|
||||
// typeFactory.GetTypePlaceholder("T"),
|
||||
// typeFactory.GetTypePlaceholder("F"));
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// resultBuilder.addPair(aTph, myType, PairOperator.Equal);
|
||||
// resultBuilder.addPair(aTph, typeFactory.GetExtendsType(myType));
|
||||
// Menge<Menge<Pair>> expectedResult = resultBuilder.getNestedPairMenge();
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(aTph, myType);
|
||||
// Menge<Menge<Pair>> actualResult = Unify.unify(
|
||||
// assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(expectedResult);
|
||||
// // System.out.println(actualResult);
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// /*
|
||||
// * Test List<List<T>> <. List<T>
|
||||
// */
|
||||
//
|
||||
// TypePlaceholder tTph = typeFactory.GetTypePlaceholder("T");
|
||||
// RefType list = typeFactory.GetSimpleType("List", tTph);
|
||||
// RefType listlist = typeFactory.GetSimpleType("List", list);
|
||||
//
|
||||
// // Expected Result
|
||||
// resultBuilder.clear();
|
||||
// resultBuilder.addPair(typeFactory.GetExtendsType(list), tTph,
|
||||
// PairOperator.Equal);
|
||||
// expectedResult = resultBuilder.getNestedPairMenge();
|
||||
//
|
||||
// // Actual Result
|
||||
// assumptionBuilder.clear();
|
||||
// assumptionBuilder.addPair(listlist, list);
|
||||
// actualResult = Unify.unify(assumptionBuilder.getPairMenge(),
|
||||
// fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// System.out.println(expectedResult);
|
||||
// System.out.println(actualResult);
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(expectedResult, actualResult));
|
||||
//
|
||||
// /*
|
||||
// * Test List<T> <. List<List<T>>
|
||||
// */
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void unifyTestInheritance() {
|
||||
//
|
||||
// // Init Factories and Builders
|
||||
// UnifyTypeFactory typeFactory = new UnifyTypeFactory();
|
||||
// Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder();
|
||||
// UnifyPairMengenBuilder assumptionBuilder = new UnifyPairMengenBuilder();
|
||||
// UnifyPairMengenBuilder resultBuilder = new UnifyPairMengenBuilder();
|
||||
//
|
||||
// // Init Types
|
||||
// RefType tBool = typeFactory.GetSimpleType("java.lang.Boolean");
|
||||
// RefType tString = typeFactory.GetSimpleType("java.lang.String");
|
||||
// RefType tInt = typeFactory.GetSimpleType("java.lang.Integer");
|
||||
// TypePlaceholder tphA = typeFactory.GetTypePlaceholder("a");
|
||||
//
|
||||
// // Build inheritance hierachy
|
||||
// // Bool <. String <. Int
|
||||
// fcBuilder.AddInheritance(tBool, tString);
|
||||
// fcBuilder.AddInheritance(tString, tInt);
|
||||
//
|
||||
// // Build Assumptions
|
||||
// assumptionBuilder.addPair(tphA, tString);
|
||||
//
|
||||
// // Build expected result
|
||||
// resultBuilder.addPair(tphA, tBool, PairOperator.Equal);
|
||||
// resultBuilder.addPair(tphA, typeFactory.GetExtendsType(tBool),
|
||||
// PairOperator.Equal);
|
||||
// resultBuilder.addPair(tphA, tString, PairOperator.Equal);
|
||||
// resultBuilder.addPair(tphA, typeFactory.GetExtendsType(tString),
|
||||
// PairOperator.Equal);
|
||||
//
|
||||
// // Assert
|
||||
// Menge<Menge<Pair>> actualResult = Unify.unify(
|
||||
// assumptionBuilder.getPairMenge(), fcBuilder.Get_FC_TTO());
|
||||
//
|
||||
// // System.out.println(actualResult);
|
||||
// // System.out.println("-------------------");
|
||||
// // System.out.println(resultBuilder.getNestedPairMenge());
|
||||
//
|
||||
// Assert.assertTrue(mengeEquals(resultBuilder.getNestedPairMenge(),
|
||||
// actualResult));
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void unifyTestWildcards() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static boolean mengeEquals(Menge<Menge<Pair>> m1,
|
||||
// Menge<Menge<Pair>> m2) {
|
||||
// if (m1.size() != m2.size())
|
||||
// return false;
|
||||
//
|
||||
// return containsAll(m1, m2) && containsAll(m2, m1);
|
||||
// }
|
||||
//
|
||||
// private static boolean containsAll(Menge<Menge<Pair>> m1,
|
||||
// Menge<Menge<Pair>> m2) {
|
||||
// for (Menge<Pair> elem : m2)
|
||||
// if (!contains(m1, elem))
|
||||
// return false;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// private static boolean contains(Menge<Menge<Pair>> m1, Menge<Pair> m2) {
|
||||
// for (Menge<Pair> elem : m1)
|
||||
// if (mengePairEquals(elem, m2))
|
||||
// return true;
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean mengePairEquals(Menge<Pair> m1, Menge<Pair> m2) {
|
||||
// if (m1.size() != m2.size())
|
||||
// return false;
|
||||
//
|
||||
// return containsAllPair(m1, m2) && containsAllPair(m2, m1);
|
||||
// }
|
||||
//
|
||||
// private static boolean containsAllPair(Menge<Pair> m1, Menge<Pair> m2) {
|
||||
// for (Pair elem : m1)
|
||||
// if (contains(m2, elem))
|
||||
// return true;
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean contains(Menge<Pair> m, Pair p) {
|
||||
// for (Pair elem : m)
|
||||
// if (pairEquals(elem, p))
|
||||
// return true;
|
||||
// return false;
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static boolean pairEquals(Pair p1, Pair p2) {
|
||||
// return (p1.TA1.equals(p2.TA1) && p1.TA2.equals(p2.TA2))
|
||||
// || (p1.TA1.equals(p2.TA2) && p1.TA2.equals(p2.TA1));
|
||||
// }
|
||||
>>>>>>> d89d06797e17a7a95f007fe24e9b6133b3b13179
|
||||
|
||||
}
|
||||
|
@ -1,50 +1,344 @@
|
||||
package unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.Unify;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class UnifyTest extends Unify {
|
||||
|
||||
/**
|
||||
* Testing the unification for cases with (n)one pair and without generics.
|
||||
*/
|
||||
@Test
|
||||
public void unifyTest() {
|
||||
public void unifyTestTrivial() {
|
||||
/*
|
||||
* INIT
|
||||
*/
|
||||
|
||||
TypeFactory tf = new TypeFactory();
|
||||
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
|
||||
Set<MPair> eq = new HashSet<MPair>();
|
||||
|
||||
//fcb.add(tf.getSimpleType("Number"), tf.getSimpleType("Object"));
|
||||
fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number"));
|
||||
fcb.add(tf.getSimpleType("Double"), tf.getSimpleType("Number"));
|
||||
fcb.add(tf.getSimpleType("MyList"), tf.getSimpleType("List", tf.getSimpleType("Integer")));
|
||||
//fcb.add(tf.getSimpleType("List", "T"));
|
||||
|
||||
UnifyType number = tf.getSimpleType("Number");
|
||||
UnifyType object = tf.getSimpleType("Object");
|
||||
UnifyType integer = tf.getSimpleType("Integer");
|
||||
UnifyType doubl = tf.getSimpleType("Double");
|
||||
|
||||
fcb.add(number, object);
|
||||
fcb.add(integer, number);
|
||||
fcb.add(doubl, number);
|
||||
|
||||
IFiniteClosure fc = fcb.getCollectionExample();
|
||||
|
||||
// Vector<Integer> <. Vector<A>
|
||||
// Vector<Integer <. Vector<C>
|
||||
// A <. Integer
|
||||
// Number <. A
|
||||
// Double <. B
|
||||
// B <. Object
|
||||
eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT));
|
||||
eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Number")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "C"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("List", "A"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getSimpleType("Number"), tf.getPlaceholderType("A"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getPlaceholderType("A"), tf.getPlaceholderType("C"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getSimpleType("Double"), tf.getPlaceholderType("B"), PairOperator.SMALLERDOT));
|
||||
//eq.add(new MPair(tf.getPlaceholderType("B"), tf.getSimpleType("Object"), PairOperator.EQUALSDOT));
|
||||
/*
|
||||
* Test 1:
|
||||
*
|
||||
* unify({ }) = { }
|
||||
*/
|
||||
|
||||
System.out.println(this.unify(eq, fc));
|
||||
Set<MPair> eq = new HashSet<MPair>();
|
||||
Set<Set<MPair>> expected = new HashSet<>();
|
||||
Set<Set<MPair>> actual = unify(eq, fc);
|
||||
Assert.assertEquals(actual, expected);
|
||||
|
||||
/*
|
||||
* Test 2:
|
||||
*
|
||||
* (a <. Number)
|
||||
*/
|
||||
|
||||
UnifyType tphA = tf.getPlaceholderType("a");
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(tphA, number, PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, number, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, integer, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, doubl, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 3:
|
||||
*
|
||||
* (Integer <. a)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(integer, tphA, PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, integer, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, number, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, object, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
|
||||
/*
|
||||
* Test 4:
|
||||
*
|
||||
* (a <.? Number)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(tphA, number, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, number, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 5:
|
||||
*
|
||||
* (a <.? ? super Integer)
|
||||
*/
|
||||
|
||||
UnifyType supInteger = tf.getSuperType(integer);
|
||||
UnifyType supNumber = tf.getSuperType(number);
|
||||
UnifyType supObject = tf.getSuperType(object);
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(tphA, supInteger, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, integer, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, number, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, object, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supInteger, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supNumber, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supObject, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 6:
|
||||
*
|
||||
* (Number <.? a)
|
||||
*
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
UnifyType extNumber = tf.getExtendsType(number);
|
||||
UnifyType extObject = tf.getExtendsType(object);
|
||||
UnifyType supDouble = tf.getSuperType(doubl);
|
||||
eq.add(new MPair(number, tphA, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, number, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, extNumber, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, extObject, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supInteger, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supDouble, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, supNumber, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 7:
|
||||
*
|
||||
* (? extends Number <.? a)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(extNumber, tphA, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, extNumber, PairOperator.EQUALSDOT));
|
||||
addAsSet(expected, new MPair(tphA, extObject, PairOperator.EQUALSDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
|
||||
/*
|
||||
* Test 8:
|
||||
*
|
||||
* (Integer <. Number)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(integer, number, PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 9:
|
||||
*
|
||||
* (Integer <.? Number)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(integer, number, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 10:
|
||||
*
|
||||
* (a <. b)
|
||||
*/
|
||||
|
||||
UnifyType tphB = tf.getPlaceholderType("b");
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(tphA, tphB, PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, tphB, PairOperator.SMALLERDOT));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
/*
|
||||
* Test 11:
|
||||
*
|
||||
* (a <.? b)
|
||||
*/
|
||||
|
||||
eq = new HashSet<>();
|
||||
eq.add(new MPair(tphA, tphB, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
addAsSet(expected, new MPair(tphA, tphB, PairOperator.SMALLERDOTWC));
|
||||
|
||||
actual = unify(eq, fc);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unifyTestSimple() {
|
||||
/*
|
||||
* INIT
|
||||
*/
|
||||
TypeFactory tf = new TypeFactory();
|
||||
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
|
||||
|
||||
UnifyType number = tf.getSimpleType("Number");
|
||||
UnifyType object = tf.getSimpleType("Object");
|
||||
UnifyType integer = tf.getSimpleType("Integer");
|
||||
UnifyType doubl = tf.getSimpleType("Double");
|
||||
|
||||
fcb.add(number, object);
|
||||
fcb.add(integer, number);
|
||||
fcb.add(doubl, number);
|
||||
|
||||
IFiniteClosure fc = fcb.getCollectionExample();
|
||||
|
||||
/*
|
||||
* Test 1:
|
||||
*
|
||||
* (Vector<a> <. Vector<? extends b>)
|
||||
* (List<b> <. List<? extends Number>)
|
||||
*/
|
||||
|
||||
UnifyType tphA = tf.getPlaceholderType("a");
|
||||
UnifyType tphB = tf.getPlaceholderType("b");
|
||||
UnifyType extB = tf.getExtendsType(tphB);
|
||||
UnifyType extNum = tf.getExtendsType(number);
|
||||
|
||||
Set<MPair> eq = new HashSet<MPair>();
|
||||
eq.add(new MPair(tf.getSimpleType("Vector", tphA), tf.getSimpleType("Vector", extB), PairOperator.SMALLERDOT));
|
||||
eq.add(new MPair(tf.getSimpleType("List", tphB), tf.getSimpleType("List", extNum), PairOperator.SMALLERDOT));
|
||||
|
||||
Set<Set<MPair>> expected = new HashSet<>();
|
||||
Set<Set<MPair>> actual = unify(eq, fc);
|
||||
|
||||
System.out.println(actual);
|
||||
//Assert.assertEquals(actual, expected);
|
||||
|
||||
/*
|
||||
* Test 2:
|
||||
*
|
||||
* Vector<? extends a> <. List<? extends Number>
|
||||
*
|
||||
*/
|
||||
|
||||
UnifyType extA = tf.getExtendsType(tphA);
|
||||
|
||||
eq = new HashSet<MPair>();
|
||||
eq.add(new MPair(tf.getSimpleType("Vector", extA), tf.getSimpleType("Vector", extNum), PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
actual = unify(eq, fc);
|
||||
|
||||
System.out.println(actual);
|
||||
//Assert.assertEquals(actual, expected);
|
||||
|
||||
/*
|
||||
* Test 3:
|
||||
*
|
||||
* Vector<? extends Number> <. List<? extends a>
|
||||
*
|
||||
*/
|
||||
|
||||
eq = new HashSet<MPair>();
|
||||
eq.add(new MPair(tf.getSimpleType("Vector", extNum), tf.getSimpleType("Vector", extA), PairOperator.SMALLERDOT));
|
||||
|
||||
expected = new HashSet<>();
|
||||
actual = unify(eq, fc);
|
||||
|
||||
System.out.println(actual);
|
||||
//Assert.assertEquals(actual, expected);
|
||||
|
||||
/*
|
||||
* Test 4:
|
||||
*
|
||||
* LinkedList <. Deque <. Queue <. Collection
|
||||
*
|
||||
* Vector<Number> <. List<a>
|
||||
* List<a> <. AbstractList<b>
|
||||
* ? extends Number <.? b
|
||||
*/
|
||||
|
||||
eq = new HashSet<MPair>();
|
||||
eq.add(new MPair(tf.getSimpleType("LinkedList", number), tf.getSimpleType("Deque", tphA), PairOperator.SMALLERDOT));
|
||||
eq.add(new MPair(tf.getSimpleType("Deque", tphA), tf.getSimpleType("Queue", tphB), PairOperator.SMALLERDOT));
|
||||
eq.add(new MPair(extNum, tphB, PairOperator.SMALLERDOTWC));
|
||||
|
||||
expected = new HashSet<>();
|
||||
actual = unify(eq, fc);
|
||||
|
||||
System.out.println(actual);
|
||||
//Assert.assertEquals(actual, expected);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unifyTestComplex() {
|
||||
|
||||
}
|
||||
|
||||
@ -82,7 +376,12 @@ public class UnifyTest extends Unify {
|
||||
|
||||
Set<TypeParams> result = permuteParams(candidates);
|
||||
|
||||
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
|
||||
private void addAsSet(Set<Set<MPair>> addTo, MPair... mPairs) {
|
||||
addTo.add(new HashSet<>(Arrays.stream(mPairs).collect(Collectors.toSet())));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user