diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index a2aa42f0..c31fc695 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -339,7 +339,7 @@ public class Pair implements Serializable, DeepCloneable */ public boolean OperatorEqual() { - return eOperator == PairOperator.EQUALS; + return eOperator == PairOperator.EQUALSDOT; } /** diff --git a/src/de/dhbwstuttgart/typeinference/unify/Mapping.java b/src/de/dhbwstuttgart/typeinference/unify/Mapping.java index 07206065..5c9be501 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/Mapping.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Mapping.java @@ -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 unmap(de.dhbwstuttgart.typeinference.unify.model.MPair mpair) { + public Optional 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> unmapTypeSet(Set types) { @@ -57,7 +58,7 @@ public class Mapping { Set 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; diff --git a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java index da29a58f..22759fbc 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java @@ -31,9 +31,9 @@ public class MartelliMontanariUnify implements IUnify { ArrayList termsQ = new ArrayList(); Iterator 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; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index 297eadbf..3ae16c23 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -84,11 +84,15 @@ public class RuleSet implements IRuleSet{ public Optional> 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 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> 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 result = new HashSet<>(); + + int[] pi = pi(xParams, supYParams); if(pi.length == 0) return Optional.empty(); - TypeParams rhsTypeParams = rhsType.getTypeParams(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); - Set 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 result = new HashSet<>(); TypeParams lhsTypeParams = lhsType.getTypeParams(); TypeParams rhsTypeParams = rhsType.getTypeParams(); @@ -182,28 +218,38 @@ public class RuleSet implements IRuleSet{ public Optional> 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 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 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 result = new ArrayList(pairs); - + Queue result1 = new LinkedList(pairs); + ArrayList result = new ArrayList(); 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 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 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 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(); diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 54ca107c..06e12a36 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -49,13 +49,12 @@ public interface IFiniteClosure { public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); - + public Set grArg(FunNType type); public Set smArg(FunNType type); public Optional getLeftHandedType(UnifyType t); public Set getAncestors(UnifyType t); - - public Set getAllTypesByName(String typeName); - + public Set getChildren(UnifyType t); + public Set getAllTypesByName(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index f04ccfcd..a4c5a51d 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -94,9 +94,9 @@ public class FiniteClosure implements IFiniteClosure { if (strInheritanceGraph.containsKey(type.getName())) { HashSet 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 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 getAncestors(UnifyType t) { if(!inheritanceGraph.containsKey(t)) return new HashSet<>(); - return inheritanceGraph.get(t).getContentOfPredecessors(); + Set result = inheritanceGraph.get(t).getContentOfPredecessors(); + result.add(t); + return result; + } + + @Override + public Set getChildren(UnifyType t) { + if(!inheritanceGraph.containsKey(t)) + return new HashSet<>(); + Set result = inheritanceGraph.get(t).getContentOfDescendants(); + result.add(t); + return result; } protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java index dc4aa142..254ba142 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java @@ -1,6 +1,6 @@ package de.dhbwstuttgart.typeinference.unify.model; -public class MPair { +public class MPair { private UnifyType lhs; private UnifyType rhs; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java b/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java index 0f55be30..7b8258bd 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java @@ -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 "=."; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 5dd89a21..34e5e161 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -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 bufferSet = eq2s.stream() + Set 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 eqss : changed) { + for(Set 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 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 applyTypeUnificationRules(Set 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 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 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 thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); thetaQs.add(c); // reflexive Set 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 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 thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); thetaQs.add(c); // reflexive Set 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 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 thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); thetaQs.add(c); // reflexive Set thetaQPrimes = new HashSet<>(); diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index 69ff63be..dcda97fd 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -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); diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 6ac50fe0..a391adeb 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -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) = - * { HashSet, Set, TreeSet, LinkedHashSet, - * HashSet, Set, TreeSet, LinkedHashSet } + * { HashSet, Set, TreeSet, LinkedHashSet } */ +<<<<<<< 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, Set, TreeSet, LinkedHashSet, - * HashSet, Set, TreeSet, LinkedHashSet } + * TODO probleme wenn Set weil T auch in der Klassendeklaration class Set verwendet wird. + * smaller(Set, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } * */ +<<<<<<< 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 } diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index f38d9f2c..0ae1d49c 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -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 { diff --git a/test/unify/UnifyOldTest.java b/test/unify/UnifyOldTest.java index 9a28e30a..a2de8ce0 100644 --- a/test/unify/UnifyOldTest.java +++ b/test/unify/UnifyOldTest.java @@ -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> expectedResult = resultBuilder.getNestedPairMenge(); +// +// // Actual Result +// assumptionBuilder.clear(); +// assumptionBuilder.addPair(aTph, boolT); +// Menge> 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 buffer = resultBuilder.getPairMenge(); +// expectedResult = new Menge>(); +// 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 +// */ +// +// 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> expectedResult = resultBuilder.getNestedPairMenge(); +// +// // Actual Result +// assumptionBuilder.clear(); +// assumptionBuilder.addPair(aTph, myType); +// Menge> 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 +// */ +// +// 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 <. List> +// */ +// } +// +// @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> 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> m1, +// Menge> m2) { +// if (m1.size() != m2.size()) +// return false; +// +// return containsAll(m1, m2) && containsAll(m2, m1); +// } +// +// private static boolean containsAll(Menge> m1, +// Menge> m2) { +// for (Menge elem : m2) +// if (!contains(m1, elem)) +// return false; +// return true; +// } +// +// private static boolean contains(Menge> m1, Menge m2) { +// for (Menge elem : m1) +// if (mengePairEquals(elem, m2)) +// return true; +// return false; +// } +// +// private static boolean mengePairEquals(Menge m1, Menge m2) { +// if (m1.size() != m2.size()) +// return false; +// +// return containsAllPair(m1, m2) && containsAllPair(m2, m1); +// } +// +// private static boolean containsAllPair(Menge m1, Menge m2) { +// for (Pair elem : m1) +// if (contains(m2, elem)) +// return true; +// return false; +// } +// +// private static boolean contains(Menge 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 } diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 8a6f2f32..852ecbdf 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -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 eq = new HashSet(); - - //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 <. Vector - // Vector - // 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 eq = new HashSet(); + Set> expected = new HashSet<>(); + Set> 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 <. Vector) + * (List <. List) + */ + + UnifyType tphA = tf.getPlaceholderType("a"); + UnifyType tphB = tf.getPlaceholderType("b"); + UnifyType extB = tf.getExtendsType(tphB); + UnifyType extNum = tf.getExtendsType(number); + + Set eq = new HashSet(); + 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> expected = new HashSet<>(); + Set> actual = unify(eq, fc); + + System.out.println(actual); + //Assert.assertEquals(actual, expected); + + /* + * Test 2: + * + * Vector <. List + * + */ + + UnifyType extA = tf.getExtendsType(tphA); + + eq = new HashSet(); + 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 <. List + * + */ + + eq = new HashSet(); + 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 <. List + * List <. AbstractList + * ? extends Number <.? b + */ + + eq = new HashSet(); + 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 result = permuteParams(candidates); + System.out.println(result); } + + private void addAsSet(Set> addTo, MPair... mPairs) { + addTo.add(new HashSet<>(Arrays.stream(mPairs).collect(Collectors.toSet()))); + } }