From 07ea25b5b71fa32c8570908938f237ef08268c14 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 25 May 2016 17:46:33 +0200 Subject: [PATCH] Filtern von Constraints vor dem Karthesischen Produkt bilden --- .../dhbwstuttgart/syntaxtree/SourceFile.java | 205 +++++++++++------- .../unify/model/ExtendsType.java | 3 + .../unify/model/PlaceholderType.java | 10 + .../typeinference/unify/model/TypeParams.java | 10 + .../typeinference/unify/model/UnifyPair.java | 11 + .../typeinference/unify/model/UnifyType.java | 9 + .../unify/model/WildcardType.java | 11 + 7 files changed, 183 insertions(+), 76 deletions(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index f81c40f2..4576354c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -4,11 +4,14 @@ package de.dhbwstuttgart.syntaxtree; // ino.module.SourceFile.8722.import import java.io.IOException; +import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; +import java.util.List; import java.util.Set; import java.util.function.Function; @@ -49,7 +52,9 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.unify.TypeUnify; +import de.dhbwstuttgart.typeinference.unify.Unifikationsalgorithmus; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; +import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; @@ -195,7 +200,122 @@ public class SourceFile InterfaceVektor.addElement((Interface) e); } } - + + /** + * 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 Menge schnitt1 (Menge var, Menge> vars, Menge indexe) { + int j = -1; + for (Menge varelems : vars) { + j++; + if (varelems != null) { + if (var.stream().map(x -> varelems.contains(x)).reduce(false, (a,b) -> (a || b)) + && (!indexe.contains(j))) + { + Menge 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 Menge> schnitt (Menge> vars) { + Menge> ret = new Menge<>(); + int i = -1; + for (Menge var : vars) { + i++; + if (var != null) {//Element wurde noch bearbeitet + Menge indexe = new Menge<>(); + indexe.add(i); + ret.add(schnitt1(var, vars, indexe)); + } + } + return ret; + } + + public static Set> cartesianProduct(List constraints, FiniteClosure 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 + Menge> constraintsclonevars = constraints.stream().map(p -> {Menge TPHs = new Menge<>(); + TPHs.addAll(p.getInvolvedPlaceholderTypes()); + TPHs.addAll(p.getInvolvedPlaceholderTypes()); + return TPHs;} + ).collect(Menge::new, Menge::add, Menge::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 + Menge> indexeset = new Menge<>(); + if (constraintsclonevars != null && constraintsclonevars.size()>0) { + indexeset = SourceFile.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 -> constraints.get(i)) + .>collect(Menge::new, Menge::add, Menge::addAll)); + //Menge> vecconstraintsclone = streamconstraintsclone.collect(Menge::new, Menge::add, Menge::addAll); + //System.out.println(); + //Schritt 4: Unifikation + Menge>> vecunifyResult = + //streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Menge::new, Menge::add, Menge::addAll); + //DEBUG-Variante + streamconstraintsclone.map(x -> + { Set> z = new TypeUnify().unify(x, finiteClosure); + return z; + } + ).collect(Menge::new, Menge::add, Menge::addAll); + + + //card gibt die Cardinalitaet der unifizierten Mengen an + Menge card = vecunifyResult.stream().map(x -> x.size()).collect(Menge::new, Menge::add, Menge::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]] + Set> cardprodret_start = new Menge<>(); + cardprodret_start.add(new Menge()); + + //cart. Produkt mit Linkverschiebung + Set> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> { + Set> cardprodret= new Menge<>(); + if (y.size() > 0) { + //System.out.println(y); + //Menge> cardprodretold = x; + //cardprodret = new Menge<>(); + for(Set xElement : x) { + for (Set yElement : y){ + Set help = new Menge<>(); + help.addAll(yElement); + help.addAll(xElement); + cardprodret.add(help); + } + } + } + else + return new Menge<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis [] + return cardprodret; + }); + return unifyResult; + } ///////////////////////////////////////////////////////////////////////// // TypeReconstructionAlgorithmus @@ -256,13 +376,11 @@ public class SourceFile UnifyConstraintsSet unifyConstraints = UnifyTypeFactory.convert(oderConstraints); //Unmögliche ConstraintsSets aussortieren durch Unifizierung - Function,Menge>> unifier = (pairs)->{ - Menge> retValue = new Menge<>(); - Set> unifiedPairs = new TypeUnify().unify(pairs, finiteClosure); - return retValue;}; - //oderConstraints.filterWrongConstraints(unifier); + Unifikationsalgorithmus unifier = (pairs)->new TypeUnify().unify(pairs, finiteClosure); - //oderConstraints.unifyUndConstraints(unifier); //rausgeworfen für Tests (08.12.2015) + unifyConstraints.filterWrongConstraints(unifier); + + unifyConstraints.unifyUndConstraints(unifier); //rausgeworfen für Tests (08.12.2015) typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE); @@ -273,7 +391,9 @@ public class SourceFile //////////////// Set> xConstraints = unifyConstraints.cartesianProduct(); - + + //Sets zu Listen umwandeln: + //Set> allUnifiedConstraints = xConstraints.stream().map((set)-> new ArrayList<>(set)).collect(Menge::new, Menge::add, Menge::addAll);; typinferenzLog.debug("Finite Closure: "+finiteClosure, Section.TYPEINFERENCE); typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints, Section.TYPEINFERENCE); @@ -286,74 +406,7 @@ public class SourceFile boolean unifyFail = true; for(Set constraints : xConstraints){ //Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen: - //Menge> result = new Menge>(); - //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 - Menge> constraintsclonevars = constraints.stream().map(p -> {Menge TPHs = new Menge<>(); - TPHs.addAll(p.TA1.getInvolvedTypePlaceholder()); - TPHs.addAll(p.TA2.getInvolvedTypePlaceholder()); - return TPHs;} - ).collect(Menge::new, Menge::add, Menge::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 - Menge> indexeset = new Menge<>(); - 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(Menge::new, Menge::add, Menge::addAll)); - //Menge> vecconstraintsclone = streamconstraintsclone.collect(Menge::new, Menge::add, Menge::addAll); - //System.out.println(); - //Schritt 4: Unifikation - Set>> vecunifyResult = - //streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Menge::new, Menge::add, Menge::addAll); - //DEBUG-Variante - streamconstraintsclone.map(x -> - { Set> z = new Unify().unify(x, finiteClosure); - return z; - } - ).collect(Menge::new, Menge::add, Menge::addAll); - - - //card gibt die Cardinalitaet der unifizierten Mengen an - Menge card = vecunifyResult.stream().map(x -> x.size()).collect(Menge::new, Menge::add, Menge::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]] - Set> cardprodret_start = new Menge<>(); - cardprodret_start.add(new Menge()); - - //cart. Produkt mit Linkverschiebung - Set> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> { - Set> cardprodret= new Menge<>(); - if (y.size() > 0) { - //System.out.println(y); - //Menge> cardprodretold = x; - //cardprodret = new Menge<>(); - for(int j = 0; j < x.size(); j++) { - for (int k = 0; k < y.size(); k++){ - Set help = new Menge<>(); - help.addAll(y.elementAt(k)); - help.addAll(x.elementAt(j)); - cardprodret.add(help); - } - } - } - else - return new Menge<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis [] - return cardprodret; - }); - */ typinferenzLog.debug("\nUnifiziere Constraints:\n"+constraints, Section.TYPEINFERENCE); typinferenzLog.debug("\nFC:\n"+finiteClosure, Section.TYPEINFERENCE); long start = System.currentTimeMillis(); @@ -361,7 +414,7 @@ public class SourceFile long time = System.currentTimeMillis()-start; typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE); typinferenzLog.debug("\nAnzahl Lösungen:\n"+unifyResult.size(), Section.TYPEINFERENCE); - typinferenzLog.debug("\nZeit für Unifizierung: "+time + "ms", Section.TYPEINFERENCE); + //typinferenzLog.debug("\nZeit für Unifizierung: "+time + "ms", Section.TYPEINFERENCE); Menge> convertedResult = unifyResult.parallelStream().>map((Set resultSet)->{ diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java index 014500bc..33f32e07 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/ExtendsType.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Collection; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; @@ -81,4 +83,5 @@ public final class ExtendsType extends WildcardType { return "? extends " + wildcardedType; } + } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index 01102fca..e9268d0d 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -106,4 +108,12 @@ public final class PlaceholderType extends UnifyType{ return ((PlaceholderType) obj).getName().equals(typeName); } + + + @Override + public Collection getInvolvedPlaceholderTypes() { + ArrayList ret = new ArrayList<>(); + ret.add(this); + return ret; + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index 02edb933..31469ac4 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -1,6 +1,8 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import de.dhbwstuttgart.typeinference.Menge; @@ -168,5 +170,13 @@ public final class TypeParams implements Iterable{ res += t + ","; return "<" + res.substring(0, res.length()-1) + ">"; } + + public Collection getInvolvedPlaceholderTypes() { + ArrayList ret = new ArrayList<>(); + for(UnifyType t : typeParams){ + ret.addAll(t.getInvolvedPlaceholderTypes()); + } + return ret; + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java index 672a516d..988f9b7a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java @@ -1,5 +1,9 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + /** * A pair which contains two types and an operator, e.q. (Integer <. a). * @author Florian Steurer @@ -83,6 +87,13 @@ public class UnifyPair { public String toString() { return "(" + lhs + " " + pairOp + " " + rhs + ")"; } + + public List getInvolvedPlaceholderTypes() { + ArrayList ret = new ArrayList<>(); + ret.addAll(lhs.getInvolvedPlaceholderTypes()); + ret.addAll(rhs.getInvolvedPlaceholderTypes()); + return ret; + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java index 4f1965eb..56718198 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; @@ -87,4 +90,10 @@ public abstract class UnifyType { return typeName + params; } + + public Collection getInvolvedPlaceholderTypes() { + ArrayList ret = new ArrayList<>(); + ret.addAll(typeParams.getInvolvedPlaceholderTypes()); + return ret; + } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/WildcardType.java b/src/de/dhbwstuttgart/typeinference/unify/model/WildcardType.java index 9b42c087..2bc51460 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/WildcardType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/WildcardType.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.Collection; + /** * A wildcard type that is either a ExtendsType or a SuperType. * @author Florian Steurer @@ -53,4 +56,12 @@ public abstract class WildcardType extends UnifyType { WildcardType other = (WildcardType) obj; return other.getWildcardedType().equals(wildcardedType); } + + + @Override + public Collection getInvolvedPlaceholderTypes() { + ArrayList ret = new ArrayList<>(); + ret.addAll(wildcardedType.getInvolvedPlaceholderTypes()); + return ret; + } }