From 5c73224f8f8583c31f5ed6a6b106d8136ca137fb Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 8 Apr 2016 18:04:11 +0200 Subject: [PATCH] support for extended case 1 // tests // bugfix in "big" cases --- .../typeinference/unify/Unify.java | 38 +++--- test/unify/UnifyTest.java | 126 +++++++++++++++--- 2 files changed, 123 insertions(+), 41 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index 6f4fa514..b0e3d7a9 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -327,12 +327,9 @@ public class Unify { Set cs = fc.getAllTypesByName(thetaPrime.getName()); - for(UnifyType c : cs) { - - // 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 - + for(UnifyType c : cs) { + Set thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); + Set thetaQPrimes = new HashSet<>(); TypeParams cParams = c.getTypeParams(); if(cParams.size() == 0) @@ -352,6 +349,7 @@ public class Unify { continue; Unifier unifier = opt.get(); + unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams().toArray()); Set substitutionSet = new HashSet<>(); for (Entry sigma : unifier.getSubstitutions()) substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); @@ -360,7 +358,15 @@ public class Unify { Set smaller = fc.smaller(unifier.apply(tq)); for(UnifyType theta : smaller) { Set resultPrime = new HashSet<>(); - resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT)); + + UnifyType[] freshTphs = new UnifyType[theta.getTypeParams().size()]; + for(int i = 0; i < freshTphs.length; i++) { + freshTphs[i] = PlaceholderType.freshPlaceholder(); + resultPrime.add(new UnifyPair(freshTphs[i], theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC)); + } + + UnifyType freshTheta = theta.setTypeParams(new TypeParams(freshTphs)); + resultPrime.add(new UnifyPair(a, freshTheta, PairOperator.EQUALSDOT)); resultPrime.addAll(substitutionSet); result.add(resultPrime); } @@ -379,12 +385,9 @@ public class Unify { UnifyType thetaPrime = extThetaPrime.getExtendedType(); Set cs = fc.getAllTypesByName(thetaPrime.getName()); - for(UnifyType c : cs) { - - // 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 - + for(UnifyType c : cs) { + Set thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); + Set thetaQPrimes = new HashSet<>(); TypeParams cParams = c.getTypeParams(); if(cParams.size() == 0) @@ -485,12 +488,9 @@ public class Unify { UnifyType theta = supTheta.getSuperedType(); Set cs = fc.getAllTypesByName(theta.getName()); - for(UnifyType c : cs) { - - // 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 - + for(UnifyType c : cs) { + Set thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); + Set thetaQPrimes = new HashSet<>(); TypeParams cParams = c.getTypeParams(); if(cParams.size() == 0) diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 3d091f5e..1a9ec729 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -129,6 +129,8 @@ public class UnifyTest extends Unify { addAsSet(expected, new UnifyPair(tphA, supObject, PairOperator.EQUALSDOT)); actual = unify(eq, fc); + System.out.println("? super Integer"); + System.out.println(actual); actual = filterGeneratedTPHsMultiple(actual); Assert.assertEquals(expected, actual); @@ -278,9 +280,9 @@ public class UnifyTest extends Unify { UnifyType integer = tf.getSimpleType("Integer"); UnifyType doubl = tf.getSimpleType("Double"); - fcb.add(number, object); + //fcb.add(number, object); fcb.add(integer, number); - fcb.add(doubl, number); + //fcb.add(doubl, number); IFiniteClosure fc = fcb.getCollectionExample(); @@ -289,6 +291,10 @@ public class UnifyTest extends Unify { * * (Vector <. Vector) * (List <. List) + * + * Expected: + * {(b = Number), (a = Number)}, {(b = Number), (a = Integer)}, {(b = Number), (a = Integer)} + * (b = Integer), */ UnifyType tphA = tf.getPlaceholderType("a"); @@ -305,26 +311,7 @@ public class UnifyTest extends Unify { System.out.println(actual); //Assert.assertEquals(actual, expected); - - /* - * Test 8: - * - * (a <.? ? sup b) - * (b = Number) - */ - - UnifyType supB = tf.getSuperType(tphB); - eq = new HashSet<>(); - eq.add(new UnifyPair(tphA, supB, PairOperator.SMALLERDOTWC)); - eq.add(new UnifyPair(tphB, number, PairOperator.EQUALSDOT)); - - expected = new HashSet<>(); - - actual = unify(eq, fc); - - System.out.println(actual); - //Assert.assertEquals(expected, actual); - + /* * Test 2: @@ -382,6 +369,101 @@ public class UnifyTest extends Unify { //Assert.assertEquals(actual, expected); } + /** + * These are tests that specifically test cases where the old unify algorithm was incomplete. + */ + @Test + public void unifyTestExtension() { + /* + * 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: + * This is a Test for the extension of case 1 in the cartesian product of step 4. + * + * (a <. Vector) + * (List <. List) + * + * Expected: + * (b = Integer), (a = Vector) + * (b = ? extends Integer), (a = Vector), + * (b = ? extends Integer), (a = Vector), + * (b = ? super Integer), (a = Vector) + * (b = ? super Integer), (a = Vector) + * (b = ? super Integer), (a = Vector) + * (b = ? super Integer), (a = Vector) + * (b = ? extends Number), (a = Vector) + * (b = ? extends Number), (a = Vector) + * (b = ? extends Number), (a = Vector) + * (b = ? extends Number), (a = Vector) + */ + + 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 UnifyPair(tphA, tf.getSimpleType("Stack", tphB), PairOperator.SMALLERDOT)); + eq.add(new UnifyPair(tf.getSimpleType("List", integer), tf.getSimpleType("List", tphB), PairOperator.SMALLERDOT)); + + Set> expected = new HashSet<>(); + Set> actual = unify(eq, fc); + + System.out.println(actual); + //Assert.assertEquals(actual, expected); + + /* + * Test 2: + * + * This is a test for th extension of case 2 of the cartesian product of step 4. + * + * TODO + */ + + /* + * Test 3: + * This is a test for the extension of case 3 of the cartesian product of step 4. + * + * (a <.? ? sup b) + * (b = Number) + */ + + UnifyType supB = tf.getSuperType(tphB); + eq = new HashSet<>(); + eq.add(new UnifyPair(tphA, supB, PairOperator.SMALLERDOTWC)); + eq.add(new UnifyPair(tphB, number, PairOperator.EQUALSDOT)); + + expected = new HashSet<>(); + + actual = unify(eq, fc); + + System.out.println(actual); + //Assert.assertEquals(expected, actual); + + /* + * Test 4: + * This is a test for the extension of case 4 of the cartesian product of step 4. + * + * + */ + } + @Test public void unifyTestComplex() { /*