diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 193c8589..df903209 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -32,7 +32,7 @@ import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.SimpleType; +import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; @@ -82,9 +82,9 @@ public class UnifyTypeFactory { for(Type pT : t.getParaList()){ params.add(UnifyTypeFactory.convert(pT)); } - ret = new SimpleType(t.get_Name(),new TypeParams(params)); + ret = new ReferenceType(t.get_Name(),new TypeParams(params)); }else{ - ret = new SimpleType(t.get_Name()); + ret = new ReferenceType(t.get_Name()); } return ret; } @@ -102,7 +102,7 @@ public class UnifyTypeFactory { } public static UnifyType convert(GenericTypeVar t){ - return new SimpleType(t.get_Name()); + return new ReferenceType(t.get_Name()); } public static UnifyConstraintsSet convert(ConstraintsSet constraints) { @@ -146,7 +146,7 @@ public class UnifyTypeFactory { return new Pair(tl, tr, mp.getPairOp()); } - public static Type convert(SimpleType t) { + public static Type convert(ReferenceType t) { return new RefType(t.getName(),null,0); } @@ -165,7 +165,7 @@ public class UnifyTypeFactory { } public static Type convert(UnifyType t) { - if(t instanceof SimpleType)return convert((SimpleType) t); + if(t instanceof ReferenceType)return convert((ReferenceType) t); if(t instanceof SuperType)return convert((SuperType) t); if(t instanceof ExtendsType)return convert((ExtendsType) t); if(t instanceof PlaceholderType)return convert((PlaceholderType) t); diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index 30150cd3..d0710675 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import java.util.Optional; import java.util.Queue; import java.util.Set; @@ -18,9 +17,10 @@ import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.SimpleType; +import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; +import de.dhbwstuttgart.typeinference.unify.model.WildcardType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.Unifier; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; @@ -43,7 +43,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) + if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType)) return Optional.empty(); return Optional.of(new MPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT)); @@ -59,7 +59,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType rhsType = pair.getRhsType(); - if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) + if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType)) return Optional.empty(); return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT)); @@ -89,7 +89,7 @@ public class RuleSet implements IRuleSet{ UnifyType x = pair.getLhsType(); UnifyType sTypeX; - if(x instanceof SimpleType) + if(x instanceof ReferenceType) sTypeX = x; else if(x instanceof ExtendsType) sTypeX = ((ExtendsType) x).getExtendedType(); @@ -141,7 +141,7 @@ public class RuleSet implements IRuleSet{ UnifyType x = pair.getLhsType(); UnifyType sTypeX; - if(x instanceof SimpleType) + if(x instanceof ReferenceType) sTypeX = x; else if(x instanceof SuperType) sTypeX = ((SuperType) x).getSuperedType(); @@ -221,15 +221,15 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType c = pair.getLhsType(); - if(!(c instanceof SimpleType)) + if(!(c instanceof ReferenceType)) return Optional.empty(); UnifyType d = pair.getRhsType(); - if(!(d instanceof SimpleType)) + if(!(d instanceof ReferenceType)) return Optional.empty(); - SimpleType lhsSType = (SimpleType) c; - SimpleType rhsSType = (SimpleType) d; + ReferenceType lhsSType = (ReferenceType) c; + ReferenceType rhsSType = (ReferenceType) d; if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) return Optional.empty(); @@ -265,14 +265,17 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType lhsType = pair.getLhsType(); - SimpleType lhsSType; + ReferenceType lhsSType; - if(lhsType instanceof SimpleType) - lhsSType = (SimpleType) lhsType; - else if(lhsType instanceof ExtendsType) - lhsSType = (SimpleType) ((ExtendsType) lhsType).getExtendedType(); - else if(lhsType instanceof SuperType) - lhsSType = (SimpleType) ((SuperType) lhsType).getSuperedType(); + if(lhsType instanceof ReferenceType) + lhsSType = (ReferenceType) lhsType; + else if(lhsType instanceof WildcardType) { + UnifyType lhsSTypeRaw = ((WildcardType) lhsType).getWildcardedType(); + if(lhsSTypeRaw instanceof ReferenceType) + lhsSType = (ReferenceType) lhsSTypeRaw; + else + return Optional.empty(); + } else return Optional.empty(); @@ -280,14 +283,17 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType rhsType = pair.getLhsType(); - SimpleType rhsSType; + ReferenceType rhsSType; - if(rhsType instanceof SimpleType) - rhsSType = (SimpleType) rhsType; - else if(rhsType instanceof ExtendsType) - rhsSType = (SimpleType) ((ExtendsType) rhsType).getExtendedType(); - else if(rhsType instanceof SuperType) - rhsSType = (SimpleType) ((SuperType) rhsType).getSuperedType(); + if(rhsType instanceof ReferenceType) + rhsSType = (ReferenceType) rhsType; + else if(rhsType instanceof WildcardType) { + UnifyType rhsSTypeRaw = ((WildcardType) rhsType).getWildcardedType(); + if(rhsSTypeRaw instanceof ReferenceType) + rhsSType = (ReferenceType) rhsSTypeRaw; + else + return Optional.empty(); + } else return Optional.empty(); @@ -314,11 +320,11 @@ public class RuleSet implements IRuleSet{ return false; UnifyType lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) + if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType)) return false; UnifyType rhsType = pair.getRhsType(); - if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) + if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType)) return false; return finiteClosure.greater(lhsType).contains(rhsType); @@ -363,11 +369,11 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType typeD = pair.getLhsType(); - if(!(typeD instanceof SimpleType)) + if(!(typeD instanceof ReferenceType)) return Optional.empty(); UnifyType typeDs = pair.getRhsType(); - if(!(typeDs instanceof SimpleType)) + if(!(typeDs instanceof ReferenceType)) return Optional.empty(); if(typeD.getTypeParams().size() == 0 || typeDs.getTypeParams().size() == 0) @@ -409,7 +415,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType typeD = pair.getLhsType(); - if(!(typeD instanceof SimpleType) && !(typeD instanceof ExtendsType)) + if(!(typeD instanceof ReferenceType) && !(typeD instanceof ExtendsType)) return Optional.empty(); UnifyType typeExtDs = pair.getRhsType(); @@ -420,7 +426,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType typeDgen; - if(typeD instanceof SimpleType) + if(typeD instanceof ReferenceType) typeDgen = finiteClosure.getLeftHandedType(typeD).orElse(null); else { Optional opt = finiteClosure.getLeftHandedType(((ExtendsType) typeD).getExtendedType()); @@ -455,7 +461,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType typeDs = pair.getLhsType(); - if(!(typeDs instanceof SimpleType) && !(typeDs instanceof SuperType)) + if(!(typeDs instanceof ReferenceType) && !(typeDs instanceof SuperType)) return Optional.empty(); UnifyType typeSupD = pair.getRhsType(); @@ -484,7 +490,7 @@ public class RuleSet implements IRuleSet{ // New RHS UnifyType newRhs = null; - if(typeDs instanceof SimpleType) + if(typeDs instanceof ReferenceType) newRhs = new ExtendsType(typeDs); else newRhs = new ExtendsType(((SuperType) typeDs).getSuperedType()); @@ -600,7 +606,7 @@ public class RuleSet implements IRuleSet{ UnifyType lhsType = pair.getLhsType(); UnifyType rhsType = pair.getRhsType(); - if(!(lhsType instanceof SimpleType) || !(rhsType instanceof ExtendsType)) + if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType)) return Optional.empty(); return Optional.of(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); @@ -626,7 +632,7 @@ public class RuleSet implements IRuleSet{ UnifyType lhsType = pair.getLhsType(); UnifyType rhsType = pair.getRhsType(); - if(!(lhsType instanceof SimpleType) || !(rhsType instanceof SuperType)) + if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType)) return Optional.empty(); return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC)); @@ -664,16 +670,13 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); UnifyType rhsType = pair.getRhsType(); - if(!(rhsType instanceof SimpleType)) + if(!(rhsType instanceof ReferenceType)) return Optional.empty(); UnifyType lhsType = pair.getLhsType(); - if(lhsType instanceof SuperType) - return Optional.of(new MPair(((SuperType) lhsType).getSuperedType(), rhsType, PairOperator.EQUALSDOT)); - - if(lhsType instanceof ExtendsType) - return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.EQUALSDOT)); + if(lhsType instanceof WildcardType) + return Optional.of(new MPair(((WildcardType) lhsType).getWildcardedType(), rhsType, PairOperator.EQUALSDOT)); return Optional.empty(); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index b4fb7bb9..d781a2a4 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -73,11 +73,18 @@ public class Unify { Set> wrap = new HashSet<>(); wrap.add(bufferSet); topLevelSets.add(wrap); + eq2s.removeAll(bufferSet); } // Sets that originate from pair pattern matching // Sets of the "second level" - Set>>> secondLevelSets = calculatePairSets(eq2s, fc); + Set undefinedPairs = new HashSet<>(); + Set>>> secondLevelSets = calculatePairSets(eq2s, fc, undefinedPairs); + + // If pairs occured that did not match one of the cartesian product cases, + // those pairs are contradictory and the unification is impossible. + if(!undefinedPairs.isEmpty()) + return new HashSet<>(); /* Up to here, no cartesian products are calculated. * filters for pairs and sets can be applied here */ @@ -104,9 +111,6 @@ public class Unify { * Step 5: Substitution */ - /* - * TODO hier das ergebnis schonh flach machen? (wird im unify old (glaub ich) so gemacht) - */ Set> eqPrimeSetFlat = new HashSet<>(); for(Set> setToFlatten : eqPrimeSet) { Set buffer = new HashSet<>(); @@ -121,10 +125,16 @@ public class Unify { for(Set eqPrime : eqPrimeSetFlat) { Optional> eqPrimePrime = rules.subst(eqPrime); - if(eqPrimePrime.isPresent()) + if(eqPrime.equals(eq)) + eqPrimePrimeSet.add(eqPrime); + else if(eqPrimePrime.isPresent()) + eqPrimePrimeSet.addAll(this.unify(eqPrimePrime.get(), fc)); + else + eqPrimePrimeSet.addAll(this.unify(eqPrime, fc)); + /*if(eqPrimePrime.isPresent()) changed.add(eqPrimePrime.get()); else - eqPrimePrimeSet.add(eqPrime); + eqPrimePrimeSet.add(eqPrime);*/ } /* @@ -255,9 +265,9 @@ public class Unify { } - protected Set>>> calculatePairSets(Set eq2s, IFiniteClosure fc) { + protected Set>>> calculatePairSets(Set eq2s, IFiniteClosure fc, Set undefined) { List>>> result = new ArrayList<>(); - + // Init all 8 cases for(int i = 0; i < 8; i++) result.add(new HashSet<>()); @@ -299,6 +309,12 @@ public class Unify { // Case 8: (Theta <.? a) else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType) result.get(7).add(unifyCase8(lhsType, (PlaceholderType) rhsType, fc)); + // Case unknown: If a pair fits no other case, then the type unification has failed. + // Through application of the rules, every pair should have one of the above forms. + // Pairs that do not have one of the aboves form are contradictory. + else + undefined.add(pair); + } return result.stream().map(x -> x.stream().filter(y -> y.size() > 0).collect(Collectors.toCollection(HashSet::new))) @@ -415,17 +431,18 @@ public class Unify { UnifyType aPrime = PlaceholderType.freshPlaceholder(); UnifyType supAPrime = new SuperType(aPrime); - for(UnifyType theta : fc.smArg(subThetaPrime)) { + UnifyType thetaPrime = subThetaPrime.getSuperedType(); + //for(UnifyType theta : fc.smArg(subThetaPrime)) { Set resultPrime = new HashSet<>(); resultPrime.add(new MPair(a, aPrime, PairOperator.EQUALSDOT)); - resultPrime.add(new MPair(aPrime,theta, PairOperator.SMALLERDOT)); + resultPrime.add(new MPair(thetaPrime, aPrime, PairOperator.SMALLERDOT)); result.add(resultPrime); resultPrime = new HashSet<>(); resultPrime.add(new MPair(a, supAPrime, PairOperator.EQUALSDOT)); - resultPrime.add(new MPair(supAPrime,theta, PairOperator.SMALLERDOT)); + resultPrime.add(new MPair(thetaPrime, aPrime, PairOperator.SMALLERDOT)); result.add(resultPrime); - } + //} return result; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 06e12a36..bd15999a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -6,7 +6,7 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.SimpleType; +import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; @@ -38,8 +38,8 @@ public interface IFiniteClosure { */ public Set smArg(UnifyType type); - public Set grArg(SimpleType type); - public Set smArg(SimpleType type); + public Set grArg(ReferenceType type); + public Set smArg(ReferenceType type); public Set grArg(ExtendsType type); public Set smArg(ExtendsType type); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java index f4a79794..847abfd5 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java @@ -7,38 +7,28 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; /** * An extends wildcard type "? extends T". */ -public final class ExtendsType extends UnifyType { - - /** - * The extended type - */ - private UnifyType extendedType; +public final class ExtendsType extends WildcardType { /** * Creates a new extends wildcard type. * @param extendedType The extended type e.g. Integer in "? extends Integer" */ public ExtendsType(UnifyType extendedType) { - super("? extends " + extendedType.getName(), extendedType.getTypeParams()); - this.extendedType = extendedType; + super("? extends " + extendedType.getName(), extendedType, extendedType.getTypeParams()); } - - /** - * Gets the type extended by this wildcard e.g. "Integer" for "? extends Integer" - * @return The extended type. - */ + public UnifyType getExtendedType() { - return extendedType; + return wildcardedType; } @Override public TypeParams getTypeParams() { - return extendedType.getTypeParams(); + return wildcardedType.getTypeParams(); } @Override public UnifyType setTypeParams(TypeParams newTp) { - return new ExtendsType(extendedType.setTypeParams(newTp)); + return new ExtendsType(wildcardedType.setTypeParams(newTp)); } @Override @@ -53,12 +43,16 @@ public final class ExtendsType extends UnifyType { @Override UnifyType apply(Unifier unif) { - return new ExtendsType(extendedType.apply(unif)); + return new ExtendsType(wildcardedType.apply(unif)); } @Override public int hashCode() { - return extendedType.hashCode() + 17; + /* + * It is important that the prime that is added is different to the prime added in hashCode() of SuperType. + * Otherwise ? extends T and ? super T have the same hashCode() for every Type T. + */ + return wildcardedType.hashCode() + 229; } @Override @@ -67,12 +61,12 @@ public final class ExtendsType extends UnifyType { return false; ExtendsType other = (ExtendsType) obj; - return other.getExtendedType().equals(extendedType); + return other.getWildcardedType().equals(wildcardedType); } @Override public String toString() { - return "? extends " + extendedType; + return "? extends " + wildcardedType; } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index a4c5a51d..5ef8c93a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -214,7 +214,7 @@ public class FiniteClosure implements IFiniteClosure { } @Override - public Set grArg(SimpleType type) { + public Set grArg(ReferenceType type) { Set result = new HashSet(); result.add(type); @@ -268,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure { } @Override - public Set smArg(SimpleType type) { + public Set smArg(ReferenceType type) { Set result = new HashSet(); result.add(type); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index aa401b8a..f45a4a13 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -13,9 +13,18 @@ public final class PlaceholderType extends UnifyType{ protected static String nextName = "gen_"; protected static Random rnd = new Random(43558747548978L); + private final boolean IsGenerated; + public PlaceholderType(String name) { super(name); EXISTING_PLACEHOLDERS.add(name); + IsGenerated = false; + } + + protected PlaceholderType(String name, boolean isGenerated) { + super(name); + EXISTING_PLACEHOLDERS.add(name); + IsGenerated = isGenerated; } public static PlaceholderType freshPlaceholder() { @@ -24,7 +33,7 @@ public final class PlaceholderType extends UnifyType{ while(EXISTING_PLACEHOLDERS.contains(name)); nextName += randomChar(); - return new PlaceholderType(name); + return new PlaceholderType(name, true); } /** @@ -33,6 +42,10 @@ public final class PlaceholderType extends UnifyType{ private static char randomChar() { return (char) (rnd.nextInt(22) + 97); } + + public boolean isGenerated() { + return IsGenerated; + } @Override Set smArg(IFiniteClosure fc) { diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java similarity index 64% rename from src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java rename to src/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java index 62d3ca1c..fd5a0ec1 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java @@ -4,12 +4,12 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public final class SimpleType extends UnifyType { - public SimpleType(String name, UnifyType... typeParams) { +public final class ReferenceType extends UnifyType { + public ReferenceType(String name, UnifyType... typeParams) { super(name, new TypeParams(typeParams)); } - public SimpleType(String name, TypeParams params) { + public ReferenceType(String name, TypeParams params) { super(name, params); } @@ -25,12 +25,12 @@ public final class SimpleType extends UnifyType { @Override UnifyType apply(Unifier unif) { - return new SimpleType(typeName, typeParams.apply(unif)); + return new ReferenceType(typeName, typeParams.apply(unif)); } @Override public UnifyType setTypeParams(TypeParams newTp) { - return new SimpleType(new String(typeName), newTp); + return new ReferenceType(new String(typeName), newTp); } @Override @@ -40,10 +40,10 @@ public final class SimpleType extends UnifyType { @Override public boolean equals(Object obj) { - if(!(obj instanceof SimpleType)) + if(!(obj instanceof ReferenceType)) return false; - SimpleType other = (SimpleType) obj; + ReferenceType other = (ReferenceType) obj; if(!other.getName().equals(typeName)) return false; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java index 48ed2891..51f640c9 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java @@ -4,32 +4,30 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public final class SuperType extends UnifyType { - - private UnifyType superedType; +public final class SuperType extends WildcardType { + public SuperType(UnifyType superedType) { - super("? super " + superedType.getName(), superedType.getTypeParams()); - this.superedType = superedType; + super("? super " + superedType.getName(), superedType, superedType.getTypeParams()); } public UnifyType getSuperedType() { - return superedType; + return wildcardedType; } @Override public String toString() { - return "? super " + superedType; + return "? super " + wildcardedType; } @Override public TypeParams getTypeParams() { - return superedType.getTypeParams(); + return wildcardedType.getTypeParams(); } @Override public UnifyType setTypeParams(TypeParams newTp) { - return new SuperType(superedType.setTypeParams(newTp)); + return new SuperType(wildcardedType.setTypeParams(newTp)); } @Override @@ -44,12 +42,16 @@ public final class SuperType extends UnifyType { @Override UnifyType apply(Unifier unif) { - return new SuperType(superedType.apply(unif)); + return new SuperType(wildcardedType.apply(unif)); } @Override public int hashCode() { - return superedType.hashCode() + 17; + /* + * It is important that the prime that is added is different to the prime added in hashCode() of ExtendsType. + * Otherwise ? extends T and ? super T have the same hashCode() for every Type T. + */ + return wildcardedType.hashCode() + 3917; } @Override @@ -58,7 +60,6 @@ public final class SuperType extends UnifyType { return false; SuperType other = (SuperType) obj; - return other.getSuperedType().equals(superedType); + return other.getSuperedType().equals(wildcardedType); } - } diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 0ae1d49c..dad10d5d 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -12,7 +12,7 @@ import de.dhbwstuttgart.typeinference.unify.RuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; 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.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; @@ -139,15 +139,15 @@ public class RuleSetTest { */ // C - SimpleType c1 = tf.getSimpleType("C", "T1", "T2", "T3", "T4"); + ReferenceType c1 = tf.getSimpleType("C", "T1", "T2", "T3", "T4"); // D - SimpleType d1 = tf.getSimpleType("D", "T4", "T1", "T2", "T3"); - SimpleType buffer = tf.getSimpleType("Buffer"); + ReferenceType d1 = tf.getSimpleType("D", "T4", "T1", "T2", "T3"); + ReferenceType buffer = tf.getSimpleType("Buffer"); //C - SimpleType c2 = tf.getSimpleType("C", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + ReferenceType c2 = tf.getSimpleType("C", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); //D, Number, Double, N> - SimpleType d2 = tf.getSimpleType("D", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N")); + ReferenceType d2 = tf.getSimpleType("D", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N")); // C<...> < buffer < D<...> fcb.add(c1, buffer); @@ -195,9 +195,9 @@ public class RuleSetTest { System.out.println("----- Reduce2 ------"); // C - SimpleType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); + ReferenceType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); // C - SimpleType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + ReferenceType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); MPair pair1 = new MPair(c1, c2, PairOperator.EQUALSDOT); MPair pair2 = new MPair(tf.getExtendsType(c1), tf.getExtendsType(c2), PairOperator.EQUALSDOT); @@ -217,7 +217,7 @@ public class RuleSetTest { * Negative Tests */ - SimpleType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + ReferenceType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); pair1 = new MPair(d1, c1, PairOperator.EQUALSDOT); // Case 1: D =. C pair2 = new MPair(tf.getExtendsType(c1), c2, PairOperator.EQUALSDOT); // Case 2: ? extends C =. C pair3 = new MPair(tf.getExtendsType(c1), tf.getSuperType(c2), PairOperator.EQUALSDOT); // Case 3: ? extends C =. ? super C @@ -239,13 +239,13 @@ public class RuleSetTest { */ // X - SimpleType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); + ReferenceType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); // Y - SimpleType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); - SimpleType buffer = tf.getSimpleType("Buffer"); + ReferenceType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); + ReferenceType buffer = tf.getSimpleType("Buffer"); //X - SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + ReferenceType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); //? extends Y, Number, Double, N> ExtendsType extY1 = tf.getExtendsType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); @@ -301,13 +301,13 @@ public class RuleSetTest { */ // X - SimpleType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); + ReferenceType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); // Y - SimpleType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); - SimpleType buffer = tf.getSimpleType("Buffer"); + ReferenceType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); + ReferenceType buffer = tf.getSimpleType("Buffer"); //X - SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + ReferenceType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); //? super Y, Number, Double, N> SuperType supY1 = tf.getSuperType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); @@ -365,9 +365,9 @@ public class RuleSetTest { System.out.println("----- ReduceEq ------"); // C - SimpleType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); + ReferenceType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); // C - SimpleType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + ReferenceType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); MPair pair = new MPair(c1, c2, PairOperator.SMALLERDOTWC); Optional> res = rules.reduceEq(pair); @@ -378,7 +378,7 @@ public class RuleSetTest { */ // Case 1: D <.? C - SimpleType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + ReferenceType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); pair = new MPair(d1, c1, PairOperator.SMALLERDOTWC); Assert.assertFalse(rules.reduceEq(pair).isPresent()); @@ -521,9 +521,9 @@ public class RuleSetTest { TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); - SimpleType t2 = tf.getSimpleType("Type2", "T"); - SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + ReferenceType t1 = tf.getSimpleType("Type1", "T", "U"); + ReferenceType t2 = tf.getSimpleType("Type2", "T"); + ReferenceType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); fcb.add(t1, t2); fcb.add(t2, t3); @@ -534,9 +534,9 @@ public class RuleSetTest { * Positive Tests */ - SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); - SimpleType c2 = tf.getSimpleType("Type2", "Object"); - SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + ReferenceType c1 = tf.getSimpleType("Type1", "String", "Double"); + ReferenceType c2 = tf.getSimpleType("Type2", "Object"); + ReferenceType c3 = tf.getSimpleType("Type3", "Object", "Number"); MPair pair1 = new MPair(c1, c2, PairOperator.SMALLERDOT); MPair pair2 = new MPair(c2, c3, PairOperator.SMALLERDOT); @@ -565,11 +565,11 @@ public class RuleSetTest { TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); - SimpleType t2 = tf.getSimpleType("Type2", "T"); - SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); - SimpleType t32 = tf.getSimpleType("Type3", "T", "U"); - SimpleType t4 = tf.getSimpleType("Object"); + ReferenceType t1 = tf.getSimpleType("Type1", "T", "U"); + ReferenceType t2 = tf.getSimpleType("Type2", "T"); + ReferenceType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + ReferenceType t32 = tf.getSimpleType("Type3", "T", "U"); + ReferenceType t4 = tf.getSimpleType("Object"); fcb.add(t1, t2); fcb.add(t2, t3); @@ -581,9 +581,9 @@ public class RuleSetTest { * Positive Tests */ - SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); - SimpleType c2 = tf.getSimpleType("Type2", "Object"); - SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + ReferenceType c1 = tf.getSimpleType("Type1", "String", "Double"); + ReferenceType c2 = tf.getSimpleType("Type2", "Object"); + ReferenceType c3 = tf.getSimpleType("Type3", "Object", "Number"); ExtendsType extc1 = new ExtendsType(c1); ExtendsType extc2 = new ExtendsType(c2); ExtendsType extc3 = new ExtendsType(c3); @@ -627,11 +627,11 @@ public class RuleSetTest { TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); - SimpleType t2 = tf.getSimpleType("Type2", "T"); - SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); - SimpleType t32 = tf.getSimpleType("Type3", "T", "U"); - SimpleType t4 = tf.getSimpleType("Object"); + ReferenceType t1 = tf.getSimpleType("Type1", "T", "U"); + ReferenceType t2 = tf.getSimpleType("Type2", "T"); + ReferenceType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + ReferenceType t32 = tf.getSimpleType("Type3", "T", "U"); + ReferenceType t4 = tf.getSimpleType("Object"); fcb.add(t1, t2); fcb.add(t2, t3); @@ -643,9 +643,9 @@ public class RuleSetTest { * Positive Tests */ - SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); - SimpleType c2 = tf.getSimpleType("Type2", "Object"); - SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + ReferenceType c1 = tf.getSimpleType("Type1", "String", "Double"); + ReferenceType c2 = tf.getSimpleType("Type2", "Object"); + ReferenceType c3 = tf.getSimpleType("Type3", "Object", "Number"); SuperType supc1 = new SuperType(c1); SuperType supc2 = new SuperType(c2); SuperType supc3 = new SuperType(c3); diff --git a/test/unify/StandardUnifyTest.java b/test/unify/StandardUnifyTest.java index ac6e5c0c..b8e8a479 100644 --- a/test/unify/StandardUnifyTest.java +++ b/test/unify/StandardUnifyTest.java @@ -11,7 +11,6 @@ import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; -import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; public class StandardUnifyTest { diff --git a/test/unify/TypeFactory.java b/test/unify/TypeFactory.java index 965e324d..099638e7 100644 --- a/test/unify/TypeFactory.java +++ b/test/unify/TypeFactory.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.SimpleType; +import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; @@ -19,16 +19,16 @@ public class TypeFactory { return new SuperType(superedType); } - public SimpleType getSimpleType(String name) { - return new SimpleType(name); + public ReferenceType getSimpleType(String name) { + return new ReferenceType(name); } - public SimpleType getSimpleType(String name, UnifyType... typeParams) { - return new SimpleType(name, typeParams); + public ReferenceType getSimpleType(String name, UnifyType... typeParams) { + return new ReferenceType(name, typeParams); } - public SimpleType getSimpleType(String name, String... typeParams) { - return new SimpleType(name, Arrays.stream(typeParams).map(x -> getPlaceholderType(x)).collect(Collectors.toList()).toArray(new UnifyType[0])); + public ReferenceType getSimpleType(String name, String... typeParams) { + return new ReferenceType(name, Arrays.stream(typeParams).map(x -> getPlaceholderType(x)).collect(Collectors.toList()).toArray(new UnifyType[0])); } public PlaceholderType getPlaceholderType(String name) { diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index d5172970..3e3e51d1 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -12,6 +12,7 @@ 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.PairOperator; +import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import junit.framework.Assert; @@ -128,6 +129,7 @@ public class UnifyTest extends Unify { addAsSet(expected, new MPair(tphA, supObject, PairOperator.EQUALSDOT)); actual = unify(eq, fc); + actual = filterGeneratedTPHsMultiple(actual); Assert.assertEquals(expected, actual); @@ -208,10 +210,11 @@ public class UnifyTest extends Unify { eq.add(new MPair(integer, number, PairOperator.SMALLERDOT)); expected = new HashSet<>(); + expected.add(new HashSet<>()); actual = unify(eq, fc); - //Assert.assertEquals(expected, actual); + Assert.assertEquals(expected, actual); /* * Test 9: @@ -226,7 +229,7 @@ public class UnifyTest extends Unify { actual = unify(eq, fc); - //Assert.assertEquals(expected, actual); + Assert.assertEquals(expected, actual); /* * Test 10: @@ -260,7 +263,22 @@ public class UnifyTest extends Unify { actual = unify(eq, fc); Assert.assertEquals(expected, actual); - + + /* + * Test 11: + * + * (a <.? ? super b) + */ + + eq = new HashSet<>(); + eq.add(new MPair(tphA, tf.getSuperType(tphB), PairOperator.SMALLERDOTWC)); + + expected = new HashSet<>(); + addAsSet(expected, new MPair(tphA, tf.getSuperType(tphB), PairOperator.SMALLERDOTWC)); + + actual = unify(eq, fc); + + System.out.println(actual); } @Test @@ -320,8 +338,8 @@ public class UnifyTest extends Unify { actual = unify(eq, fc); - System.out.println(actual); - //Assert.assertEquals(expected, actual); + //System.out.println(actual); + Assert.assertEquals(expected, actual); /* @@ -425,6 +443,14 @@ public class UnifyTest extends Unify { System.out.println(result); } + private Set> filterGeneratedTPHsMultiple(Set> set) { + return set.stream().map(x -> filterGeneratedTPHs(x)).collect(Collectors.toSet()); + } + + private Set filterGeneratedTPHs(Set set) { + return set.stream().filter(x -> !((x.getRhsType() instanceof PlaceholderType) && ((PlaceholderType) x.getRhsType()).isGenerated())). + filter(x -> !((x.getLhsType() instanceof PlaceholderType) && ((PlaceholderType) x.getLhsType()).isGenerated())).collect(Collectors.toSet()); + } private void addAsSet(Set> addTo, MPair... mPairs) { addTo.add(new HashSet<>(Arrays.stream(mPairs).collect(Collectors.toSet()))); diff --git a/test/unify/UnifyTypeFactoryTest.java b/test/unify/UnifyTypeFactoryTest.java index 15d6f5f5..8bfac1a9 100644 --- a/test/unify/UnifyTypeFactoryTest.java +++ b/test/unify/UnifyTypeFactoryTest.java @@ -23,7 +23,7 @@ import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.UnifyConstraintsSet; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; -import de.dhbwstuttgart.typeinference.unify.model.SimpleType; +import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; @@ -60,8 +60,8 @@ public class UnifyTypeFactoryTest { MPair mp4 = new MPair(tf.getPlaceholderType(tph2.getName().toString()), tf.getPlaceholderType(tph1.getName().toString()), PairOperator.SMALLERDOT); checkConvertMPair(mp4); - SimpleType typeWithParams = tf.getSimpleType("Test", getSimpleType()); - SimpleType typeWithTPHParams = tf.getSimpleType("Test", tf.getPlaceholderType("Test")); + ReferenceType typeWithParams = tf.getSimpleType("Test", getSimpleType()); + ReferenceType typeWithTPHParams = tf.getSimpleType("Test", tf.getPlaceholderType("Test")); MPair mp5 = new MPair(typeWithTPHParams, typeWithParams, PairOperator.SMALLERDOT); checkConvertMPair(mp5); } @@ -130,7 +130,7 @@ public class UnifyTypeFactoryTest { return p; } - private static SimpleType getSimpleType(){ + private static ReferenceType getSimpleType(){ return tf.getSimpleType("String"); }