diff --git a/pom.xml b/pom.xml index 3c31a7e8..3541ad9b 100644 --- a/pom.xml +++ b/pom.xml @@ -138,10 +138,6 @@ http://maven.apache.org/maven-v4_0_0.xsd"> - @@ -169,5 +165,3 @@ http://maven.apache.org/maven-v4_0_0.xsd"> - - diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index f8d4a363..fd570a0c 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -27,25 +27,34 @@ import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.unify.RuleSet; import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.distributeVariance; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; +import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl; +import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; +import org.apache.commons.io.output.NullOutputStream; + public class JavaTXCompiler { final CompilationEnvironment environment; + Boolean resultmodel = true; public final Map sourceFiles = new HashMap<>(); Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll? @@ -268,9 +277,8 @@ public class JavaTXCompiler { } */ - - public List typeInference() throws ClassNotFoundException { - List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); + public UnifyResultModel typeInferenceAsync() throws ClassNotFoundException { + List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf)); @@ -279,10 +287,12 @@ public class JavaTXCompiler { final ConstraintSet cons = getConstraints(); Set> results = new HashSet<>(); + UnifyResultModel urm = new UnifyResultModel(); try { - FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); + Writer logFile = new OutputStreamWriter(new NullOutputStream()); + //new FileWriter(new File("log_"+sourceFiles.keySet().iterator().next().getName())); - FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); System.out.println(finiteClosure); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); @@ -388,35 +398,193 @@ public class JavaTXCompiler { //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"); + List>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> { + Set> ret = new HashSet<>(); + for (Constraint y : x) { + ret.add(new HashSet<>(y)); + } + return ret; + }).collect(Collectors.toCollection(ArrayList::new)); + unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons, urm); + } + catch (IOException e) { + System.err.println("kein LogFile"); + } + return urm; + } + + + public List typeInference() throws ClassNotFoundException { + List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); + //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC + for(SourceFile sf : this.sourceFiles.values()) { + allClasses.addAll(getAvailableClasses(sf)); + allClasses.addAll(sf.getClasses()); + } + + final ConstraintSet cons = getConstraints(); + Set> results = new HashSet<>(); + try { + Writer logFile = new OutputStreamWriter(new NullOutputStream()); + //new FileWriter(new File("log_"+sourceFiles.keySet().iterator().next().getName())); + + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses,logFile); + System.out.println(finiteClosure); + ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); + + Function distributeInnerVars = + x -> { + UnifyType lhs, rhs; + if (((lhs = x.getLhsType()) instanceof PlaceholderType) + && ((rhs = x.getRhsType()) instanceof PlaceholderType) + && (((PlaceholderType)lhs).isInnerType() + || ((PlaceholderType)rhs).isInnerType())) + { + ((PlaceholderType)lhs).setInnerType(true); + ((PlaceholderType)rhs).setInnerType(true); + } + return x; + + }; + logFile.write(unifyCons.toString()); + unifyCons = unifyCons.map(distributeInnerVars); + logFile.write(unifyCons.toString()); + TypeUnify unify = new TypeUnify(); + //Set> results = new HashSet<>(); Nach vorne gezogen + logFile.write("FC:\\" + finiteClosure.toString()+"\n"); + for(SourceFile sf : this.sourceFiles.values()) { + logFile.write(ASTTypePrinter.print(sf)); + } logFile.flush(); - results.addAll(result); + + Set methodParaTypeVarNames = 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 constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().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 paraTypeVarNames = methodParaTypeVarNames; + paraTypeVarNames.addAll(constructorParaTypeVarNames); + + + 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) + .map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); + + 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(); + } + } + 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 + }); + Set varianceTPHold; + Set varianceTPH = new HashSet<>(); + varianceTPH = varianceInheritanceConstraintSet(unifyCons); + + /* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt + do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen + //anderen Seite übertragen + varianceTPHold = new HashSet<>(varianceTPH); + varianceTPH = varianceInheritanceConstraintSet(unifyCons); + unifyCons.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; } ); } + while (!varianceTPHold.equals(varianceTPH)); + */ + + //Set> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); + //Set> result = unify.unify(xConsSet, finiteClosure); + List>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> { + Set> ret = new HashSet<>(); + for (Constraint y : x) { + ret.add(new HashSet<>(y)); + } + return ret; + }).collect(Collectors.toCollection(ArrayList::new)); + if (resultmodel) { + /* UnifyResultModel Anfang */ + UnifyResultModel urm = new UnifyResultModel(); + UnifyResultListenerImpl li = new UnifyResultListenerImpl(); + urm.addUnifyResultListener(li); + unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons, urm); + System.out.println("RESULT Final: " + li.getResults()); + logFile.write("RES_FINAL: " + li.getResults().toString()+"\n"); + logFile.flush(); + return li.getResults(); + } + /* UnifyResultModel End */ + else { + Set> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + //Set> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); + 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); - return y; //alle Paare a <.? b erden durch a =. b ersetzt - }).collect(Collectors.toCollection(HashSet::new))); - if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert - return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); - } - else return x; //wenn nichts veraendert wurde wird x zurueckgegeben - }).collect(Collectors.toCollection(HashSet::new)); - System.out.println("RESULT Final: " + results); - logFile.write("RES_FINAL: " + results.toString()+"\n"); - logFile.flush(); - logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); - logFile.flush(); - } - catch (IOException e) { - System.err.println("kein LogFile"); - } - return results.stream().map((unifyPairs -> - new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList()); - } + results = results.stream().map(x -> { + Optional> res = new RuleSet().subst(x.stream().map(y -> { + if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); + return y; //alle Paare a <.? b erden durch a =. b ersetzt + }).collect(Collectors.toCollection(HashSet::new))); + if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert + return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); + } + else return x; //wenn nichts veraendert wurde wird x zurueckgegeben + }).collect(Collectors.toCollection(HashSet::new)); + System.out.println("RESULT Final: " + results); + logFile.write("RES_FINAL: " + results.toString()+"\n"); + logFile.flush(); + logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); + logFile.flush(); + }} + catch (IOException e) { + System.err.println("kein LogFile"); + } + return results.stream().map((unifyPairs -> + new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); + } + /** @@ -464,19 +632,7 @@ public class JavaTXCompiler { } - private Map generateTPHMap(ConstraintSet constraints) { - HashMap ret = new HashMap<>(); - constraints.map((Pair p) -> { - if (p.TA1 instanceof TypePlaceholder) { - ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); - } - if (p.TA2 instanceof TypePlaceholder) { - ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); - } - return null; - }); - return ret; - } + private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index f3fbdd63..a764db6e 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.io.FileWriter; +import java.io.Writer; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,7 +31,7 @@ public class UnifyTypeFactory { private static ArrayList PLACEHOLDERS = new ArrayList<>(); - public static FiniteClosure generateFC(List fromClasses, FileWriter logFile) throws ClassNotFoundException { + public static FiniteClosure generateFC(List fromClasses, Writer logFile) throws ClassNotFoundException { /* Die transitive Hülle muss funktionieren. Man darf schreiben List extends AL diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java index 4d1f076f..1dda8dc5 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.constraints; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java index 98679f7d..0c8ad7a5 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Pair.java @@ -1,7 +1,10 @@ package de.dhbwstuttgart.typeinference.constraints; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; @@ -110,5 +113,20 @@ public class Pair implements Serializable public boolean OperatorSmallerDot() { return eOperator == PairOperator.SMALLERDOT; } + + + static public Map generateTPHMap(ConstraintSet constraints) { + HashMap ret = new HashMap<>(); + constraints.map((Pair p) -> { + if (p.TA1 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); + } + if (p.TA2 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); + } + return null; + }); + return ret; + } } // ino.end diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java index d4e6b551..e333bdfe 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -28,6 +28,7 @@ import de.dhbwstuttgart.typeinference.unify.distributeVariance; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; /** * Implementation of the type inference rules. @@ -36,13 +37,13 @@ import java.io.IOException; */ public class RuleSet implements IRuleSet{ - FileWriter logFile; + Writer logFile; public RuleSet() { super(); } - RuleSet(FileWriter logFile) { + RuleSet(Writer logFile) { this.logFile = logFile; } @@ -319,13 +320,21 @@ public class RuleSet implements IRuleSet{ UnifyType lhsType = pair.getLhsType(); ReferenceType lhsSType; + UnifyType rhsType = pair.getRhsType(); + ReferenceType rhsSType; - if(lhsType instanceof ReferenceType) + if ((lhsType instanceof ReferenceType) && (rhsType instanceof ReferenceType)) { lhsSType = (ReferenceType) lhsType; - else if(lhsType instanceof WildcardType) { + rhsSType = (ReferenceType) rhsType; + } + else if (((lhsType instanceof ExtendsType) && (rhsType instanceof ExtendsType)) + || ((lhsType instanceof SuperType) && (rhsType instanceof SuperType))) { UnifyType lhsSTypeRaw = ((WildcardType) lhsType).getWildcardedType(); - if(lhsSTypeRaw instanceof ReferenceType) + UnifyType rhsSTypeRaw = ((WildcardType) rhsType).getWildcardedType(); + if ((lhsSTypeRaw instanceof ReferenceType) && (rhsSTypeRaw instanceof ReferenceType)) { lhsSType = (ReferenceType) lhsSTypeRaw; + rhsSType = (ReferenceType) rhsSTypeRaw; + } else return Optional.empty(); } @@ -334,7 +343,8 @@ public class RuleSet implements IRuleSet{ if(lhsSType.getTypeParams().empty()) return Optional.empty(); - + + /* PL 2018-01-22 in obere Teil integriert UnifyType rhsType = pair.getRhsType(); ReferenceType rhsSType; @@ -349,6 +359,7 @@ public class RuleSet implements IRuleSet{ } else return Optional.empty(); + */ if(!rhsSType.getName().equals(lhsSType.getName())) return Optional.empty(); diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java index d2428def..974581a9 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java @@ -1,31 +1,52 @@ package de.dhbwstuttgart.typeinference.unify; import java.io.FileWriter; +import java.io.Writer; import java.util.List; import java.util.Set; import java.util.concurrent.ForkJoinPool; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; public class TypeUnify { - public Set> unify(Set eq, IFiniteClosure fc, FileWriter logFile, Boolean log) { - TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, true, logFile, log); + public Set> unify(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, ConstraintSet cons) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, new UnifyResultModel(), cons); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(unifyTask); Set> res = unifyTask.join(); return res; } + public UnifyResultModel unifyAsync(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); + ForkJoinPool pool = new ForkJoinPool(); + pool.invoke(unifyTask); + return ret; + } + + public UnifyResultModel unifyParallel(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, ConstraintSet cons, UnifyResultModel ret) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); + ForkJoinPool pool = new ForkJoinPool(); + pool.invoke(unifyTask); + Set> res = unifyTask.join(); + return ret; + } + + /* public Set> unifySequential(Set eq, IFiniteClosure fc, FileWriter logFile, Boolean log) { TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log); 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); + public Set> unifyOderConstraints(Set undConstrains, List>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet cons) { + TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, new UnifyResultModel(), cons); Set> res = unifyTask.compute(); return res; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java new file mode 100644 index 00000000..ac6f04bb --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java @@ -0,0 +1,38 @@ +package de.dhbwstuttgart.typeinference.unify; + +import java.io.FileWriter; +import java.io.Writer; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; + +public class TypeUnify2Task extends TypeUnifyTask { + + Set> setToFlatten; + + public TypeUnify2Task(Set> setToFlatten, Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons) { + super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); + this.setToFlatten = setToFlatten; + } + + @Override + protected Set> compute() { + if (one) { + System.out.println("two"); + } + one = true; + Set> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField); + /*if (isUndefinedPairSetSet(res)) { + return new HashSet<>(); } + else + */ + noOfThread--; + return res; + } +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java index a149be4c..43142773 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java @@ -19,7 +19,10 @@ import java.util.function.BinaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; @@ -34,12 +37,14 @@ import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.Unifier; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; +import de.dhbwstuttgart.typeinference.unify.model.WildcardType; import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair; import de.dhbwstuttgart.typeinference.unify.model.Pair; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import com.google.common.collect.Ordering; @@ -55,8 +60,19 @@ public class TypeUnifyTask extends RecursiveTask>> { private boolean printtag = false; Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll? + /** + * Fuer die Threads + */ + UnifyResultModel urm; + ConstraintSet cons; + protected static int noOfThread = 0; + private static int totalnoOfThread = 0; + int thNo; + protected boolean one = false; + Integer MaxNoOfThreads = 8; + public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/"; - FileWriter logFile; + Writer logFile; /** * The implementation of setOps that will be used during the unification @@ -83,6 +99,8 @@ public class TypeUnifyTask extends RecursiveTask>> { protected boolean parallel; + int rekTiefeField; + Integer nOfUnify = 0; Integer noUndefPair = 0; @@ -97,6 +115,7 @@ public class TypeUnifyTask extends RecursiveTask>> { rules = new RuleSet(); } + /* public TypeUnifyTask(Set eq, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log) { this.eq = eq; this.fc = fc; @@ -105,26 +124,41 @@ public class TypeUnifyTask extends RecursiveTask>> { this.logFile = logFile; this.log = log; rules = new RuleSet(logFile); + noOfThread++; + thNo = noOfThread; } + */ - 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.oderConstraintsField = oderConstraints.stream().map(x -> { + public TypeUnifyTask(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet cons2) { + synchronized (this) { + 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.oderConstraintsField = oderConstraints; /*.stream().map(x -> { Set> ret = new HashSet<>(); for (Constraint y : x) { ret.add(new HashSet<>(y)); } return ret; - }).collect(Collectors.toCollection(ArrayList::new)); + }).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); + //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); + this.rekTiefeField = rekTiefe; + this.urm = urm; + this.cons = cons2; + + noOfThread++; + totalnoOfThread++; + writeLog("thNo1 " + thNo); + thNo = totalnoOfThread; + writeLog("thNo2 " + thNo); + } } /** @@ -161,6 +195,10 @@ public class TypeUnifyTask extends RecursiveTask>> { */ protected Set> compute() { + if (one) { + System.out.println("two"); + } + one = true; Set neweq = new HashSet<>(eq); /* 1-elementige Oder-Constraints werden in und-Constraints umgewandelt */ oderConstraintsField.stream() @@ -169,7 +207,8 @@ public class TypeUnifyTask extends RecursiveTask>> { ArrayList>> remainingOderconstraints = oderConstraintsField.stream() .filter(x -> x.size()>1) .collect(Collectors.toCollection(ArrayList::new)); - Set> res = unify(neweq, remainingOderconstraints, fc, parallel, 0); + Set> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefeField); + noOfThread--; if (isUndefinedPairSetSet(res)) { return new HashSet<>(); } else return res; } @@ -439,7 +478,7 @@ public class TypeUnifyTask extends RecursiveTask>> { * @param fc The finite closure * @return The set of all principal type unifiers */ - protected Set> unify(Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe) { + protected Set> unify(final Set eq, List>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe) { //Set aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT) // ).collect(Collectors.toCollection(HashSet::new)); //writeLog(nOfUnify.toString() + " AA: " + aas.toString()); @@ -613,10 +652,13 @@ public class TypeUnifyTask extends RecursiveTask>> { */ //writeLog("vor Subst: " + eqPrime); Optional> eqPrimePrime = rules.subst(eqPrime); + Set> unifyres1 = null; + Set> unifyres2 = null; //writeLog("nach Subst: " + eqPrimePrime); /* * Step 6 a) Restart (fork) for pairs where subst was applied */ + /* if(parallel) { if (eqPrime.equals(eq) && !eqPrimePrime.isPresent() && oderConstraints.isEmpty()) //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch @@ -637,7 +679,8 @@ public class TypeUnifyTask extends RecursiveTask>> { fork.fork(); } } - else { // sequentiell (Step 6b is included) + else */ + {// sequentiell (Step 6b is included) if (printtag) System.out.println("nextStep: " + eqPrimePrime); if (eqPrime.equals(eq) && !eqPrimePrime.isPresent() && oderConstraints.isEmpty()) { //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch @@ -654,14 +697,26 @@ public class TypeUnifyTask extends RecursiveTask>> { System.err.println("log-File nicht vorhanden"); } eqPrimePrimeSet.add(eqPrime); + Set> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> { + Optional> res = new RuleSet().subst(x.stream().map(y -> { + if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); + return y; //alle Paare a <.? b erden durch a =. b ersetzt + }).collect(Collectors.toCollection(HashSet::new))); + if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert + return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc); + } + else return x; //wenn nichts veraendert wurde wird x zurueckgegeben + }).collect(Collectors.toCollection(HashSet::new)); + urm.notify(eqPrimePrimeSetRet.stream().map((unifyPairs -> + new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))).collect(Collectors.toList())); } else if(eqPrimePrime.isPresent()) { - Set> unifyres = unify(eqPrimePrime.get(), oderConstraints, fc, false, rekTiefe); + Set> unifyres = unifyres1 = unify(eqPrimePrime.get(), oderConstraints, fc, parallel, rekTiefe); eqPrimePrimeSet.addAll(unifyres); } else { - Set> unifyres = unify(eqPrime, oderConstraints, fc, false, rekTiefe); + Set> unifyres = unifyres2 = unify(eqPrime, oderConstraints, fc, parallel, rekTiefe); eqPrimePrimeSet.addAll(unifyres); @@ -674,17 +729,20 @@ public class TypeUnifyTask extends RecursiveTask>> { /* * Step 6 b) Build the union over everything. */ + /* + * PL 2019-01-22: geloescht if(parallel) for(TypeUnifyTask fork : forks) eqPrimePrimeSet.addAll(fork.join()); - + */ /* * Step 7: Filter empty sets; */ eqPrimePrimeSet = eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x) || this.isUndefinedPairSet(x)).collect(Collectors.toCollection(HashSet::new)); - if (!eqPrimePrimeSet.isEmpty() && !isUndefinedPairSetSet(eqPrimePrimeSet)) + if (!eqPrimePrimeSet.isEmpty() && !isUndefinedPairSetSet(eqPrimePrimeSet)) { writeLog("Result1 " + eqPrimePrimeSet.toString()); + } return eqPrimePrimeSet; } @@ -758,15 +816,74 @@ public class TypeUnifyTask extends RecursiveTask>> { Set a = null; while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) { Set a_last = a; + List> nextSetasListRest = new ArrayList<>(); + //List> nextSetasListRestMin = new ArrayList<>(); + //List> nextSetasListRestOder = new ArrayList<>(); if (variance == 1) { a = oup.max(nextSetasList.iterator()); nextSetasList.remove(a); + nextSetasListRest = new ArrayList<>(nextSetasList); + Iterator> nextSetasListItRest = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest.hasNext()) { + Set a_next = nextSetasListItRest.next(); + if (//a.equals(a_next) || + (oup.compare(a, a_next) == 1)) { + nextSetasListRest.remove(a_next); + } + } + //Alle maximale Elemente in nextSetasListRest bestimmen + List> nextSetasListRestTest; + do { + nextSetasListRestTest = new ArrayList>(nextSetasListRest); + if (!nextSetasListRest.isEmpty()) { + Set max = oup.max(nextSetasListRest.iterator()); + Iterator> nextSetasListItRest2 = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest2.hasNext()) { + Set a_nextRest = nextSetasListItRest2.next(); + if (//a.equals(a_next) || + (oup.compare(max, a_nextRest) == 1)) { + nextSetasListRest.remove(a_nextRest); + } + + }} + } while(!nextSetasListRestTest.equals(nextSetasListRest)); + } else if (variance == -1) { a = oup.min(nextSetasList.iterator()); nextSetasList.remove(a); + nextSetasListRest = new ArrayList<>(nextSetasList); + Iterator> nextSetasListItRest = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest.hasNext()) { + Set a_next = nextSetasListItRest.next(); + if (//a.equals(a_next) || + (oup.compare(a, a_next) == -1)) { + nextSetasListRest.remove(a_next); + } + } + //Alle minimalen Elemente in nextSetasListRest bestimmen + + List> nextSetasListRestTest; + do { + nextSetasListRestTest = new ArrayList>(nextSetasListRest); + if (!nextSetasListRest.isEmpty()) { + Set min = oup.min(nextSetasListRest.iterator()); + Iterator> nextSetasListItRest2 = new ArrayList>(nextSetasListRest).iterator(); + while (nextSetasListItRest2.hasNext()) { + Set a_nextRest = nextSetasListItRest2.next(); + if (//a.equals(a_next) || + (oup.compare(min, a_nextRest) == -1)) { + nextSetasListRest.remove(a_nextRest); + } + + }} + } while(!nextSetasListRestTest.equals(nextSetasListRest)); } - else if (variance == 0 || variance == 2) { + else if (variance == 2) { + a = nextSetasList.remove(0); + nextSetasListRest = new ArrayList<>(nextSetasList); + } + else if (variance == 0) { a = nextSetasList.remove(0); } //writeLog("nextSet: " + nextSetasList.toString()+ "\n"); @@ -795,14 +912,175 @@ public class TypeUnifyTask extends RecursiveTask>> { //for(Set a : newSet) { i++; Set> elems = new HashSet>(fstElems); - writeLog("a1: " + rekTiefe + " "+ a.toString()+ "\n"); - elems.add(a); + writeLog("a1: " + rekTiefe + " "+ "variance: "+ variance + " " + a.toString()+ "\n"); + //elems.add(a); PL 2019-01-20 Muss weg, weil das in jeweiligen Thread erfolgen muss. Fuer den sequentiellen Fall + //im else-Zweig //if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt //writeLog("Vor unify2 Aufruf: " + elems.toString()); - Set> res = unify2(elems, eq, oderConstraints, fc, parallel, rekTiefe); + Set> res = new HashSet<>(); + Set>> add_res = new HashSet<>(); + if(parallel && (variance == 1) && noOfThread <= MaxNoOfThreads) { + Set forks = new HashSet<>(); + Set newEqOrig = new HashSet<>(eq); + Set> newElemsOrig = new HashSet<>(elems); + List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); + newElemsOrig.add(a); + + /* FORK ANFANG */ + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); + //forks.add(forkOrig); + forkOrig.fork(); + /* FORK ENDE */ + + synchronized (this) { + writeLog("a in " + variance + " "+ a); + writeLog("nextSetasListRest: " + nextSetasListRest.toString()); + } + while (!nextSetasListRest.isEmpty()) { + Set nSaL = nextSetasListRest.remove(0); + synchronized (this) { nextSetasList.remove(nSaL); + writeLog("1 RM" + nSaL.toString()); + } + Set newEq = new HashSet<>(eq); + Set> newElems = new HashSet<>(elems); + List>> newOderConstraints = new ArrayList<>(oderConstraints); + newElems.add(nSaL); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); + forks.add(fork); + fork.fork(); + } + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + + /* FORK ANFANG */ + synchronized (this) { + res = forkOrig.join(); + //Set> fork_res = forkOrig.join(); + writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + //add_res.add(fork_res); + }; + /* FORK ENDE */ + + for(TypeUnifyTask fork : forks) { + synchronized (this) { + Set> fork_res = fork.join(); + writeLog("Join " + new Integer(fork.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + add_res.add(fork_res); + }; + } + } else { + if(parallel && (variance == -1) && noOfThread <= MaxNoOfThreads) { + Set forks = new HashSet<>(); + Set newEqOrig = new HashSet<>(eq); + Set> newElemsOrig = new HashSet<>(elems); + List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); + newElemsOrig.add(a); + + /* FORK ANFANG */ + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); + //forks.add(forkOrig); + forkOrig.fork(); + /* FORK ENDE */ + + synchronized (this) { + writeLog("a in " + variance + " "+ a); + writeLog("nextSetasListRest: " + nextSetasListRest.toString()); + } + while (!nextSetasListRest.isEmpty()) { + Set nSaL = nextSetasListRest.remove(0); + synchronized (this) { nextSetasList.remove(nSaL); + writeLog("-1 RM" + nSaL.toString()); + } + Set newEq = new HashSet<>(eq); + Set> newElems = new HashSet<>(elems); + List>> newOderConstraints = new ArrayList<>(oderConstraints); + newElems.add(nSaL); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); + forks.add(fork); + fork.fork(); + } + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + + /* FORK ANFANG */ + synchronized (this) { + res = forkOrig.join(); + //Set> fork_res = forkOrig.join(); + writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + //add_res.add(fork_res); + }; + /* FORK ENDE */ + + for(TypeUnifyTask fork : forks) { + synchronized (this) { + Set> fork_res = fork.join(); + writeLog("Join " + new Integer(fork.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + add_res.add(fork_res); + }; + } + } else { + if(parallel && (variance == 2) && noOfThread <= MaxNoOfThreads) { + writeLog("var2einstieg"); + Set forks = new HashSet<>(); + Set newEqOrig = new HashSet<>(eq); + Set> newElemsOrig = new HashSet<>(elems); + List>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); + newElemsOrig.add(a); + + /* FORK ANFANG */ + TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, logFile, log, rekTiefe, urm, cons); + //forks.add(forkOrig); + forkOrig.fork(); + /* FORK ENDE */ + + synchronized (this) { + writeLog("a in " + variance + " "+ a); + writeLog("nextSetasListRest: " + nextSetasListRest.toString()); + } + while (!nextSetasListRest.isEmpty()) { + Set nSaL = nextSetasListRest.remove(0); + //nextSetasList.remove(nSaL); + Set newEq = new HashSet<>(eq); + Set> newElems = new HashSet<>(elems); + List>> newOderConstraints = new ArrayList<>(oderConstraints); + newElems.add(nSaL); + TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); + forks.add(fork); + fork.fork(); + } + //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); + + /* FORK ANFANG */ + synchronized (this) { + res = forkOrig.join(); + //Set> fork_res = forkOrig.join(); + writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + //add_res.add(fork_res); //vermutlich falsch + }; + /* FORK ENDE */ + + for(TypeUnifyTask fork : forks) { + synchronized (this) { + Set> fork_res = fork.join(); + writeLog("Join " + new Integer(fork.thNo).toString()); + //noOfThread--; an das Ende von compute verschoben + add_res.add(fork_res); + }; + }} + else { + //parallel = false; //Wenn MaxNoOfThreads erreicht ist, sequentiell weiterarbeiten + elems.add(a); //PL 2019-01-16 muss das wirklich hin steht schon in Zeile 859 ja braucht man siehe Zeile 859 + res = unify2(elems, eq, oderConstraints, fc, parallel, rekTiefe); + }}} if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) { //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen result = res; + if (res.iterator().next() instanceof WildcardType) { + System.out.println(""); + } } else { if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) @@ -874,11 +1152,13 @@ public class TypeUnifyTask extends RecursiveTask>> { //result = result; }}}} else { if (variance == 0) { + writeLog("RES var=1 ADD:" + result.toString() + " " + res.toString()); result.addAll(res); - }}} - //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + }}} } else { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + writeLog("RES Fst:" + result.toString() + " " + res.toString()); result.addAll(res); } } @@ -894,6 +1174,27 @@ public class TypeUnifyTask extends RecursiveTask>> { //else {//duerfte gar nicht mehr vorkommen PL 2018-04-03 //result.addAll(computeCartesianRecursive(elems, remainingSets, eq, fc, parallel)); //} + if (parallel) { + for (Set> par_res : add_res) { + if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) { + //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen + result = par_res; + if (par_res.iterator().next() instanceof WildcardType) { + System.out.println(""); + } + } + else { + if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) + || (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result)) + || result.isEmpty()) { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + writeLog("RES var1 ADD:" + result.toString() + " " + par_res.toString()); + result.addAll(par_res); + } + } + } + //break; + } /* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */ if (!result.isEmpty() && !isUndefinedPairSetSet(res)) { @@ -901,6 +1202,33 @@ public class TypeUnifyTask extends RecursiveTask>> { System.out.print(""); Iterator> nextSetasListIt = new ArrayList>(nextSetasList).iterator(); if (variance == 1) { + /* vorgezogen vor das if + if (parallel) { + for (Set> par_res : add_res) { + if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) { + //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen + result = par_res; + if (par_res.iterator().next() instanceof WildcardType) { + System.out.println(""); + } + } + else { + if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) + || (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result)) + || result.isEmpty()) { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + writeLog("RES var1 ADD:" + result.toString() + " " + par_res.toString()); + result.addAll(par_res); + } + } + } + //break; + */ + + /* nextSetasList = nextSetasListRest; */ + /* wird bereits vor den unify2-Aufruf durchgefuehrt und nextSetasListRest zugeordnet + */ + System.out.println(""); writeLog("a: " + rekTiefe + " variance: " + variance + a.toString()); while (nextSetasListIt.hasNext()) { @@ -917,6 +1245,32 @@ public class TypeUnifyTask extends RecursiveTask>> { } } else { if (variance == -1) { + /* vorgezogen vor das if + if (parallel) { + for (Set> par_res : add_res) { + if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) { + //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen + result = par_res; + if (par_res.iterator().next() instanceof WildcardType) { + System.out.println(""); + } + } + else { + if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) + || (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result)) + || result.isEmpty()) { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + writeLog("RES var-1 ADD:" + result.toString() + " " + par_res.toString()); + result.addAll(par_res); + } + } + } + //break; + } + + } + */ + System.out.println(""); writeLog("a: " + rekTiefe + " variance: " + variance + a.toString()); while (nextSetasListIt.hasNext()) { @@ -932,10 +1286,34 @@ public class TypeUnifyTask extends RecursiveTask>> { } } } - else if (variance == 0) { + else { if (variance == 0) { writeLog("a: " + rekTiefe + " variance: " + variance + a.toString()); - break; - } + break; } + else { if (variance == 2) { + /* vorgezogen vor das if + if (parallel) { + for (Set> par_res : add_res) { + if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) { + //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen + result = par_res; + if (par_res.iterator().next() instanceof WildcardType) { + System.out.println(""); + } + } + else { + if ((isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) + || (!isUndefinedPairSetSet(par_res) && !isUndefinedPairSetSet(result)) + || result.isEmpty()) { + //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden + writeLog("RES var2 ADD:" + result.toString() + " " + par_res.toString()); + result.addAll(par_res); + } + } + } + //break; + } + */ + }}} writeLog("a: " + rekTiefe + " variance: " + variance + a.toString()); } } @@ -1503,9 +1881,10 @@ public class TypeUnifyTask extends RecursiveTask>> { } //if (thetaPrime.getName().equals("java.util.Vector") //Fuer Bug 127 // && thetaPrime instanceof ReferenceType - // && ((ReferenceType)thetaPrime).getTypeParams().iterator().next().getName().equals("java.util.Vector") + // && ((ReferenceType)thetaPrime).getTypeParams().iterator().next() instanceof PlaceholderType) //.getName().equals("java.util.Vector")) // && ((ReferenceType)((ReferenceType)thetaPrime).getTypeParams().iterator().next()).getTypeParams().iterator().next().getName().equals("java.lang.Integer")) { - // System.out.println(""); + // { + // System.out.println(""); //} Set cs = fc.getAllTypesByName(thetaPrime.getName());//cs= [java.util.Vector, java.util.Vector>, ????java.util.Vector???] @@ -1526,13 +1905,17 @@ public class TypeUnifyTask extends RecursiveTask>> { for(UnifyType c : csPHRenamed) { //PL 18-02-05 getChildren durch smaller ersetzt in getChildren werden die Varianlen nicht ersetzt. - Set thetaQs = fc.smaller(c, new HashSet<>()).stream().collect(Collectors.toCollection(HashSet::new)); + Set thetaQs = new HashSet<>(); + //TODO smaller wieder reinnehmen? + //thetaQs.add(c);// + thetaQs = fc.smaller(c, new HashSet<>()).stream().collect(Collectors.toCollection(HashSet::new)); //Set thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new)); //thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht //PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert, //da children offensichtlich ein echtes kleiner und kein kleinergleich ist //PL 18-02-06: eingefuegt, thetaQs der Form V> <. V'> werden entfernt + //TODO PL 19-01-14 wieder reinnehmen kurzfristig auskommentiert thetaQs = thetaQs.stream().filter(ut -> ut.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); //PL 18-02-06: eingefuegt @@ -1597,13 +1980,16 @@ public class TypeUnifyTask extends RecursiveTask>> { if(allGen) { UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); - while (upit.hasNext()) ((PlaceholderType)upit.next()).setVariance(a.getVariance()); + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt + while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } else { UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair); Iterator upit = up.getRhsType().getTypeParams().iterator(); - while (upit.hasNext()) ((PlaceholderType)upit.next()).setVariance(a.getVariance()); + distributeVariance dv = new distributeVariance(); + //TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt + while (upit.hasNext()) upit.next().accept(new distributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance()); resultPrime.add(up); } resultPrime.addAll(substitutionSet); @@ -1826,8 +2212,12 @@ public class TypeUnifyTask extends RecursiveTask>> { } void writeLog(String str) { + synchronized ( this ) { if (log) { try { + logFile.write("Thread no.:" + thNo + "\n"); + logFile.write("noOfThread:" + noOfThread + "\n"); + logFile.write("parallel:" + parallel + "\n"); logFile.write(str+"\n\n"); logFile.flush(); @@ -1837,4 +2227,5 @@ public class TypeUnifyTask extends RecursiveTask>> { } } } + } } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java new file mode 100644 index 00000000..a79e34ec --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultEvent.java @@ -0,0 +1,18 @@ +package de.dhbwstuttgart.typeinference.unify; + +import java.util.List; + +import de.dhbwstuttgart.typeinference.result.ResultSet; + +public class UnifyResultEvent { + + private List newTypeResult; + + public UnifyResultEvent(List newTypeResult) { + this.newTypeResult = newTypeResult; + } + + public List getNewTypeResult() { + return newTypeResult; + } +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListener.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListener.java new file mode 100644 index 00000000..f490ccde --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListener.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.typeinference.unify; + +public interface UnifyResultListener { + + void onNewTypeResultFound(UnifyResultEvent evt); + +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java new file mode 100644 index 00000000..ea34728b --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultListenerImpl.java @@ -0,0 +1,21 @@ +package de.dhbwstuttgart.typeinference.unify; + +import java.util.ArrayList; +import java.util.List; + +import de.dhbwstuttgart.typeinference.result.ResultSet; +import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; + +public class UnifyResultListenerImpl implements UnifyResultListener { + + List results = new ArrayList<>(); + + public synchronized void onNewTypeResultFound(UnifyResultEvent evt) { + results.addAll(evt.getNewTypeResult()); + } + + public List getResults() { + return results; + } + +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java new file mode 100644 index 00000000..fe72bfea --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyResultModel.java @@ -0,0 +1,28 @@ +package de.dhbwstuttgart.typeinference.unify; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.result.ResultSet; + +public class UnifyResultModel { + + private List listeners = new ArrayList<>(); + + public void addUnifyResultListener(UnifyResultListener listenerToAdd) { + listeners.add(listenerToAdd); + } + + public void removeUnifyResultListener(UnifyResultListener listenerToRemove) { + listeners.remove(listenerToRemove); + } + + public void notify(List newResult) { + UnifyResultEvent evt = new UnifyResultEvent(newResult); + + for (UnifyResultListener listener : listeners) { + listener.onNewTypeResultFound(evt); + } + } +} diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 07c86457..29a0e198 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.io.FileWriter; import java.io.IOException; +import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -32,7 +33,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; public class FiniteClosure //extends Ordering //entfernt PL 2018-12-11 implements IFiniteClosure { - FileWriter logFile; + Writer logFile; static Boolean log = false; public void setLogTrue() { log = true; @@ -66,7 +67,7 @@ implements IFiniteClosure { /** * Creates a new instance using the inheritance tree defined in the pairs. */ - public FiniteClosure(Set pairs, FileWriter logFile) { + public FiniteClosure(Set pairs, Writer logFile) { this.logFile = logFile; this.pairs = new HashSet<>(pairs); inheritanceGraph = new HashMap>(); @@ -109,6 +110,18 @@ implements IFiniteClosure { strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key)); } } + + void testSmaller() { + UnifyType tq1, tq2, tq3; + tq1 = new ExtendsType(PlaceholderType.freshPlaceholder()); + List l1 = new ArrayList<>(); + List l2 = new ArrayList<>(); + l1.add(tq1); + tq2 = new ReferenceType("java.util.Vector", new TypeParams(l1)); + l2.add(tq2); + tq3 = new ReferenceType("java.util.Vector", new TypeParams(l2)); + Set smaller = smaller(tq3, new HashSet<>()); + } /** * Returns all types of the finite closure that are subtypes of the argument. @@ -641,8 +654,7 @@ implements IFiniteClosure { */ public int compare (UnifyType left, UnifyType right, PairOperator pairop) { - if ((left instanceof ExtendsType && right instanceof ReferenceType) - || (right instanceof ExtendsType && left instanceof ReferenceType)) + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) System.out.println(""); /* List al = new ArrayList<>(); @@ -693,6 +705,13 @@ implements IFiniteClosure { HashSet hs = new HashSet<>(); hs.add(up); Set smallerRes = unifyTask.applyTypeUnificationRules(hs, this); + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) + {try { + logFile.write("\nsmallerRes: " + smallerRes);//"smallerHash: " + greaterHash.toString()); + logFile.flush(); + } + catch (IOException e) { + System.err.println("no LogFile");}} //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); if (smallerLen == 0) return -1; @@ -702,6 +721,13 @@ implements IFiniteClosure { hs = new HashSet<>(); hs.add(up); Set greaterRes = unifyTask.applyTypeUnificationRules(hs, this); + if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) + {try { + logFile.write("\ngreaterRes: " + greaterRes);//"smallerHash: " + greaterHash.toString()); + logFile.flush(); + } + catch (IOException e) { + System.err.println("no LogFile");}} //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); if (greaterLen == 0) return 1; diff --git a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java index 73d73578..490826cc 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java @@ -229,7 +229,7 @@ public class OrderingUnifyPair extends Ordering> { if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) { hm = rsleuni.stream().reduce(new HashMap(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner); Stream lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getLhsType()) == null)); - si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } ); + si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } ); } //4. Fall else { diff --git a/src/test/resources/bytecode/javFiles/Matrix.jav b/src/test/resources/bytecode/javFiles/Matrix.jav index 9e87c1e6..29505161 100644 --- a/src/test/resources/bytecode/javFiles/Matrix.jav +++ b/src/test/resources/bytecode/javFiles/Matrix.jav @@ -1,6 +1,6 @@ import java.util.Vector; import java.lang.Integer; -//import java.lang.Float; +import java.lang.Float; //import java.lang.Byte; //import java.lang.Boolean;