diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 00c12f65..d2c6f0f4 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -53,6 +53,8 @@ public interface IFiniteClosure { public Set grArg(FunNType type); public Set smArg(FunNType type); - public Optional findGenericParent(String typeName); + public Optional getLeftHandedType(Type t); + public Set getAncestors(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 4bbcde0b..9e1b8808 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -271,8 +272,6 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); result.add(type); - // smaller(type).forEach(x -> result.add(new ExtendsType(x))); TODO inkorrekt? daher erstmal raus - return result; } @@ -318,8 +317,6 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - //result.add(new SuperType(type)); TODO inkorrekt, daher erstmal raus - //result.add(new ExtendsType(type)); return result; } @@ -337,25 +334,6 @@ public class FiniteClosure implements IFiniteClosure { return false; } - - @Override - public Optional findGenericParent(String type) { - Type genericType = null; - for(MPair pair : pairs) { - Type lhs = pair.getLhsType(); - if(lhs.getName().equals(type)) { - genericType = lhs; - break; - } - } - - if(genericType == null) - return Optional.empty(); - - // TODO reduce reglen überarbeiten, es kann mehrere Typen D geben die eine bedingung - // erfüllen, diese methode ausimplementieren - return Optional.empty(); - } @Override public Set getAllTypesByName(String typeName) { @@ -364,6 +342,25 @@ public class FiniteClosure implements IFiniteClosure { return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } + @Override + public Optional getLeftHandedType(Type t) { + if(!strInheritanceGraph.containsKey(t.getName())) + return Optional.empty(); + + for(MPair pair : pairs) + if(pair.getLhsType().getName().equals(t.getName())) + return Optional.of(pair.getLhsType()); + + return Optional.empty(); + } + + @Override + public Set getAncestors(Type t) { + if(!inheritanceGraph.containsKey(t)) + return new HashSet<>(); + return inheritanceGraph.get(t).getContentOfPredecessors(); + } + protected void permuteParams(ArrayList> candidates, int idx, Set result, Type[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index bae13582..672c104d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -85,26 +85,26 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - Type lhsType = pair.getLhsType(); + Type x = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) + if(!(x instanceof SimpleType) && !(x instanceof ExtendsType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); + Type extY = pair.getRhsType(); - if(!(rhsType instanceof ExtendsType)) + if(!(extY instanceof ExtendsType)) return Optional.empty(); - if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) + if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsType, rhsType); + int[] pi = pi(x, extY); if(pi.length == 0) return Optional.empty(); - TypeParams rhsTypeParams = rhsType.getTypeParams(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams rhsTypeParams = extY.getTypeParams(); + TypeParams lhsTypeParams = x.getTypeParams(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) @@ -160,7 +160,7 @@ public class RuleSet implements IRuleSet{ if(!rhsType.getName().equals(lhsType.getName())) return Optional.empty(); - if(rhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) + if(rhsType instanceof PlaceholderType || lhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) return Optional.empty(); if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) @@ -328,16 +328,16 @@ public class RuleSet implements IRuleSet{ if(typeD.getName().equals(typeDs.getName())) return Optional.empty(); - Optional opt = finiteClosure.findGenericParent(typeD.getName()); + Optional opt = finiteClosure.getLeftHandedType(typeD); if(!opt.isPresent()) return Optional.empty(); // The generic Version of Type D (D) Type typeDgen = opt.get(); - + // Actually greater+ because the types are ensured to have different names - Set greater = finiteClosure.greater(typeDgen); + Set greater = finiteClosure.getAncestors(typeDgen); opt = greater.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) @@ -350,7 +350,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); } @@ -373,9 +373,9 @@ public class RuleSet implements IRuleSet{ Type typeDgen; if(typeD instanceof SimpleType) - typeDgen = finiteClosure.findGenericParent(typeD.getName()).orElse(null); + typeDgen = finiteClosure.getLeftHandedType(typeD).orElse(null); else { - Optional opt = finiteClosure.findGenericParent(((ExtendsType) typeD).getExtendedType().getName()); + Optional opt = finiteClosure.getLeftHandedType(((ExtendsType) typeD).getExtendedType()); typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null; } @@ -396,7 +396,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC)); } @@ -418,7 +418,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); - Optional opt = finiteClosure.findGenericParent(((SuperType) typeSupD).getSuperedType().getName()); + Optional opt = finiteClosure.getLeftHandedType(((SuperType) typeSupD).getSuperedType()); if(!opt.isPresent()) return Optional.empty(); @@ -448,7 +448,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC)); } @@ -460,43 +460,27 @@ 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 = null; - if(C instanceof SimpleType) - cFromFc = finiteClosure.findGenericParent(C.getName()).orElse(null); - else if(C instanceof ExtendsType) { - Optional opt = finiteClosure.findGenericParent(((ExtendsType) C).getExtendedType().getName()); - if(opt.isPresent()) cFromFc = new ExtendsType(opt.get()); - } - else if(C instanceof SuperType) { - Optional opt = finiteClosure.findGenericParent(((SuperType) C).getSuperedType().getName()); - if(opt.isPresent()) cFromFc = new SuperType(opt.get()); - } + String simpleTypeDName = D.getName(); + if(D instanceof ExtendsType) + simpleTypeDName = ((ExtendsType) D).getExtendedType().getName(); + else if(D instanceof SuperType) + simpleTypeDName = ((SuperType) D).getSuperedType().getName(); - if(cFromFc == null) + 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]; - Optional opt = Optional.empty(); - if(D instanceof ExtendsType) { - SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); - opt = finiteClosure.grArg(cFromFc).stream() - .filter(x -> x instanceof ExtendsType) - .filter(x -> ((ExtendsType) x).getExtendedType().getName().equals(dSType.getName())).findAny(); - } - else if(D instanceof SuperType) { - SimpleType dSType = (SimpleType) ((SuperType) D).getSuperedType(); - opt = finiteClosure.grArg(cFromFc).stream() - .filter(x -> x instanceof SuperType) - .filter(x -> ((SuperType) x).getSuperedType().getName().equals(dSType.getName())).findAny(); - } - else if (D instanceof SimpleType) - opt = finiteClosure.greater(cFromFc).stream() - .filter(x -> x.getName().equals(D.getName())).findAny(); - - if(!opt.isPresent()) - return new int[0]; - - Type dFromFc = opt.get(); - + Type cFromFc = typesFromFc.get()[0]; + Type dFromFc = typesFromFc.get()[1]; + Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); Assert.assertTrue(dFromFc.getTypeParams().size() > 0);