From 6778160315d001ddeee4bd3c00cccf6a2d7bbf8e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 13 Mar 2016 23:01:28 +0100 Subject: [PATCH] various --- .../unify/interfaces/IRuleSet.java | 1 - .../unify/interfaces/IUnify.java | 2 +- .../unify/model/ExtendsType.java | 36 +++++++++++++------ .../unify/model/PlaceholderType.java | 19 +++++----- .../typeinference/unify/model/SimpleType.java | 15 ++++---- .../typeinference/unify/model/SuperType.java | 15 ++++---- .../typeinference/unify/model/Type.java | 7 ++-- .../typeinference/unify/model/TypeParams.java | 16 +++++++-- .../{unifynew => unify/model}/Unifier.java | 6 +--- .../unifynew/MartelliMontanariUnify.java | 1 + .../typeinference/unifynew/RuleSet.java | 30 +++++++--------- .../typeinference/unifynew/Unify.java | 20 +++++++---- test/unify/FiniteClosureTest.java | 7 ++++ test/unify/UnifyTest.java | 3 +- 14 files changed, 103 insertions(+), 75 deletions(-) rename src/de/dhbwstuttgart/typeinference/{unifynew => unify/model}/Unifier.java (80%) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index d2a95f3d..840d7259 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -4,7 +4,6 @@ import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.model.MPair; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; public interface IRuleSet { diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java index a573b5d2..f286e3b6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java @@ -6,7 +6,7 @@ import java.util.Set; import java.util.stream.Collectors; import de.dhbwstuttgart.typeinference.unify.model.Type; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; +import de.dhbwstuttgart.typeinference.unify.model.Unifier; /** * Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java index 4eceb240..da59af1a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java @@ -3,16 +3,30 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; +/** + * An extends wildcard type "? extends T". + */ public final class ExtendsType extends Type { + + /** + * The extended type + */ private Type extendedType; + /** + * Creates a new extends wildcard type. + * @param extendedType The extended type e.g. Integer in "? extends Integer" + */ public ExtendsType(Type extendedType) { super("? extends " + extendedType.getName(), extendedType.getTypeParams()); this.extendedType = extendedType; } + /** + * Gets the type extended by this wildcard e.g. "Integer" for "? extends Integer" + * @return The extended type. + */ public Type getExtendedType() { return extendedType; } @@ -21,21 +35,21 @@ public final class ExtendsType extends Type { public TypeParams getTypeParams() { return extendedType.getTypeParams(); } - - @Override - public String toString() { - return "? extends " + extendedType; - } @Override - public Set smArg(IFiniteClosure fc) { + Set smArg(IFiniteClosure fc) { return fc.smArg(this); } @Override - public Set grArg(IFiniteClosure fc) { + Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + + @Override + Type apply(Unifier unif) { + return new ExtendsType(extendedType.apply(unif)); + } @Override public int hashCode() { @@ -50,9 +64,9 @@ public final class ExtendsType extends Type { ExtendsType other = (ExtendsType) obj; return other.getExtendedType().equals(extendedType); } - + @Override - public Type apply(Unifier unif) { - return new ExtendsType(extendedType.apply(unif)); + public String toString() { + return "? extends " + extendedType; } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index 0514517d..e1f1697a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class PlaceholderType extends Type{ @@ -12,12 +11,12 @@ public final class PlaceholderType extends Type{ } @Override - public Set smArg(IFiniteClosure fc) { + Set smArg(IFiniteClosure fc) { return fc.smArg(this); } @Override - public Set grArg(IFiniteClosure fc) { + Set grArg(IFiniteClosure fc) { return fc.grArg(this); } @@ -26,6 +25,13 @@ public final class PlaceholderType extends Type{ return typeName.hashCode(); } + @Override + Type apply(Unifier unif) { + if(unif.hasSubstitute(this)) + return unif.getSubstitute(this); + return this; + } + @Override public boolean equals(Object obj) { if(!(obj instanceof PlaceholderType)) @@ -33,11 +39,4 @@ public final class PlaceholderType extends Type{ return ((PlaceholderType) obj).getName().equals(typeName); } - - @Override - public Type apply(Unifier unif) { - if(unif.hasSubstitute(this)) - return unif.getSubstitute(this); - return this; - } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java index 27581016..1283ceb6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/SimpleType.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class SimpleType extends Type { public SimpleType(String name, Type... typeParams) { @@ -15,15 +14,20 @@ public final class SimpleType extends Type { } @Override - public Set smArg(IFiniteClosure fc) { + Set smArg(IFiniteClosure fc) { return fc.smArg(this); } @Override - public Set grArg(IFiniteClosure fc) { + Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + @Override + Type apply(Unifier unif) { + return new SimpleType(typeName, typeParams.apply(unif)); + } + @Override public int hashCode() { return typeName.hashCode(); @@ -41,9 +45,4 @@ public final class SimpleType extends Type { return other.getTypeParams().equals(typeParams); } - - @Override - public Type apply(Unifier unif) { - return new SimpleType(typeName, typeParams.apply(unif)); - } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java index 5cc8ad63..7090d86a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/SuperType.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class SuperType extends Type { @@ -29,15 +28,20 @@ public final class SuperType extends Type { } @Override - public Set smArg(IFiniteClosure fc) { + Set smArg(IFiniteClosure fc) { return fc.smArg(this); } @Override - public Set grArg(IFiniteClosure fc) { + Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + @Override + Type apply(Unifier unif) { + return new SuperType(superedType.apply(unif)); + } + @Override public int hashCode() { return superedType.hashCode() + 17; @@ -51,9 +55,4 @@ public final class SuperType extends Type { SuperType other = (SuperType) obj; return other.getSuperedType().equals(superedType); } - - @Override - public Type apply(Unifier unif) { - return new SuperType(superedType.apply(unif)); - } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Type.java b/src/de/dhbwstuttgart/typeinference/unify/model/Type.java index 137541e6..52977fbf 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Type.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; public abstract class Type { @@ -28,11 +27,11 @@ public abstract class Type { return typeParams; } - public abstract Set smArg(IFiniteClosure fc); + abstract Set smArg(IFiniteClosure fc); - public abstract Set grArg(IFiniteClosure fc); + abstract Set grArg(IFiniteClosure fc); - public abstract Type apply(Unifier unif); + abstract Type apply(Unifier unif); @Override public String toString() { diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index 3fdd8679..806a310a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -3,8 +3,6 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Arrays; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.unifynew.Unifier; - public final class TypeParams implements Iterable{ private final Type[] typeParams; @@ -42,6 +40,20 @@ public final class TypeParams implements Iterable{ return new TypeParams(newParams); } + public boolean occurs(PlaceholderType t) { + for(Type p : typeParams) { + if(p instanceof PlaceholderType) { + if(p.equals(t)) + return true; + } else { + if(p.getTypeParams().occurs(t)) + return true; + } + } + + return false; + } + public boolean contains(Type t) { for(Type t1 : typeParams) if(t1.equals(t1)) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java similarity index 80% rename from src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java rename to src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index 8979575d..cb0f52d4 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -1,13 +1,9 @@ -package de.dhbwstuttgart.typeinference.unifynew; +package de.dhbwstuttgart.typeinference.unify.model; import java.util.HashMap; import java.util.Map.Entry; import java.util.function.Function; -import de.dhbwstuttgart.typeinference.unify.model.MPair; -import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.Type; - public class Unifier implements Function { private HashMap substitutions = new HashMap<>(); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java index 101f861a..6c55d0be 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -15,6 +15,7 @@ import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.Type; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; +import de.dhbwstuttgart.typeinference.unify.model.Unifier; /** * Implementation of the Martelli-Montanari unification algorithm. diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 4c14cdaf..e41525f5 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -20,6 +20,7 @@ import de.dhbwstuttgart.typeinference.unify.model.SimpleType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.Type; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; +import de.dhbwstuttgart.typeinference.unify.model.Unifier; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; public class RuleSet implements IRuleSet{ @@ -534,35 +535,28 @@ public class RuleSet implements IRuleSet{ typeMap.put(t2, typeMap.get(t2)+1); } - Queue result = new LinkedList(pairs); + ArrayList result = new ArrayList(pairs); boolean applied = false; for(int i = 0; i < result.size(); i++) { - MPair pair = result.poll(); - Type lhsType; + MPair pair = result.get(i); + PlaceholderType lhsType = null; Type rhsType; - if(pair.getPairOp() == PairOperator.EQUALSDOT - && ((lhsType = pair.getLhsType()) instanceof PlaceholderType) + + if(pair.getPairOp() == PairOperator.EQUALSDOT + && pair.getLhsType() instanceof PlaceholderType) + lhsType = (PlaceholderType) pair.getLhsType(); + if(lhsType != null && !((rhsType = pair.getRhsType()) instanceof PlaceholderType) && typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair. - && !occurs(lhsType, rhsType)) { - Unifier uni = new Unifier((PlaceholderType) lhsType, rhsType); - result = result.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new)); + && !rhsType.getTypeParams().occurs(lhsType)) { + Unifier uni = new Unifier(lhsType, rhsType); + result = result.stream().map(uni::apply).collect(Collectors.toCollection(ArrayList::new)); applied = true; } - result.add(pair); } return applied ? Optional.of(new HashSet<>(result)) : Optional.empty(); } - - private boolean occurs(Type t1, Type t2) { - TypeParams t2Params = t2.getTypeParams(); - for(Type t2Param : t2Params) - if(t1.equals(t2Param) || occurs(t1, t2Param)) - return true; - return false; - } - } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 65193117..6b05338b 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -70,8 +70,8 @@ public class Unify { // Sets that originate from pair pattern matching // Sets of the "second level" - sets.addAll(calculatePairSets(eq2s, fc)); + sets.addAll(calculatePairSets(eq2s, fc)); /* Up to here, no cartesian products are calculated. * Around here, filters for pairs and sets can be applied */ @@ -105,7 +105,7 @@ public class Unify { else unchanged.add(eqss); } - + /* * Step 6 a) Restart for pairs where subst was applied @@ -116,7 +116,7 @@ public class Unify { unchanged.addAll(this.unify(eqss, fc)); /* - * Step 7: Filter result for solved pairs + * Step 7: Filter result for solved pairs TODO wie? */ return unchanged; @@ -228,13 +228,21 @@ public class Unify { IUnify unify = new MartelliMontanariUnify(); Set possibleCs = fc.getAllTypes(rhsType.getName()); + + + + + + /*IUnify unify = new MartelliMontanariUnify(); + + Set possibleCs = fc.getAllTypes(rhsType.getName()); Set possibleThetas = possibleCs.stream() .flatMap(x -> fc.smaller(x).stream()) .collect(Collectors.toCollection(HashSet::new)); Set possibleThetaPrimes = possibleThetas.stream() .flatMap(x -> getAllInstantiations(x, fc).stream()) .collect(Collectors.toCollection(HashSet::new)); - + */ // TODO /*Set unifiers = possibleThetaPrimes.stream() @@ -263,7 +271,7 @@ public class Unify { // Case 2: (a <.? ? ext Theta') else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType){ - // TODO + throw new NotImplementedException(); // TODO } // Case 3: (a <.? ? sup Theta') @@ -299,7 +307,7 @@ public class Unify { // Case 7: (? sup Theta <.? a) else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof SuperType && rhsType instanceof PlaceholderType) { - // TODO + throw new NotImplementedException(); // TODO } // Case 8: (Theta <.? a) diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 04017908..85819ecd 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -7,6 +7,7 @@ import org.junit.Test; 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.Type; public class FiniteClosureTest { @@ -54,4 +55,10 @@ public class FiniteClosureTest { System.out.println("SmArg(? extends List) = " + fc.smArg(tf.getExtendsType(tf.getSimpleType("List", "T")))); System.out.println("SmArg(? super List) = " + fc.smArg(tf.getSuperType(tf.getSimpleType("List", "T")))); } + + @Test + public void testGetGenericType() { + + // TODO + } } diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index eb7f9f5b..be759f6e 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -31,8 +31,9 @@ public class UnifyTest extends Unify { // 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("Integer"), PairOperator.SMALLERDOT)); + //eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("Integer"), 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));