diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 27827dbe..a1b56472 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -24,11 +24,13 @@ public class FiniteClosure implements IFiniteClosure { } public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { + if(!pair.getLhsType().getTypeParams().arePlaceholders()) + throw new IllegalArgumentException("The finite closure only has pairs of the form D <= C<...>"); + if(pair.getPairOp() != PairOperator.SMALLER) continue; @@ -66,14 +68,15 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - // - if(T < T') then T <=* T' - Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : new HashSet<>(); + Set result = new HashSet<>(); result.add(type); + // - if(T < T') then T <=* T' // if T1 <=* T2 then sigma1(T1) <=* sigma1(T2) // where foreach type var a in T2: // sigma1(T1) <=* sigma2(T2) - /*if(strInheritanceGraph.containsKey(type.getName())) { + //If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied) + if(strInheritanceGraph.containsKey(type.getName())) { IUnify unify = new MartelliMontanariUnify(); HashSet> candidateNodes = strInheritanceGraph.get(type.getName()); for(Node candidateNode : candidateNodes) { @@ -81,67 +84,27 @@ public class FiniteClosure implements IFiniteClosure { Optional sigma2 = unify.unify(theta2, type); if(!sigma2.isPresent()) continue; - for(Type sigma1theta1 : candidateNode.getContentOfDescendants()) { - Type theta1 = sigma2.get().apply(sigma1theta1); + Set theta1s = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : smaller(theta2); + for(Type theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + Type sigma1Theta1 = sigma2.get().apply(theta1); + + ArrayList> paramCandidates = new ArrayList<>(); + for(Type param : sigma1Theta1.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for(TypeParams newParams : permResult) + result.add(sigma1Theta1.setTypeParams(newParams)); } } - }*/ - - if(type.getTypeParams().size() == 0) - return result; - - ArrayList> paramCandidates = new ArrayList<>(); - for(Type param : type.getTypeParams()) { - if(param instanceof ExtendsType || param instanceof SuperType) { - Set pc = param.smArg(this); - paramCandidates.add(pc); - } else { - HashSet pc = new HashSet<>(); - pc.add(param); - paramCandidates.add(pc); - } } - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); - - for(TypeParams newParams : permResult) - result.add(type.setTypeParams(newParams)); - return result; } - /** - * @param t1 - * @param t2 - * @return - */ - protected Optional match(Type t1, Type t2) { - if(!t1.getName().equals(t2.getName())) - return Optional.empty(); - - TypeParams t1Params = t1.getTypeParams(); - TypeParams t2Params = t2.getTypeParams(); - - if(t1Params.size() != t2Params.size()) - return Optional.empty(); - - Unifier result = new Unifier(); - for(int i = 0; i < t1Params.size(); i++) { - Type t1i = t1Params.get(i); - Type t2i = t2Params.get(i); - - boolean equal = t1i.equals(t2i); - if(!equal && !(t2i instanceof PlaceholderType)) - return Optional.empty(); - - if(!equal && t2i instanceof PlaceholderType) - result.Add((PlaceholderType) t2i, t1i); - } - - return Optional.of(result); - } - /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. @@ -182,9 +145,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -201,9 +161,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -216,9 +173,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -245,13 +199,10 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - Set result = new HashSet(); result.add(type); - smaller(type).forEach(x -> result.add(new ExtendsType(x))); + // smaller(type).forEach(x -> result.add(new ExtendsType(x))); TODO inkorrekt? daher erstmal raus return result; } @@ -263,9 +214,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -283,9 +231,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -304,8 +249,8 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - result.add(new SuperType(type)); - result.add(new ExtendsType(type)); + //result.add(new SuperType(type)); TODO inkorrekt, daher erstmal raus + //result.add(new ExtendsType(type)); return result; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index add681e5..6c2eaa0f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -8,8 +8,6 @@ import java.util.function.Function; public class Unifier implements Function /*, Set*/ { // TODO set implementieren private HashMap substitutions = new HashMap<>(); - public static Unifier IDENTITY = new Unifier(); - public Unifier(PlaceholderType source, Type target) { substitutions.put(source, target); } @@ -21,6 +19,10 @@ public class Unifier implements Function /*, Set*/ { // TODO } + public static Unifier Identity() { + return new Unifier(); + } + public void Add(PlaceholderType source, Type target) { Unifier tempU = new Unifier(source, target); for(PlaceholderType pt : substitutions.keySet()) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java index d15fefdd..6ae0acf6 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -26,7 +26,7 @@ public class MartelliMontanariUnify implements IUnify { @Override public Optional unify(Set terms) { if(terms.size() < 2) - return Optional.of(Unifier.IDENTITY); + return Optional.of(Unifier.Identity()); ArrayList termsQ = new ArrayList(); Iterator iter = terms.iterator(); @@ -37,7 +37,7 @@ public class MartelliMontanariUnify implements IUnify { prev = next; } - Unifier mgu = Unifier.IDENTITY; + Unifier mgu = Unifier.Identity(); int idx = 0; while(idx < termsQ.size()) { @@ -101,7 +101,7 @@ public class MartelliMontanariUnify implements IUnify { TypeParams rhsTypeParams = rhs.getTypeParams(); TypeParams lhsTypeParams = lhs.getTypeParams(); - if(!rhs.getName().equals(lhs.getName()) || rhsTypeParams.size() != lhsTypeParams.size()) + if(rhsTypeParams.size() != lhsTypeParams.size() || (!rhs.getName().equals(lhs.getName()) && rhsTypeParams.size() != 0)) return null; // conflict if(rhsTypeParams.size() == 0 || lhsTypeParams.size() == 0)