From ae37dd625596bc2ffb2d2b285a3f5cd9188fb327 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 18:08:46 +0100 Subject: [PATCH] fc identifier from string to type --- .../unify/interfaces/IFiniteClosure.java | 2 +- .../typeinference/unifynew/RuleSet.java | 59 +++++++++++-- .../unify/model/FiniteClosure.java | 83 ++++++++++++------- .../typinference/unify/model/SuperType.java | 2 +- .../typinference/unify/model/TypeParams.java | 9 +- test/unify/RuleSetTest.java | 59 ++++++++++++- 6 files changed, 171 insertions(+), 43 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index fb620046..796a2706 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -48,5 +48,5 @@ public interface IFiniteClosure { public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); - public Type getType(String typeName); + public Type getType(Type type); } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 5eb2c90b..ad9afc7d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -322,7 +322,7 @@ public class RuleSet implements IRuleSet{ if(lhsType.getName().equals(rhsType.getName())) return Optional.empty(); - Type lhsFromFc = finiteClosure.getType(lhsType.getName()); + Type lhsFromFc = finiteClosure.getType(lhsType); if(lhsFromFc == null) return Optional.empty(); @@ -364,9 +364,9 @@ public class RuleSet implements IRuleSet{ Type lhsFromFc; if(lhsType instanceof SimpleType) - lhsFromFc = finiteClosure.getType(lhsType.getName()); + lhsFromFc = finiteClosure.getType(lhsType); else - lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType().getName())); + lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType())); if(lhsFromFc == null) return Optional.empty(); @@ -392,8 +392,51 @@ public class RuleSet implements IRuleSet{ @Override public Optional adaptSup(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType)) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(!(rhsType instanceof SuperType)) + return Optional.empty(); + + if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + return Optional.empty(); + + Type lhsFromFc; + Type newRhs; + if(lhsType instanceof SimpleType) { + lhsFromFc = finiteClosure.getType(lhsType); + newRhs = new ExtendsType(lhsType); + } + else { + lhsFromFc = new ExtendsType(finiteClosure.getType(((SuperType) lhsType).getSuperedType())); + newRhs = new ExtendsType(((SuperType) lhsType).getSuperedType()); + } + + if(lhsFromFc == null) + return Optional.empty(); + + Set grArg = finiteClosure.grArg(lhsFromFc); + + Optional opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + + if(!opt.isPresent()) + return Optional.empty(); + + Type newLhs = opt.get(); + + TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + + Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); + for(int i = 1; i < lhsTypeParams.size(); i++) + unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + + return Optional.of(new MPair(newLhs.apply(unif), newRhs, PairOperator.SMALLERDOTWC)); } /** @@ -405,11 +448,11 @@ public class RuleSet implements IRuleSet{ private int[] pi(Type C, Type D) { Type cFromFc = null; if(C instanceof SimpleType) - cFromFc = finiteClosure.getType(C.getName()); + cFromFc = finiteClosure.getType(C); else if(C instanceof ExtendsType) - cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType().getName())); + cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType())); else if(C instanceof SuperType) - cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType().getName())); + cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType())); if(cFromFc == null) return new int[0]; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 0b1ee461..b8910e17 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -9,11 +9,12 @@ import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; public class FiniteClosure implements IFiniteClosure { - private HashMap> inheritanceGraph; + private HashMap> inheritanceGraph; + private HashMap>> strInheritanceGraph; public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { @@ -21,13 +22,13 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType().getName())) - inheritanceGraph.put(pair.getLhsType().getName(), new Node(pair.getLhsType())); - if(!inheritanceGraph.containsKey(pair.getRhsType().getName())) - inheritanceGraph.put(pair.getRhsType().getName(), new Node(pair.getRhsType())); + if(!inheritanceGraph.containsKey(pair.getLhsType())) + inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); + if(!inheritanceGraph.containsKey(pair.getRhsType())) + inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); - Node childNode = inheritanceGraph.get(pair.getLhsType().getName()); - Node parentNode = inheritanceGraph.get(pair.getRhsType().getName()); + Node childNode = inheritanceGraph.get(pair.getLhsType()); + Node parentNode = inheritanceGraph.get(pair.getRhsType()); // Add edge parentNode.AddDescendant(childNode); @@ -36,6 +37,16 @@ public class FiniteClosure implements IFiniteClosure { parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode)); childNode.getDescendants().stream().forEach(x -> x.AddPredecessor(parentNode)); } + + // Build the alternative representation with strings as keys + + strInheritanceGraph = new HashMap<>(); + for(Type key : inheritanceGraph.keySet()) { + if(!strInheritanceGraph.containsKey(key.getName())) + strInheritanceGraph.put(key.getName(), new HashSet<>()); + + strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key)); + } } /** @@ -44,21 +55,15 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); - Set result = inheritanceGraph.get(type.getName()).getContentOfDescendants(); + Set result = inheritanceGraph.get(type).getContentOfDescendants(); result.add(type); + return result; } - @Override - public Type getType(String typeName) { - if(!inheritanceGraph.containsKey(typeName)) - return null; - - return inheritanceGraph.get(typeName).getContent(); - } /** * Returns all types of the finite closure that are supertypes of the argument. @@ -66,10 +71,10 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); - Set result = inheritanceGraph.get(type.getName()).getContentOfPredecessors(); + Set result = inheritanceGraph.get(type).getContentOfPredecessors(); result.add(type); return result; } @@ -82,12 +87,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getName()).getContent(); + Type t = inheritanceGraph.get(type).getContent(); result.add(t); smaller(type).forEach(x -> result.add(new SuperType(x))); @@ -98,12 +103,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + if(!inheritanceGraph.containsKey(type.getExtendedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); greater(t).forEach(x -> result.add(new ExtendsType(x))); @@ -112,12 +117,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + if(!inheritanceGraph.containsKey(type.getSuperedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); smaller(t).forEach(x -> result.add(new SuperType(x))); @@ -136,12 +141,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getName()).getContent(); + Type t = inheritanceGraph.get(type).getContent(); result.add(t); smaller(type).forEach(x -> result.add(new ExtendsType(x))); @@ -150,12 +155,12 @@ public class FiniteClosure implements IFiniteClosure { } public Set smArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + if(!inheritanceGraph.containsKey(type.getExtendedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); result.add(t); smaller(t).forEach(x -> { @@ -169,12 +174,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + if(!inheritanceGraph.containsKey(type.getSuperedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); result.add(t); greater(t).forEach(x -> { @@ -189,4 +194,20 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { return new HashSet<>(); } + + @Override + public Type getType(Type type) { + if(!strInheritanceGraph.containsKey(type.getName())) + return null; + + HashSet> candidates = strInheritanceGraph.get(type.getName()); + + for(Node node : candidates) { + Type candidate = node.getContent(); + if(candidate.getTypeParams().arePlaceholders()) + return candidate; + } + + return null; + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index 6a243e34..15c432d2 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -10,7 +10,7 @@ public final class SuperType extends Type { private Type superedType; public SuperType(Type superedType) { - super("? extends " + superedType.getName(), superedType.getTypeParams()); + super("? super " + superedType.getName(), superedType.getTypeParams()); this.superedType = superedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index 0d48e814..d723395d 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -7,11 +7,18 @@ import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class TypeParams implements Iterable{ private final Type[] typeParams; - + public TypeParams(Type... types) { typeParams = types; } + public boolean arePlaceholders() { + for(Type t : typeParams) + if(!(t instanceof PlaceholderType)) + return false; + return true; + } + @Override public String toString() { String res = ""; diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 818aa47a..da8b8544 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -396,7 +396,7 @@ public class RuleSetTest { * Positive Tests */ MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); - MPair erase2 = new MPair(tf.getSimpleType("HashSet", "W"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); + MPair erase2 = new MPair(tf.getSimpleType("HashSet", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); MPair erase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); Assert.assertTrue(rules.erase1(erase1)); @@ -568,9 +568,12 @@ public class RuleSetTest { SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); SimpleType t2 = tf.getSimpleType("Type2", "T"); SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + SimpleType t32 = tf.getSimpleType("Type3", "T", "U"); + SimpleType t4 = tf.getSimpleType("Object"); fcb.add(t1, t2); fcb.add(t2, t3); + fcb.add(t32, t4); IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); @@ -621,6 +624,60 @@ public class RuleSetTest { @Test public void testAdaptSup() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); + SimpleType t2 = tf.getSimpleType("Type2", "T"); + SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + + fcb.add(t1, t2); + fcb.add(t2, t3); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + + /* + * Positive Tests + */ + + SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); + SimpleType c2 = tf.getSimpleType("Type2", "Object"); + SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + SuperType supc1 = new SuperType(c1); + SuperType supc2 = new SuperType(c2); + SuperType supc3 = new SuperType(c3); + + MPair pair1 = new MPair(c2, supc1, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(c3, supc2, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(c3, supc1, PairOperator.SMALLERDOTWC); + MPair pair4 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC); + MPair pair5 = new MPair(supc3, supc2, PairOperator.SMALLERDOTWC); + MPair pair6 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC); + MPair pair7 = new MPair(supc1, supc1, PairOperator.SMALLERDOTWC); + + System.out.println("------ AdaptSup ------"); + System.out.println(rules.adaptSup(pair1)); + System.out.println(rules.adaptSup(pair2)); + System.out.println(rules.adaptSup(pair3)); + System.out.println(rules.adaptSup(pair4)); + System.out.println(rules.adaptSup(pair5)); + System.out.println(rules.adaptSup(pair6)); + System.out.println(rules.adaptSup(pair7)); + + /* + * Negative Tests + */ + + MPair noAdapt1 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC); + MPair noAdapt2 = new MPair(supc1, c2, PairOperator.SMALLERDOTWC); + MPair noAdapt3 = new MPair(tf.getExtendsType(c1), supc2, PairOperator.SMALLERDOTWC); + MPair noAdapt4 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC); + MPair noAdapt5 = new MPair(c1, supc2, PairOperator.SMALLERDOT); + + Assert.assertFalse(rules.adaptExt(noAdapt1).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt2).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt3).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt4).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt5).isPresent()); } }