diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index e618482d..977f36ee 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Optional; @@ -57,12 +59,30 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet<>(); - - Set result = inheritanceGraph.get(type).getContentOfDescendants(); + Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : new HashSet<>(); result.add(type); + 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; } @@ -72,11 +92,30 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet<>(); - - Set result = inheritanceGraph.get(type).getContentOfPredecessors(); + Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfPredecessors() : new HashSet<>(); result.add(type); + + 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.grArg(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; } @@ -213,4 +252,18 @@ public class FiniteClosure implements IFiniteClosure { return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } + + protected void permuteParams(ArrayList> candidates, int idx, Set result, Type[] current) { + if(candidates.size() == idx) { + result.add(new TypeParams(Arrays.copyOf(current, current.length))); + return; + } + + Set localCandidates = candidates.get(idx); + + for(Type t : localCandidates) { + current[idx] = t; + permuteParams(candidates, idx+1, result, current); + } + } } diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 9b5c72e6..7b1b6664 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -1,15 +1,11 @@ package unify; -import java.util.HashSet; -import java.util.Set; - import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typeinference.unifynew.TypeFactory; -import de.dhbwstuttgart.typeinference.unify.model.Type; public class FiniteClosureTest { @@ -37,10 +33,14 @@ public class FiniteClosureTest { @Test public void testSmaller() { - IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); TypeFactory tf = new TypeFactory(); + fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); + IFiniteClosure fc = fcb.getCollectionExample(); + System.out.println("\n\n----- Smaller Test -----"); + System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", tf.getExtendsType(tf.getSimpleType("Number"))))); System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", "T"))); System.out.println("Smaller(TreeSet) = " + fc.smaller(tf.getSimpleType("TreeSet", "T"))); System.out.println("Smaller(Collection) = " + fc.smaller(tf.getSimpleType("Collection")));