diff --git a/.classpath b/.classpath index 46d57734c..8031ed71f 100755 --- a/.classpath +++ b/.classpath @@ -5,6 +5,5 @@ - diff --git a/.externalToolBuilders/JavaParserBuilder.launch b/.externalToolBuilders/JavaParserBuilder.launch index 0db12c073..8e4b330b5 100755 --- a/.externalToolBuilders/JavaParserBuilder.launch +++ b/.externalToolBuilders/JavaParserBuilder.launch @@ -13,7 +13,7 @@ - + diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index f1e81cfbb..86bcc272f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; +import java.util.stream.Stream; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; @@ -777,14 +778,96 @@ public class SourceFile } */ - Vector> unifyResult = Unify.unify(constraintsClone, finiteClosure); + //IDEE: Man bildet Zusammenhangskomponenten von Paaren, die gemeinsame Variablen haben + // und unifizert nur die Zusammenhangskomponenten in Schritten 1 - 5 + + //Schritt 1: Alle Variablen in den Paaren von Elementen einsammeln + Vector> constraintsclonevars = constraintsClone.stream().map(p -> {Vector TPHs = new Vector<>(); + TPHs.addAll(p.TA1.getInvolvedTypePlaceholder()); + TPHs.addAll(p.TA2.getInvolvedTypePlaceholder()); + return TPHs;} + ).collect(Vector::new, Vector::add, Vector::addAll); + + //Schritt 2: Schnittmengen jedes Elements mit jedem Elememt von vars bilden und dann index zusammenfassen + //in indexset sind dann die Mengen von Indizes enthalten, die gemeisam unifiziert wreden müssen + Vector> indexeset = new Vector<>(); + if (constraintsclonevars != null && constraintsclonevars.size()>0) { + indexeset = Unify.schnitt(constraintsclonevars); + } + + //Schritt 3: Umwandlung der Indizes in die zugehoerigen Elemente + // In streamconstraintsclone sind die Mengen von Paar enthalten die unifiziert werden muessen + Stream> streamconstraintsclone = indexeset.stream().map(x -> x.stream() + .map(i -> constraintsClone.elementAt(i)) + .collect(Vector::new, Vector::add, Vector::addAll)); +// Vector> vecconstraintsclone = streamconstraintsclone.collect(Vector::new, Vector::add, Vector::addAll); + + //Schritt 4: Unifikation + Vector>> vecunifyResult = + streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Vector::new, Vector::add, Vector::addAll); + + //card gibt die Cardinalitaet der unifizierten Mengen an + Vector card = vecunifyResult.stream().map(x -> x.size()).collect(Vector::new, Vector::add, Vector::addAll); + ;//.reduce(1,(a,b) -> { if ((a > 0) && (b > 0)) return (a * b); else return 1; }); + + //Schritt 5: Bildung des cartesischen Produkts + //sollte wieder entfernt werden: Weiterarbeit mit: + //[[x_1 -> t_1, x_2 -> t2], [x_1 -> t'_1, x_2 -> t'_2]] x ... x [[x_n -> t_1n], [x_n -> t2n], [x_n -> t3n]] + Vector> cardprodret_start = new Vector<>(); + cardprodret_start.add(new Vector()); + + //cart. Produkt mit kopieren + //Vector> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> { + //Vector> cardprodret= new Vector<>(); + //if (y.size() > 0) { + ////System.out.println(y); + //Vector> cardprodretold = x; + //cardprodret = new Vector<>(); + //for(int j = 0; j < cardprodretold.size(); j++) { + //for (int k = 0; k < y.size(); k++){ + //Vector help; + //if (y.size() == 1) help = cardprodretold.elementAt(j); //bei einem hinzuzufuegenden Element muss nicht kopiert werden + //else help = Unify.copyVectorPair(cardprodretold.elementAt(j)); + //help.addAll(y.elementAt(k)); + //cardprodret.add(help); + //} + //} + //} + //else + //return new Vector<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis [] + //return cardprodret; + //}); + + //cart. Produkt mit Linkverschiebung + Vector> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> { + Vector> cardprodret= new Vector<>(); + if (y.size() > 0) { + //System.out.println(y); + //Vector> cardprodretold = x; + //cardprodret = new Vector<>(); + for(int j = 0; j < x.size(); j++) { + for (int k = 0; k < y.size(); k++){ + Vector help = new Vector<>(); + help.addAll(y.elementAt(k)); + help.addAll(x.elementAt(j)); + cardprodret.add(help); + } + } + } + else + return new Vector<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis [] + return cardprodret; + }); + + //Vector> unifyResult = Unify.unify(constraintsClone, finiteClosure); //Dann den Ergebnissen anfügen result.addAll(unifyResult); // Debugoutput:Vector> - typinferenzLog.debug("Unifiziertes Ergebnis: "+result, Section.TYPEINFERENCE); - /* + typinferenzLog.debug("Unifiziertes Ergebnis: "+result, Section.TYPEINFERENCE); + + /* // Prüfe ob eindeutige Lösung: if(result.size()>1 && !Unify.hasSolvedForm(result.elementAt(0))){ diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index 461e4dc4f..d3408e028 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -847,6 +847,54 @@ public class Unify return Eq2Set; } + /** + * PL 2014-10-25 + * schnitt1 checkt ob die Typeplaceholders aus in den Elemeneten aus vars enthalten sind + * Rückgabe ist die Menge der Indizies von vars der Schnittmengen mit var nicht leer sind. + * @param var + * @param vars + * @param indexe + * @return + */ + static Vector schnitt1 (Vector var, Vector> vars, Vector indexe) { + int j = -1; + for (Vector varelems : vars) { + j++; + if (varelems != null) { + if (var.stream().map(x -> varelems.contains(x)).reduce(false, (a,b) -> (a || b)) + && (!indexe.contains(j))) + { + Vector rekvarelements = vars.elementAt(j); + vars.setElementAt(null, j);//Element erledigt muss nicht nochmals bearbeitet werden. + indexe.addElement(j); + indexe = schnitt1(rekvarelements, vars, indexe); + } + } + } + return indexe; + } + + /** + * Bildet Schnittmengen der Mengen von Typeplaceholders + * Rueckgabe ist die Menge der Menge von Indizies die Schnittmengen sind. + * @param vars + * @return + */ + public static Vector> schnitt (Vector> vars) { + Vector> ret = new Vector<>(); + int i = -1; + for (Vector var : vars) { + i++; + if (var != null) {//Element wurde noch bearbeitet + Vector indexe = new Vector<>(); + indexe.add(i); + ret.add(schnitt1(var, vars, indexe)); + } + } + return ret; + } + + /** * Diese Methode wird verwendet, um Zuordnungen z.B. TPH a = Integer * aus der Ergebnismenge zu entfernen, wenn im Typ in den die eingesetzt werden sollen kein TPH a vorhanden ist.