diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index f31255e0..23a2750c 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -126,28 +126,20 @@ public class JavaTXCompiler { xConsSet = xConsSet.stream().map(x -> { if ((x.getLhsType() instanceof PlaceholderType)) { - if (paraTypeVarNames.contains(x.getLhsType().getName()) - && (!(x.getRhsType() instanceof PlaceholderType) - || ((x.getRhsType() instanceof PlaceholderType) && !paraTypeVarNames.contains(x.getRhsType().getName()) && !returnTypeVarNames.contains(x.getRhsType().getName())))) { - x.setVariance((byte)1); + if (paraTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)1); } - if (returnTypeVarNames.contains(x.getLhsType().getName()) - && (!(x.getRhsType() instanceof PlaceholderType) - || ((x.getRhsType() instanceof PlaceholderType) && !paraTypeVarNames.contains(x.getRhsType().getName()) && !returnTypeVarNames.contains(x.getRhsType().getName())))) { - x.setVariance((byte)-1); + if (returnTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)-1); } } if ((x.getRhsType() instanceof PlaceholderType)) { - if (paraTypeVarNames.contains(x.getRhsType().getName()) - && (!(x.getLhsType() instanceof PlaceholderType) - || ((x.getLhsType() instanceof PlaceholderType) && !paraTypeVarNames.contains(x.getLhsType().getName()) && !returnTypeVarNames.contains(x.getLhsType().getName())))) { - x.setVariance((byte)1); - } - if (returnTypeVarNames.contains(x.getRhsType().getName()) - && (!(x.getLhsType() instanceof PlaceholderType) - || ((x.getLhsType() instanceof PlaceholderType) && !paraTypeVarNames.contains(x.getLhsType().getName()) && !returnTypeVarNames.contains(x.getLhsType().getName())))) { - x.setVariance((byte)-1); - } + if (paraTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)1); + } + if (returnTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)-1); + } } return x; }).collect(Collectors.toCollection(HashSet::new)); diff --git a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index ec383afe..24f16bc8 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -314,7 +314,17 @@ public class TypeUnifyTask extends RecursiveTask>> { writeLog("nextSet: " + nextSet.toString()); List> nextSetasList = oup.sortedCopy(nextSet);//new ArrayList<>(nextSet); Set> result = new HashSet<>(); - byte variance = nextSetasList.iterator().next().iterator().next().getVariance(); + int variance = 0; + Optional xi = nextSetasList.stream().map(x -> x.stream().filter(y -> y.getLhsType() instanceof PlaceholderType) + .filter(z -> ((PlaceholderType)z.getLhsType()).getVariance() != 0) + .map(c -> ((PlaceholderType)c.getLhsType()).getVariance()) + .reduce((a,b)-> a*b)) + .filter(d -> d.isPresent()) + .map(e -> e.get()) + .findAny(); + if (xi.isPresent()) { + variance = xi.get(); + } if (variance == 1 && nextSetasList.size() > 1) { List> al = new ArrayList<>(nextSetasList.size()); for (int ii = 0; ii < nextSetasList.size();ii++) { diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index 5aab8784..d9fd6699 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -37,6 +37,15 @@ public final class PlaceholderType extends UnifyType{ */ private final boolean IsGenerated; + /** + * variance shows the variance of the pair + * -1: contravariant + * 1 covariant + * 0 invariant + * PL 2018-03-21 + */ + private int variance = 0; + /** * Creates a new placeholder type with the specified name. */ @@ -80,6 +89,14 @@ public final class PlaceholderType extends UnifyType{ return IsGenerated; } + public void setVariance(int v) { + variance = v; + } + + public int getVariance() { + return variance; + } + @Override Set smArg(IFiniteClosure fc) { return fc.smArg(this); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java index 780d05a5..e57c5e42 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java @@ -72,6 +72,7 @@ public class UnifyPair { pairOp = op; unifier = uni; basePair = base; + this.variance = variance; // Caching hashcode