From 23142adc70ccf9bf9ed502750acccd33a475f055 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Tue, 29 Mar 2016 17:52:38 +0200 Subject: [PATCH 1/4] reduce rules --- .../typeinference/unifynew/RuleSet.java | 140 ++++++++++-------- 1 file changed, 81 insertions(+), 59 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 672c104d..aa966e5b 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -11,6 +11,7 @@ import java.util.Set; import java.util.stream.Collectors; import junit.framework.Assert; +import de.dhbwstuttgart.typeinference.unify.FC_TTO; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; @@ -86,8 +87,13 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type x = pair.getLhsType(); + Type sTypeX; - if(!(x instanceof SimpleType) && !(x instanceof ExtendsType)) + if(x instanceof SimpleType) + sTypeX = x; + else if(x instanceof ExtendsType) + sTypeX = ((ExtendsType) x).getExtendedType(); + else return Optional.empty(); Type extY = pair.getRhsType(); @@ -98,17 +104,31 @@ public class RuleSet implements IRuleSet{ if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(x, extY); + Type xFromFc = finiteClosure.getLeftHandedType(sTypeX).orElse(null); + + if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders()) + return Optional.empty(); + + if(x instanceof ExtendsType) + xFromFc = new ExtendsType(xFromFc); + + Type 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,30 +138,48 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - Type lhsType = pair.getLhsType(); + Type x = pair.getLhsType(); + Type sTypeX; - 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(); - Type rhsType = pair.getRhsType(); + Type supY = 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); + Type xFromFc = finiteClosure.getLeftHandedType(sTypeX).orElse(null); + + if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders()) + return Optional.empty(); + + if(x instanceof SuperType) + xFromFc = new SuperType(xFromFc); + + Type 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); } @@ -166,7 +204,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,27 +220,37 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOT) return Optional.empty(); - Type lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType)) + Type c = pair.getLhsType(); + if(!(c instanceof SimpleType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); - if(!(rhsType instanceof SimpleType)) + Type 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); + Type cFromFc = finiteClosure.getLeftHandedType(c).orElse(null); + + if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders()) + return Optional.empty(); + + Type 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++) @@ -459,34 +507,9 @@ public class RuleSet implements IRuleSet{ * @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(Type C, Type 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]; - - Type cFromFc = typesFromFc.get()[0]; - Type 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(); - + private int[] pi(TypeParams cArgs, TypeParams dArgs) { + Assert.assertEquals(cArgs.size(), dArgs.size()); + int[] permutation = new int[dArgs.size()]; boolean succ = true; @@ -500,9 +523,8 @@ public class RuleSet implements IRuleSet{ break; } } - - if(succ) return permutation; - return new int[0]; + + return succ ? permutation : new int[0]; } @Override From 50304109782e46e8d7826096dd6f1a68c7d9c9e8 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Tue, 29 Mar 2016 19:07:54 +0200 Subject: [PATCH 2/4] finitclosure tests angepasst --- test/unify/FiniteClosureTest.java | 37 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 7322e857..6512243c 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -98,10 +98,8 @@ 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 } */ Type t = tf.getPlaceholderType("T"); @@ -109,14 +107,9 @@ public class FiniteClosureTest { Type hashSetT = tf.getSimpleType("HashSet", t); Type treeSetT = tf.getSimpleType("TreeSet", t); Type linkedHashSetT = tf.getSimpleType("LinkedHashSet", t); - Type hashSetExtT = tf.getSimpleType("HashSet", t); - Type treeSetExtT = tf.getSimpleType("TreeSet", t); - Type linkedHashSetExtT = tf.getSimpleType("LinkedHashSet", t); - Type setExtT = tf.getSimpleType("Set", t); expectedResult = new HashSet<>(Arrays.stream(new Type[] { - setT, hashSetT, treeSetT, linkedHashSetT, - setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + setT, hashSetT, treeSetT, linkedHashSetT }).collect(Collectors.toSet())); Assert.assertEquals(expectedResult, fc.smaller(setT)); @@ -153,19 +146,28 @@ 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 } * */ - + 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[] { - setT, hashSetT, treeSetT, linkedHashSetT, - setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + setT1, hashSetT1, treeSetT1, linkedHashSetT1, + setExtT1, hashSetExtT1, treeSetExtT1, linkedHashSetExtT1 }).collect(Collectors.toSet())); - Assert.assertEquals(expectedResult, fc.smaller(setExtT)); + Assert.assertEquals(expectedResult, fc.smaller(setExtT1)); /* * Test Case 7: @@ -656,7 +658,6 @@ public class FiniteClosureTest { @Test public void testGetGenericType() { - // TODO } From 304a5693a6b5606459a6a985042672c82d8ff05e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 30 Mar 2016 16:25:26 +0200 Subject: [PATCH 3/4] wc regeln angepasst, triviale tests fertig --- .../unify/interfaces/IFiniteClosure.java | 2 +- .../unify/model/FiniteClosure.java | 17 +- .../typeinference/unifynew/RuleSet.java | 8 +- .../typeinference/unifynew/Unify.java | 10 +- test/unify/UnifyTest.java | 252 ++++++++++++++++-- 5 files changed, 253 insertions(+), 36 deletions(-) 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()))); + } } From d89d06797e17a7a95f007fe24e9b6133b3b13179 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Thu, 31 Mar 2016 22:09:46 +0200 Subject: [PATCH 4/4] isInSolvedForm(), Unit-Tests, removed PairOp.Equals --- .../typeinference/unify/model/MPair.java | 3 - .../typeinference/unifynew/Mapping.java | 23 +- .../unifynew/MartelliMontanariUnify.java | 2 +- .../typeinference/unifynew/RuleSet.java | 11 +- .../typeinference/unifynew/Unify.java | 30 +- test/unify/UnifyOldTest.java | 585 ++++++++++-------- test/unify/UnifyTest.java | 95 ++- 7 files changed, 443 insertions(+), 306 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java index 6b740c46..60a3ff0d 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java @@ -6,7 +6,6 @@ public class MPair { SMALLER, SMALLERDOT, SMALLERDOTWC, - EQUALS, EQUALSDOT; @Override @@ -18,8 +17,6 @@ public class MPair { return "<."; case SMALLERDOTWC: return "<.?"; - case EQUALS: - return "="; default: return "=."; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java b/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java index c8996dc8..9a80f75d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java @@ -56,32 +56,27 @@ public class Mapping { return result.size() == pairs.size() ? Optional.of(result) : Optional.empty(); } - private de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator mapOp(de.dhbwstuttgart.typeinference.Pair.PairOperator op) { - /* - * TODO - * Warum hat der PairOp nur drei Werte? Wie wird SMALLERDOTWC etc im anderen Pair geregelt? - */ - + private de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator mapOp(de.dhbwstuttgart.typeinference.Pair.PairOperator op) { switch(op) { case Equal: - return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.EQUALS; + return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.EQUALSDOT; case Smaller: - return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.SMALLER; - case SmallerExtends: return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.SMALLERDOT; - default: - return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.EQUALS; + case SmallerExtends: + return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.SMALLERDOTWC; + default: + return de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator.EQUALSDOT; } } private de.dhbwstuttgart.typeinference.Pair.PairOperator unmapOp(de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator op) { switch(op) { - case EQUALS: - return de.dhbwstuttgart.typeinference.Pair.PairOperator.Equal; case SMALLER: return de.dhbwstuttgart.typeinference.Pair.PairOperator.Smaller; case SMALLERDOT: - return de.dhbwstuttgart.typeinference.Pair.PairOperator.SmallerExtends; + return de.dhbwstuttgart.typeinference.Pair.PairOperator.Smaller; + case SMALLERDOTWC: + return de.dhbwstuttgart.typeinference.Pair.PairOperator.SmallerExtends; default: return de.dhbwstuttgart.typeinference.Pair.PairOperator.Equal; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java index e3ae2322..f6bc2ca5 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -33,7 +33,7 @@ public class MartelliMontanariUnify implements IUnify { Type prev = iter.next(); while(iter.hasNext()) { Type 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/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index fde25609..d3f89104 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -542,12 +542,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; Type rhsType; @@ -560,8 +560,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(); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 26a74729..5d2040c3 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.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; @@ -68,7 +65,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()); @@ -133,17 +130,31 @@ 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 -> !x.isEmpty()).collect(Collectors.toCollection(HashSet::new)); + return eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x)).collect(Collectors.toCollection(HashSet::new)); } + protected boolean isSolvedForm(Set eqPrimePrime) { + for(MPair pair : eqPrimePrime) { + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + + if(!(lhsType instanceof PlaceholderType)) + return false; + + if(pair.getPairOp() != PairOperator.EQUALSDOT && !(rhsType instanceof PlaceholderType)) + return false; + } + + return true; + } + protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { /* @@ -288,7 +299,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, Type thetaPrime, IFiniteClosure fc) { diff --git a/test/unify/UnifyOldTest.java b/test/unify/UnifyOldTest.java index 85f5ffd5..b93ba610 100644 --- a/test/unify/UnifyOldTest.java +++ b/test/unify/UnifyOldTest.java @@ -7,7 +7,9 @@ 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.RefType; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.Pair; @@ -17,287 +19,322 @@ import de.dhbwstuttgart.typeinference.unify.Unify; public class UnifyOldTest { @Test - public void unifyTestSimpleTypes() { + public void unifyTest1() { // 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)); + 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 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)); - } +// +// @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)); +// } } diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 2d2faad8..3c5792a3 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -4,7 +4,6 @@ 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; @@ -242,6 +241,100 @@ public class UnifyTest extends Unify { @Test public void unifyTestSimple() { + /* + * INIT + */ + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + + 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(); + + /* + * Test 1: + * + * (Vector <. Vector) + * (List <. List) + */ + + Type tphA = tf.getPlaceholderType("a"); + Type tphB = tf.getPlaceholderType("b"); + Type extB = tf.getExtendsType(tphB); + Type 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 + * + */ + + Type 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); + }