diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 9424ba2b..43e33640 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -78,35 +78,25 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type lhsType = pair.getLhsType(); - SimpleType lhsSType; - if(lhsType instanceof SimpleType) - lhsSType = (SimpleType) lhsType; - else if(lhsType instanceof ExtendsType) - lhsSType = (SimpleType) ((ExtendsType) lhsType).getExtendedType(); - else - return Optional.empty(); - - if(lhsSType.getTypeParams().empty()) + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof ExtendsType)) return Optional.empty(); - - SimpleType rhsSType = (SimpleType) ((ExtendsType) rhsType).getExtendedType(); - - if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + + if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsSType, rhsType); + int[] pi = pi(lhsType, rhsType); if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) @@ -121,39 +111,29 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type lhsType = pair.getLhsType(); - SimpleType lhsSType; - if(lhsType instanceof SimpleType) - lhsSType = (SimpleType) lhsType; - else if(lhsType instanceof SuperType) - lhsSType = (SimpleType) ((SuperType) lhsType).getSuperedType(); - else - return Optional.empty(); - - if(lhsSType.getTypeParams().empty()) + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType)) return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof SuperType)) return Optional.empty(); - - SimpleType rhsSType = (SimpleType) ((SuperType) rhsType).getSuperedType(); - - if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + + if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsSType, rhsType); + int[] pi = pi(lhsType, rhsType); if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[rhsIdx], rhsTypeParams[pi[rhsIdx]], PairOperator.SMALLERDOTWC)); + result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -205,7 +185,7 @@ public class RuleSet implements IRuleSet{ SimpleType lhsSType = (SimpleType) lhsType; SimpleType rhsSType = (SimpleType) rhsType; - if(lhsSType.getTypeParams().empty() || rhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) + if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) return Optional.empty(); int[] pi = pi(lhsSType, rhsSType); @@ -267,7 +247,7 @@ public class RuleSet implements IRuleSet{ Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); for(int i = 0; i < rhsTypeParams.length; i++) - result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.SMALLERDOT)); + result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.EQUALSDOT)); return Optional.of(result); } @@ -346,15 +326,20 @@ public class RuleSet implements IRuleSet{ * @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) { - Type cFromFc = finiteClosure.getType(C.getName()); + Type cFromFc = null; + if(C instanceof SimpleType) + cFromFc = finiteClosure.getType(C.getName()); + else if(C instanceof ExtendsType) + cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType().getName())); + else if(C instanceof SuperType) + cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType().getName())); + if(cFromFc == null) return new int[0]; Optional opt = Optional.empty(); if(D instanceof ExtendsType) { SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); - - Set t = finiteClosure.grArg(cFromFc); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof ExtendsType) .filter(x -> ((ExtendsType) x).getExtendedType().getName().equals(dSType.getName())).findAny(); diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 26aefa59..754e3a25 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -265,7 +265,64 @@ public class RuleSetTest { @Test public void testReduceSup() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + /* + * Positive Tests + */ + + // X + SimpleType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); + // Y + SimpleType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); + SimpleType buffer = tf.getSimpleType("Buffer"); + + //X + SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + //? extends Y, Number, Double, N> + SuperType supY1 = tf.getSuperType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); + + // Y<...> < buffer < X<...> + fcb.add(y1, buffer); + fcb.add(buffer, x1); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + MPair pair1 = new MPair(x2, supY1, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(tf.getSuperType(x2), supY1, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(supY1, supY1, PairOperator.SMALLERDOTWC); + + System.out.println("------ ReduceSup ------"); + Optional> opt1 = rules.reduceSup(pair1); + System.out.println(opt1); + + Optional> opt2 = rules.reduceSup(pair2); + System.out.println(opt2); + + Optional> opt3 = rules.reduceSup(pair3); + System.out.println(opt3); + + /* + * Negative Tests + */ + + // Case 1: X <.? Y + pair1 = new MPair(x2, supY1.getSuperedType(), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair1).isPresent()); + + // Case 2: X =. ? super Y + pair2 = new MPair(x2, supY1, PairOperator.EQUALSDOT); + Assert.assertFalse(rules.reduceSup(pair2).isPresent()); + + // Case 3: ? super Y <.? ? super X + pair3 = new MPair(supY1, tf.getSuperType(x2), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair3).isPresent()); + + // Case 4: X <. ? super Y and ? super Y not in grArg(X) + fcb.clear(); + rules = new RuleSet(fcb.getFiniteClosure()); + pair1 = new MPair(x2, supY1, PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair1).isPresent()); } @Test