diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index d2c6f0f4..87693e4d 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -55,6 +55,6 @@ public interface IFiniteClosure { public Optional getLeftHandedType(Type t); public Set getAncestors(Type t); - + public Set getChildren(Type 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 9e1b8808..a36b93d2 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -94,7 +94,7 @@ 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(Type typePrime : result1) { for (Type theta2 : candidates) { Optional sigma2 = unify.unify(typePrime, theta2); @@ -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(Type 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(Type 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, Type[] current) { diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index aa966e5b..fde25609 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -587,7 +587,7 @@ public class RuleSet implements IRuleSet{ Type lhsType = pair.getLhsType(); Type 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)); @@ -613,10 +613,10 @@ public class RuleSet implements IRuleSet{ Type lhsType = pair.getLhsType(); Type 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 @@ -651,7 +651,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type rhsType = pair.getRhsType(); - if((rhsType instanceof SuperType) || (rhsType instanceof ExtendsType)) + if(!(rhsType instanceof SimpleType)) return Optional.empty(); Type lhsType = pair.getLhsType(); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 6e6fe376..26a74729 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -138,9 +138,9 @@ public class Unify { } /* - * Step 7: Filter result for solved pairs + * Step 7: Filter empty sets; */ - return eqPrimePrimeSet; + return eqPrimePrimeSet.stream().filter(x -> !x.isEmpty()).collect(Collectors.toCollection(HashSet::new)); } @@ -300,7 +300,7 @@ public class Unify { for(Type 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)); + Set thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); thetaQs.add(c); // reflexive Set thetaQPrimes = new HashSet<>(); @@ -347,7 +347,7 @@ public class Unify { for(Type 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)); + Set thetaQs = fc.getChildren(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); thetaQs.add(c); // reflexive Set thetaQPrimes = new HashSet<>(); @@ -422,7 +422,7 @@ public class Unify { for(Type 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)); + 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/UnifyTest.java b/test/unify/UnifyTest.java index ae219dd2..2d2faad8 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -1,8 +1,11 @@ package unify; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; import org.junit.Test; @@ -13,39 +16,237 @@ import de.dhbwstuttgart.typeinference.unify.model.Type; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unifynew.TypeFactory; import de.dhbwstuttgart.typeinference.unifynew.Unify; +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")); + + Type number = tf.getSimpleType("Number"); + Type object = tf.getSimpleType("Object"); + Type integer = tf.getSimpleType("Integer"); + Type 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) + */ + + Type 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) + */ + + Type supInteger = tf.getSuperType(integer); + Type supNumber = tf.getSuperType(number); + Type 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<>(); + Type extNumber = tf.getExtendsType(number); + Type extObject = tf.getExtendsType(object); + Type 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) + */ + + Type 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() { + + } + + @Test + public void unifyTestComplex() { } @@ -83,7 +284,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()))); + } }