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