diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 7884b85f..f984d8c8 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -239,75 +239,69 @@ public class JavaTXCompiler { logFile.write(ASTTypePrinter.print(sf)); } logFile.flush(); - Set>> cardProd = unifyCons.cartesianProduct(); - for (List> xCons : cardProd ){ - Set xConsSet = new HashSet<>(); - for (Constraint constraint : xCons) { - xConsSet.addAll(constraint); - } - //.collect(Collectors.toCollection(ArrayList::new)))) - System.out.println(xConsSet); - Set paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() - .stream().filter(z -> z.getType() instanceof TypePlaceholder) - .map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) - .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) - .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;} ); - Set returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) + Set paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() + .stream().filter(z -> z.getType() instanceof TypePlaceholder) + .map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) + .reduce(new HashSet(), (a,b) -> { a.addAll(b); return a;} ); + + Set returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); - Set fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) + Set fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); - returnTypeVarNames.addAll(fieldTypeVarNames); + returnTypeVarNames.addAll(fieldTypeVarNames); - unifyCons = unifyCons.map(x -> { - //Hier muss ueberlegt werden, ob - //1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs - // mit disableWildcardtable() werden. - //2. alle Typvariablen mit Argument- oder Retuntyp-Variablen - //in Beziehung auch auf disableWildcardtable() gesetzt werden muessen - //PL 2018-04-23 - if ((x.getLhsType() instanceof PlaceholderType)) { - if (paraTypeVarNames.contains(x.getLhsType().getName())) { - ((PlaceholderType)x.getLhsType()).setVariance((byte)1); - ((PlaceholderType)x.getLhsType()).disableWildcardtable(); - } - if (returnTypeVarNames.contains(x.getLhsType().getName())) { - ((PlaceholderType)x.getLhsType()).setVariance((byte)-1); - ((PlaceholderType)x.getLhsType()).disableWildcardtable(); - } + unifyCons = unifyCons.map(x -> { + //Hier muss ueberlegt werden, ob + //1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs + // mit disableWildcardtable() werden. + //2. alle Typvariablen mit Argument- oder Retuntyp-Variablen + //in Beziehung auch auf disableWildcardtable() gesetzt werden muessen + //PL 2018-04-23 + if ((x.getLhsType() instanceof PlaceholderType)) { + if (paraTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)1); + ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } - if ((x.getRhsType() instanceof PlaceholderType)) { - if (paraTypeVarNames.contains(x.getRhsType().getName())) { - ((PlaceholderType)x.getRhsType()).setVariance((byte)1); - ((PlaceholderType)x.getRhsType()).disableWildcardtable(); - } - if (returnTypeVarNames.contains(x.getRhsType().getName())) { - ((PlaceholderType)x.getRhsType()).setVariance((byte)-1); - ((PlaceholderType)x.getRhsType()).disableWildcardtable(); - } + if (returnTypeVarNames.contains(x.getLhsType().getName())) { + ((PlaceholderType)x.getLhsType()).setVariance((byte)-1); + ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } - return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE - }).map( y -> { - if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { - if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { - ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); - } - if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { - ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); - } - } - return y; } ); - varianceInheritanceConstrainSet(unifyCons); - Set> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); - //Set> result = unify.unify(xConsSet, finiteClosure); - System.out.println("RESULT: " + result); - logFile.write("RES: " + result.toString()+"\n"); - logFile.flush(); - results.addAll(result); - } - + } + if ((x.getRhsType() instanceof PlaceholderType)) { + if (paraTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)1); + ((PlaceholderType)x.getRhsType()).disableWildcardtable(); + } + if (returnTypeVarNames.contains(x.getRhsType().getName())) { + ((PlaceholderType)x.getRhsType()).setVariance((byte)-1); + ((PlaceholderType)x.getRhsType()).disableWildcardtable(); + } + } + return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE + }).map( y -> { + if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { + if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { + ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); + } + if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { + ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); + } + } + return y; } ); + varianceInheritanceConstrainSet(unifyCons); + //Set> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); + //Set> result = unify.unify(xConsSet, finiteClosure); + Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), unifyCons.getOderConstraints(), finiteClosure, logFile, log); + System.out.println("RESULT: " + result); + logFile.write("RES: " + result.toString()+"\n"); + logFile.flush(); + results.addAll(result); + + results = results.stream().map(x -> { Optional> res = new RuleSet().subst(x.stream().map(y -> { if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); @@ -328,7 +322,8 @@ public class JavaTXCompiler { } /** - * Vererbt alle Variancen + * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) + * wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * @param eq The set of constraints */ private void varianceInheritance(Set eq) { @@ -359,7 +354,8 @@ public class JavaTXCompiler { } /** - * Vererbt alle Variancen + * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) + * wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * @param eq The set of constraints */ private void varianceInheritanceConstrainSet(ConstraintSet cons) { diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java index 09984d28..4d1f076f 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java @@ -70,4 +70,12 @@ public class ConstraintSet { } return ret; } + + public List>> getOderConstraints() { + return oderConstraints; + } + + public Set getUndConstraints() { + return undConstraints; + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/TypeUnify.java b/src/de/dhbwstuttgart/typeinference/unify/TypeUnify.java index fa190cb7..d2428def 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/TypeUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/TypeUnify.java @@ -1,9 +1,11 @@ package de.dhbwstuttgart.typeinference.unify; import java.io.FileWriter; +import java.util.List; import java.util.Set; import java.util.concurrent.ForkJoinPool; +import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; @@ -21,5 +23,11 @@ public class TypeUnify { Set> res = unifyTask.compute(); return res; } + + public Set> unifyOderConstraints(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log); + Set> res = unifyTask.compute(); + return res; + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index 7864ece1..7af531e6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -18,6 +18,7 @@ import java.util.function.BinaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; @@ -71,7 +72,9 @@ public class TypeUnifyTask extends RecursiveTask>> { */ protected IRuleSet rules; - protected Set eq; + protected Set eq; //und-constraints + + protected List>> oderConstraints; protected IFiniteClosure fc; @@ -101,6 +104,25 @@ public class TypeUnifyTask extends RecursiveTask>> { rules = new RuleSet(logFile); } + public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log) { + this.eq = eq; + //this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new)); + this.oderConstraints = oderConstraints.stream().map(x -> { + Set> ret = new HashSet<>(); + for (Constraint y : x) { + ret.add(new HashSet<>(y)); + } + return ret; + }).collect(Collectors.toCollection(ArrayList::new)); + + //x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new)); + this.fc = fc; + this.oup = new OrderingUnifyPair(fc); + this.parallel = parallel; + this.logFile = logFile; + this.log = log; + rules = new RuleSet(logFile); + } /** * Vererbt alle Variancen @@ -141,6 +163,251 @@ public class TypeUnifyTask extends RecursiveTask>> { else return res; } + protected Set> computeNew() { + Set> fstElems = new HashSet<>(); + fstElems.add(eq); + Set> res = computeCartesianRecursiveOderConstraints(fstElems, oderConstraints, fc, parallel); + if (isUndefinedPairSetSet(res)) { return new HashSet<>(); } + else return res; + } + + public Set> computeCartesianRecursiveOderConstraints(Set> fstElems, List>> topLevelSets, IFiniteClosure fc, boolean parallel) { + //ArrayList>> remainingSets = new ArrayList<>(topLevelSets); + fstElems.addAll(topLevelSets.stream() + .filter(x -> x.size()==1) + .map(y -> y.stream().findFirst().get()) + .collect(Collectors.toCollection(HashSet::new))); + ArrayList>> remainingSets = topLevelSets.stream() + .filter(x -> x.size()>1) + .collect(Collectors.toCollection(ArrayList::new)); + if (remainingSets.isEmpty()) {//Alle Elemente sind 1-elementig + Set eq = new HashSet<>(); + fstElems.stream().forEach(x -> eq.addAll(x)); + Set> result = unify(eq, fc, parallel); + return result; + } + Set> nextSet = remainingSets.remove(0); + writeLog("nextSet: " + nextSet.toString()); + List> nextSetasList =new ArrayList<>(nextSet); + try { + //List> + //nextSetasList = oup.sortedCopy(nextSet);//new ArrayList<>(nextSet); + } + catch (java.lang.IllegalArgumentException e) { + System.out.print(""); + } + Set> result = new HashSet<>(); + 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)-> {if (a==b) return a; else return 0; })) + .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++) { + // al.add(0,nextSetasList.get(ii)); + // } + // nextSetasList = al; + //} + //Set a = nextSetasListIt.next(); + /*if (nextSetasList.size()>1) {zu loeschen + if (nextSetasList.iterator().next().iterator().next().getLhsType().getName().equals("D")) + System.out.print(""); + if (variance == 1) { + a_next = oup.max(nextSetasList.iterator()); + } + else if (variance == -1) { + a_next = oup.min(nextSetasList.iterator()); + } + else if (variance == 0) { + a_next = nextSetasList.iterator().next(); + } + } + else { + a_next = nextSetasList.iterator().next(); + } + */ + if (!nextSetasList.iterator().hasNext()) + System.out.print(""); + if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1) + System.out.print(""); + writeLog("nextSetasList: " + nextSetasList.toString()); + while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) { + Set a = null; + if (variance == 1) { + a = oup.max(nextSetasList.iterator()); + nextSetasList.remove(a); + } + else if (variance == -1) { + a = oup.min(nextSetasList.iterator()); + nextSetasList.remove(a); + } + else if (variance == 0) { + a = nextSetasList.remove(0); + } + //writeLog("nextSet: " + nextSetasList.toString()+ "\n"); + //nextSetasList.remove(a); + /* zu loeschen + if (nextSetasList.size() > 0) { + if (nextSetasList.size()>1) { + if (variance == 1) { + a_next = oup.max(nextSetasList.iterator()); + } + else if (variance == -1) { + a_next = oup.min(nextSetasList.iterator()); + } + else { + a_next = nextSetasList.iterator().next(); + } + } + else { + a_next = nextSetasList.iterator().next(); + } + } + */ + //PL 2018-03-01 + //TODO: 1. Maximum und Minimum unterscheiden + //TODO: 2. compare noch für alle Elmemente die nicht X =. ty sind erweitern + //for(Set a : newSet) { + i++; + Set> elems = new HashSet>(fstElems); + elems.add(a); + if (remainingSets.isEmpty()) { + writeLog("Vor unify Aufruf: " + eq.toString()); + Set eq = new HashSet<>(); + fstElems.stream().forEach(x -> eq.addAll(x)); + Set> res = unify(eq, fc, parallel); + if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) { + //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen + result = res; + } + else { + if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) + || (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) + || result.isEmpty()) { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + result.addAll(res); + } + //else { + //wenn Korrekte Ergebnisse da und Feherfälle dazukommen Fehlerfälle ignorieren + // if (isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) { + // result = result; + // } + //} + } + + + /* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */ + if (!result.isEmpty() && !isUndefinedPairSetSet(res)) { + if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("B")).findFirst().isPresent() && nextSetasList.size()>1) + System.out.print(""); + Iterator> nextSetasListIt = new ArrayList>(nextSetasList).iterator(); + if (variance == 1) { + System.out.println(""); + while (nextSetasListIt.hasNext()) { + Set a_next = nextSetasListIt.next(); + if (a.equals(a_next) || + (oup.compare(a, a_next) == 1)) { + nextSetasList.remove(a_next); + } + else { + System.out.println(""); + } + } + } + else { if (variance == -1) { + System.out.println(""); + while (nextSetasListIt.hasNext()) { + Set a_next = nextSetasListIt.next(); + if (a.equals(a_next) || + (oup.compare(a, a_next) == -1)) { + nextSetasList.remove(0); + } + else { + System.out.println(""); + } + } + } + else if (variance == 0) { + break; + }} + } + /* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */ + + if (isUndefinedPairSetSet(res)) { + int nofstred= 0; + Set abhSubst = res.stream() + .map(b -> + b.stream() + .map(x -> x.getAllSubstitutions()) + .reduce((y,z) -> { y.addAll(z); return y;}).get()) + .reduce((y,z) -> { y.addAll(z); return y;}).get(); + Set b = a;//effective final a + Set durchschnitt = abhSubst.stream() + .filter(x -> b.contains(x)) + //.filter(y -> abhSubst.contains(y)) + .collect(Collectors.toCollection(HashSet::new)); + //Set vars = durchschnitt.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new)); + int len = nextSetasList.size(); + Set undefRes = res.stream().reduce((y,z) -> { y.addAll(z); return y;}).get(); //flatten aller undef results + Set, UnifyPair>> reducedUndefResSubstGroundedBasePair = undefRes.stream() + .map(x -> { Set su = x.getAllSubstitutions(); //alle benutzten Substitutionen + su.add(x.getGroundBasePair()); // urspruengliches Paar + su.removeAll(durchschnitt); //alle aktuell genänderten Paare entfernen + return new Pair<>(su, x.getGroundBasePair());}) + .collect(Collectors.toCollection(HashSet::new)); + if (res.size() > 1) { + System.out.println(); + } + nextSetasList = nextSetasList.stream().filter(x -> { + //Boolean ret = false; + //for (PlaceholderType var : vars) { + // ret = ret || x.stream().map(b -> b.getLhsType().equals(var)).reduce((c,d) -> c || d).get(); + //} + return (!x.containsAll(durchschnitt)); + })//.filter(y -> couldBecorrect(reducedUndefResSubstGroundedBasePair, y)) //fuer testzwecke auskommentiert um nofstred zu bestimmen PL 2018-10-10 + .collect(Collectors.toCollection(ArrayList::new)); + nofstred = nextSetasList.size(); + //NOCH NICHT korrekt PL 2018-10-12 + //nextSetasList = nextSetasList.stream().filter(y -> couldBecorrect(reducedUndefResSubstGroundedBasePair, y)) + // .collect(Collectors.toCollection(ArrayList::new)); + writeLog("res (undef): " + res.toString()); + writeLog("abhSubst: " + abhSubst.toString()); + writeLog("a: " + a.toString()); + writeLog("Durchschnitt: " + durchschnitt.toString()); + writeLog("nextSet: " + nextSet.toString()); + writeLog("nextSetasList: " + nextSetasList.toString()); + writeLog("Number first erased Elements (undef): " + (len - nofstred)); + writeLog("Number second erased Elements (undef): " + (nofstred- nextSetasList.size())); + writeLog("Number erased Elements (undef): " + (len - nextSetasList.size())); + noAllErasedElements = noAllErasedElements + (len - nextSetasList.size()); + writeLog("Number of all erased Elements (undef): " + noAllErasedElements.toString()); + noBacktracking++; + writeLog("Number of Backtracking: " + noBacktracking); + System.out.println(""); + } + //if (nextSetasList.size() == 0 && isUndefinedPairSetSet(result) && nextSet.size() > 1) { + // return result; + //} + //else { + // result.removeIf(y -> isUndefinedPairSet(y)); + //} + //else result.stream().filter(y -> !isUndefinedPairSet(y)); + } + else {//duerfte gar nicht mehr vorkommen PL 2018-04-03 + result.addAll(computeCartesianRecursive(elems, remainingSets, eq, fc, parallel)); + } + return result; + } + } + + /** * Computes all principal type unifiers for a set of constraints. * @param eq The set of constraints