diff --git a/src/de/dhbwstuttgart/myexception/NotImplementedException.java b/src/de/dhbwstuttgart/myexception/NotImplementedException.java index bbaf52c6..d4e90ca1 100644 --- a/src/de/dhbwstuttgart/myexception/NotImplementedException.java +++ b/src/de/dhbwstuttgart/myexception/NotImplementedException.java @@ -2,6 +2,14 @@ package de.dhbwstuttgart.myexception; public class NotImplementedException extends RuntimeException { + public NotImplementedException(String message) { + super(message); + } + + public NotImplementedException() { + super("Nicht implementiert"); + } + /** * */ diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 301b73f1..11d5f8c5 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -269,8 +269,10 @@ public class SourceFile //oderConstraints.unifyUndConstraints(unifier); //rausgeworfen für Tests (08.12.2015) - typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE); - + typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE); + + typinferenzLog.debug("Übriggebliebene Konvertierte Konstraints:\n"+unifyConstraints+"\n", Section.TYPEINFERENCE); + //////////////// //Karthesisches Produkt bilden: //////////////// @@ -288,7 +290,7 @@ public class SourceFile boolean unifyFail = true; for(Set constraints : xConstraints){ //Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen: - Menge> result = new Menge>(); + //Menge> result = new Menge>(); //IDEE: Man bildet Zusammenhangskomponenten von Paaren, die gemeinsame Variablen haben // und unifizert nur die Zusammenhangskomponenten in Schritten 1 - 5 @@ -356,10 +358,21 @@ public class SourceFile return cardprodret; }); */ - Set> unifyResult = new Unify().unify(constraints, finiteClosure); + Set> unifyResult = new Unify().unify(constraints, finiteClosure); + + Menge> convertedResult = unifyResult.parallelStream().>map((Set resultSet)->{ + Menge innerConvert = resultSet.stream().map((MPair mp)->UnifyTypeFactory.convert(mp)) + .collect(Menge::new, Menge::add, Menge::addAll); + return innerConvert; + }).collect(Menge::new, Menge::add, Menge::addAll); + + Menge convertedConstraints = constraints.stream().map( + (MPair mp)->{return UnifyTypeFactory.convert(mp);} + ).collect(Menge::new, Menge::add, Menge::addAll); + //Dann den Ergebnissen anfügen typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE); - result.addAll(unifyResult); + //result.addAll(convertedResult); typinferenzLog.debug("\nJavaFiles:\n", Section.TYPEINFERENCE); @@ -369,10 +382,10 @@ public class SourceFile //Für jede Klasse in diesem SourceFile gilt das selbe ResultSet: for(Class klasse : this.KlassenVektor){ //Der Unifikationsalgorithmus kann wiederum auch mehrere Lösungen errechnen, diese werden im folgenden durchlaufen: - for(Menge resultSet : result){ + for(Menge resultSet : convertedResult){ unifyFail = false; //Ein Unifiziertes Ergebnis ist entstanden (es kann auch leer sein, das bedeutet nur, dass die Constraints mindestens in einem Fall Sinn ergaben) //Add Result set as a new ReconstructionResult to ret: - TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet(klasse, constraints, new ResultSet(resultSet)); + TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet(klasse, convertedConstraints, new ResultSet(resultSet)); ret.add(reconstructionResult); //ResultSet res = new ResultSet(resultSet); diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 9a53305b..51a895b4 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.util.HashSet; +import java.util.logging.Logger; import de.dhbwstuttgart.myexception.NotImplementedException; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; @@ -28,6 +29,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.MPair; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.SimpleType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; @@ -50,16 +52,19 @@ public class UnifyTypeFactory { } public static MPair smaller(UnifyType tl, UnifyType tr){ - return new MPair(tl, tr,MPair.PairOperator.SMALLER); + return new MPair(tl, tr, PairOperator.SMALLER); } public static UnifyType convert(Type t){ //Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist - if(t instanceof GenericTypeVar){ //WTF ? + if(t instanceof GenericTypeVar){ return UnifyTypeFactory.convert((GenericTypeVar)t); + }else if(t instanceof RefType){ + return UnifyTypeFactory.convert((RefType)t); + }else if(t instanceof TypePlaceholder){ + return UnifyTypeFactory.convert((TypePlaceholder)t); } - System.out.println("Der Typ "+t+" kann nicht umgewandelt werden"); - throw new NotImplementedException(); + throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden"); } public static UnifyType convert(RefType t){ @@ -122,4 +127,32 @@ public class UnifyTypeFactory { , UnifyTypeFactory.convert(p.getItem().TA2)); return ret; } + + public static Pair convert(MPair mp) { + Type tl = UnifyTypeFactory.convert(mp.getLhsType()); + Type tr = UnifyTypeFactory.convert(mp.getRhsType()); + return new Pair(tl, tr, mp.getPairOp()); + } + + public static Type convert(SimpleType t) { + return new RefType(t.getName(),null,0); + } + + public static Type convert(SuperType t) { + RefType innerType = new RefType(t.getSuperedType().getName(),null,0); + return new SuperWildcardType(innerType); + } + + public static Type convert(ExtendsType t) { + RefType innerType = new RefType(t.getExtendedType().getName(),null,0); + return new ExtendsWildcardType(innerType); + } + + public static Type convert(PlaceholderType t) { + return TypePlaceholder.getInstance(t.getName()); + } + + public static Type convert(UnifyType t) { + throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden"); + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java index 035d4c0a..d8f836ed 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java @@ -43,7 +43,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Block.java b/src/de/dhbwstuttgart/syntaxtree/statement/Block.java index a149a0cf..95ad0999 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Block.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Block.java @@ -37,7 +37,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/BoolLiteral.java b/src/de/dhbwstuttgart/syntaxtree/statement/BoolLiteral.java index 87be3f47..c04a8c68 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/BoolLiteral.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/BoolLiteral.java @@ -24,7 +24,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/CastExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/CastExpr.java index 0cc93bfe..db1f3fb7 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/CastExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/CastExpr.java @@ -25,7 +25,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/CharLiteral.java b/src/de/dhbwstuttgart/syntaxtree/statement/CharLiteral.java index 717b7d2a..c5398b08 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/CharLiteral.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/CharLiteral.java @@ -24,7 +24,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/DoubleLiteral.java b/src/de/dhbwstuttgart/syntaxtree/statement/DoubleLiteral.java index 7661bf86..dc8b83d3 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/DoubleLiteral.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/DoubleLiteral.java @@ -27,7 +27,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/EmptyStmt.java b/src/de/dhbwstuttgart/syntaxtree/statement/EmptyStmt.java index c80d67f3..2786749e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/EmptyStmt.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/EmptyStmt.java @@ -22,7 +22,6 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/IfStmt.java b/src/de/dhbwstuttgart/syntaxtree/statement/IfStmt.java index fb7ca5ce..51e535b6 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/IfStmt.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/IfStmt.java @@ -48,7 +48,6 @@ import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; -import de.dhbwstuttgart.typeinference.unify.MUB; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/IntLiteral.java b/src/de/dhbwstuttgart/syntaxtree/statement/IntLiteral.java index e593d448..725225c1 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/IntLiteral.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/IntLiteral.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index edf8eb33..5643f26e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -47,7 +47,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; /** * @author A10023 - Andreas Stadelmeier diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Literal.java b/src/de/dhbwstuttgart/syntaxtree/statement/Literal.java index bee299fe..21aa9f17 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Literal.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Literal.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree.statement; // ino.end import de.dhbwstuttgart.myexception.JVMCodeException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; // ino.class.Literal.25490.declaration public abstract class Literal extends Expr diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVar.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVar.java index f17ddcda..2c6debd6 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVar.java @@ -33,7 +33,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java index e03c1f81..579f77d2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java @@ -35,7 +35,6 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LongLiteral.java b/src/de/dhbwstuttgart/syntaxtree/statement/LongLiteral.java index a127eb4b..fa402791 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LongLiteral.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LongLiteral.java @@ -24,7 +24,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NegativeExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/NegativeExpr.java index fd5676fa..82a0cfec 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NegativeExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NegativeExpr.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewArray.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewArray.java index a42de638..953535bf 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NewArray.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewArray.java @@ -22,7 +22,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java index eefc048b..f39012c7 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java @@ -40,7 +40,6 @@ import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NotExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/NotExpr.java index c7b6dd99..8cf996db 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NotExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NotExpr.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Null.java b/src/de/dhbwstuttgart/syntaxtree/statement/Null.java index aa70e5d1..537aaad7 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Null.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Null.java @@ -24,7 +24,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/PositivExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/PositivExpr.java index 04cef0d5..10cd52f9 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/PositivExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/PositivExpr.java @@ -22,7 +22,6 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/PostDecExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/PostDecExpr.java index 9b80a94a..0893b076 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/PostDecExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/PostDecExpr.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/PostIncExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/PostIncExpr.java index 036a5b55..672e5cde 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/PostIncExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/PostIncExpr.java @@ -33,7 +33,6 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/PreDecExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/PreDecExpr.java index d8c3ecea..bce1dc97 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/PreDecExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/PreDecExpr.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/PreIncExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/PreIncExpr.java index 16ff6864..8ef55b9a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/PreIncExpr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/PreIncExpr.java @@ -28,7 +28,6 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java index d39204c8..73bb9f89 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java @@ -27,7 +27,6 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java index ef90282b..cc4d1c01 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java @@ -32,7 +32,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/This.java b/src/de/dhbwstuttgart/syntaxtree/statement/This.java index dc9b142b..0474e7ae 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/This.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/This.java @@ -32,7 +32,6 @@ import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java index 2bc329bf..e248583d 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java @@ -24,7 +24,6 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java b/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java index dd95b912..d96ed086 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java @@ -32,7 +32,6 @@ import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; -import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; import de.dhbwstuttgart.typeinference.unify.Unify; diff --git a/src/de/dhbwstuttgart/typeinference/ConstraintsSet.java b/src/de/dhbwstuttgart/typeinference/ConstraintsSet.java index 5728f1dc..7b611e2c 100755 --- a/src/de/dhbwstuttgart/typeinference/ConstraintsSet.java +++ b/src/de/dhbwstuttgart/typeinference/ConstraintsSet.java @@ -36,20 +36,22 @@ public class ConstraintsSet extends UndMenge implements Iterable uCons = this.filterUndConstraints(); Vector alleUndConstraints = new Vector<>(); @@ -67,7 +69,7 @@ public class ConstraintsSet extends UndMenge implements Iterable implements KomplexeMenge{ @@ -16,9 +18,9 @@ public class EinzelElement implements KomplexeMenge{ } @Override - public Menge> cartesianProduct() { + public Set> cartesianProduct() { Cloner cloner = new Cloner(); - Menge> ret = new Menge<>(); + Set> ret = new Menge<>(); Menge i = new Menge(); i.add(cloner.deepClone(item)); ret.add(i); diff --git a/src/de/dhbwstuttgart/typeinference/OderConstraint.java b/src/de/dhbwstuttgart/typeinference/OderConstraint.java index 7b88223e..e9187b39 100755 --- a/src/de/dhbwstuttgart/typeinference/OderConstraint.java +++ b/src/de/dhbwstuttgart/typeinference/OderConstraint.java @@ -90,7 +90,7 @@ public class OderConstraint extends OderMenge{ * Filtert die Constraints in diesem ODER-Verknüpften Constraint aus, * welche keinen Sinn ergeben, also beim unifizieren scheitern. * @param unifier - Wird für die Unifizierung benutzt - */ + void filterWrongConstraints(Unifier unifier) { Set filteredConstraints = new Menge<>(); for(UndConstraint cons : this.getUndConstraints()){ @@ -103,7 +103,6 @@ public class OderConstraint extends OderMenge{ } this.oderConstraintPairs = filteredConstraints; } - UndConstraint filterUndConstraints() { if(this.oderConstraintPairs.size()==1){ return this.oderConstraintPairs.firstElement(); @@ -111,6 +110,7 @@ public class OderConstraint extends OderMenge{ return null; } + */ @Override public Set> getSet() { return this.oderConstraintPairs; diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index dcb13958..a2aa42f0 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -11,10 +11,8 @@ import java.io.Serializable; import java.util.Hashtable; import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; // ino.end - - - import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.FreshWildcardType; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; @@ -43,9 +41,8 @@ public class Pair implements Serializable, DeepCloneable // ino.end // ino.attribute.bEqual.26549.declaration - private PairOperator eOperator = PairOperator.Smaller; + private PairOperator eOperator = PairOperator.SMALLER; - public enum PairOperator { Smaller, SmallerExtends, Equal }; // ino.end // ino.attribute.bSubst.26552.decldescription type=line // false <--> vorinitialisierter Wert @@ -79,7 +76,7 @@ public class Pair implements Serializable, DeepCloneable this.TA1 = TA1; this.TA2 = TA2; bSubst = false; - eOperator = PairOperator.Smaller; + eOperator = PairOperator.SMALLER; } // ino.end @@ -342,7 +339,7 @@ public class Pair implements Serializable, DeepCloneable */ public boolean OperatorEqual() { - return eOperator == PairOperator.Equal; + return eOperator == PairOperator.EQUALS; } /** @@ -351,7 +348,7 @@ public class Pair implements Serializable, DeepCloneable */ public boolean OperatorSmaller() { - return eOperator == PairOperator.Smaller; + return eOperator == PairOperator.SMALLER; } /** @@ -360,7 +357,7 @@ public class Pair implements Serializable, DeepCloneable */ public boolean OperatorSmallerExtends() { - return eOperator == PairOperator.SmallerExtends; + return eOperator == PairOperator.SMALLERDOTWC; } /** diff --git a/src/de/dhbwstuttgart/typeinference/UndConstraint.java b/src/de/dhbwstuttgart/typeinference/UndConstraint.java index 741667f3..35468bd7 100755 --- a/src/de/dhbwstuttgart/typeinference/UndConstraint.java +++ b/src/de/dhbwstuttgart/typeinference/UndConstraint.java @@ -22,13 +22,13 @@ public class UndConstraint extends UndMenge { return set; } - public Menge getConstraintPairs() { - Menge> ret = this.cartesianProduct(); + public Set getConstraintPairs() { + Set> ret = this.cartesianProduct(); if(ret.size() != 1){ //UndConstraints enthalten nur SingleConstraints, wodurch das Karthesische Produkt nur aus einem Element bestehen kann. throw new DebugException("Fehler in ConstraintPairs-Bildung"); } - return ret.firstElement(); + return ret.iterator().next(); } public void addConstraint(Type type, Type rT) { diff --git a/src/de/dhbwstuttgart/typeinference/UndMenge.java b/src/de/dhbwstuttgart/typeinference/UndMenge.java index 146121d7..fa300765 100644 --- a/src/de/dhbwstuttgart/typeinference/UndMenge.java +++ b/src/de/dhbwstuttgart/typeinference/UndMenge.java @@ -14,7 +14,6 @@ public abstract class UndMenge implements KomplexeMenge{ @Override public Set> cartesianProduct() { Set> ret = null; - //Cloner cloner = new Cloner(); for(KomplexeMenge km : this.getSet()){ if(ret == null){ ret = km.cartesianProduct(); @@ -22,7 +21,7 @@ public abstract class UndMenge implements KomplexeMenge{ Set> cartesianProduct = new Menge<>(); for(Set r : ret)for(Set m : km.cartesianProduct()){ //Für jedes Element aus dem Karthesischen Produkt: Set undElement = new Menge(); - undElement.addAll(Unify.deepClone(r)); + undElement.addAll(r); undElement.addAll(m); cartesianProduct.add(undElement); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java index b411e7fe..da29a58f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java @@ -11,7 +11,7 @@ import java.util.stream.Collectors; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.model.MPair; -import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; @@ -26,7 +26,7 @@ public class MartelliMontanariUnify implements IUnify { @Override public Optional unify(Set terms) { if(terms.size() < 2) - return Optional.of(Unifier.IDENTITY); + return Optional.of(Unifier.Identity()); ArrayList termsQ = new ArrayList(); Iterator iter = terms.iterator(); @@ -37,7 +37,7 @@ public class MartelliMontanariUnify implements IUnify { prev = next; } - Unifier mgu = Unifier.IDENTITY; + Unifier mgu = Unifier.Identity(); int idx = 0; while(idx < termsQ.size()) { @@ -101,8 +101,12 @@ public class MartelliMontanariUnify implements IUnify { TypeParams rhsTypeParams = rhs.getTypeParams(); TypeParams lhsTypeParams = lhs.getTypeParams(); - if(!rhs.getName().equals(lhs.getName()) || rhsTypeParams.size() != lhsTypeParams.size()) - return null; // conflict + if(!(rhs instanceof PlaceholderType) && !(lhs instanceof PlaceholderType)) { + if(!rhs.getName().equals(lhs.getName())) + return null; // conflict + if(rhsTypeParams.size() != lhsTypeParams.size()) + return null; // conflict; + } if(rhsTypeParams.size() == 0 || lhsTypeParams.size() == 0) return Optional.empty(); diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index 51616be3..0461a0fc 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -14,6 +14,7 @@ import junit.framework.Assert; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; +import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.SimpleType; @@ -84,26 +85,27 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - UnifyType lhsType = pair.getLhsType(); - - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) + + UnifyType x = pair.getLhsType(); + + if(!(x instanceof SimpleType) && !(x instanceof ExtendsType)) return Optional.empty(); - - UnifyType rhsType = pair.getRhsType(); - - if(!(rhsType instanceof ExtendsType)) + + UnifyType extY = pair.getRhsType(); + + if(!(extY instanceof ExtendsType)) return Optional.empty(); - if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) + if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsType, rhsType); + int[] pi = pi(x, extY); if(pi.length == 0) return Optional.empty(); - TypeParams rhsTypeParams = rhsType.getTypeParams(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams rhsTypeParams = extY.getTypeParams(); + TypeParams lhsTypeParams = x.getTypeParams(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) @@ -159,7 +161,7 @@ public class RuleSet implements IRuleSet{ if(!rhsType.getName().equals(lhsType.getName())) return Optional.empty(); - if(rhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) + if(rhsType instanceof PlaceholderType || lhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) return Optional.empty(); if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) @@ -327,16 +329,16 @@ public class RuleSet implements IRuleSet{ if(typeD.getName().equals(typeDs.getName())) return Optional.empty(); - Optional opt = finiteClosure.getGenericType(typeD.getName()); - + + Optional opt = finiteClosure.getLeftHandedType(typeD); if(!opt.isPresent()) return Optional.empty(); - // The generic Version of Type D (D) + // The generic Version of Type D (D) UnifyType typeDgen = opt.get(); - + // Actually greater+ because the types are ensured to have different names - Set greater = finiteClosure.greater(typeDgen); + Set greater = finiteClosure.getAncestors(typeDgen); opt = greater.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) @@ -349,7 +351,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); } @@ -372,9 +374,9 @@ public class RuleSet implements IRuleSet{ UnifyType typeDgen; if(typeD instanceof SimpleType) - typeDgen = finiteClosure.getGenericType(typeD.getName()).orElse(null); - else { - Optional opt = finiteClosure.getGenericType(((ExtendsType) typeD).getExtendedType().getName()); + typeDgen = finiteClosure.getLeftHandedType(typeD).orElse(null); + else { + Optional opt = finiteClosure.getLeftHandedType(((ExtendsType) typeD).getExtendedType()); typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null; } @@ -395,7 +397,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC)); } @@ -416,8 +418,8 @@ public class RuleSet implements IRuleSet{ if(typeDs.getTypeParams().size() == 0 || typeSupD.getTypeParams().size() == 0) return Optional.empty(); - - Optional opt = finiteClosure.getGenericType(((SuperType) typeSupD).getSuperedType().getName()); + + Optional opt = finiteClosure.getLeftHandedType(((SuperType) typeSupD).getSuperedType()); if(!opt.isPresent()) return Optional.empty(); @@ -447,7 +449,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC)); } @@ -457,45 +459,29 @@ public class RuleSet implements IRuleSet{ * @param C The type which arguments are permuted * @param D The other type * @return An array containing the values of pi for every type argument of C or an empty array if the search failed. - */ + */ private int[] pi(UnifyType C, UnifyType D) { - UnifyType cFromFc = null; - if(C instanceof SimpleType) - cFromFc = finiteClosure.getGenericType(C.getName()).orElse(null); - else if(C instanceof ExtendsType) { - Optional opt = finiteClosure.getGenericType(((ExtendsType) C).getExtendedType().getName()); - if(opt.isPresent()) cFromFc = new ExtendsType(opt.get()); - } - else if(C instanceof SuperType) { - Optional opt = finiteClosure.getGenericType(((SuperType) C).getSuperedType().getName()); - if(opt.isPresent()) cFromFc = new SuperType(opt.get()); - } + String simpleTypeDName = D.getName(); + if(D instanceof ExtendsType) + simpleTypeDName = ((ExtendsType) D).getExtendedType().getName(); + else if(D instanceof SuperType) + simpleTypeDName = ((SuperType) D).getSuperedType().getName(); - if(cFromFc == null) + String simpleTypeCName = C.getName(); + if(C instanceof ExtendsType) + simpleTypeCName = ((ExtendsType) C).getExtendedType().getName(); + if(C instanceof SuperType) + simpleTypeCName = ((SuperType) C).getSuperedType().getName(); + + Optional typesFromFc = Optional.empty(); //TODO reduce regeln + //finiteClosure.findCandD(simpleTypeCName, simpleTypeDName); + + if(typesFromFc == null) return new int[0]; - Optional opt = Optional.empty(); - if(D instanceof ExtendsType) { - SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); - opt = finiteClosure.grArg(cFromFc).stream() - .filter(x -> x instanceof ExtendsType) - .filter(x -> ((ExtendsType) x).getExtendedType().getName().equals(dSType.getName())).findAny(); - } - else if(D instanceof SuperType) { - SimpleType dSType = (SimpleType) ((SuperType) D).getSuperedType(); - opt = finiteClosure.grArg(cFromFc).stream() - .filter(x -> x instanceof SuperType) - .filter(x -> ((SuperType) x).getSuperedType().getName().equals(dSType.getName())).findAny(); - } - else if (D instanceof SimpleType) - opt = finiteClosure.greater(cFromFc).stream() - .filter(x -> x.getName().equals(D.getName())).findAny(); - - if(!opt.isPresent()) - return new int[0]; - - UnifyType dFromFc = opt.get(); - + UnifyType cFromFc = typesFromFc.get()[0]; + UnifyType dFromFc = typesFromFc.get()[1]; + Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); Assert.assertTrue(dFromFc.getTypeParams().size() > 0); @@ -559,4 +545,182 @@ public class RuleSet implements IRuleSet{ return applied ? Optional.of(new HashSet<>(result)) : Optional.empty(); } + + @Override + public Optional reduceWildcardLow(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardLowRight(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if((lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardUp(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardUpRight(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if((lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardLowUp(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), ((SuperType) rhsType).getSuperedType(), PairOperator.EQUALSDOT)); + } + + @Override + public Optional reduceWildcardUpLow(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + if(!(lhsType instanceof SuperType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT)); + } + + @Override + public Optional reduceWildcardLeft(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + UnifyType rhsType = pair.getRhsType(); + if((rhsType instanceof SuperType) || (rhsType instanceof ExtendsType)) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + + if(lhsType instanceof SuperType) + return Optional.of(new MPair(((SuperType) lhsType).getSuperedType(), rhsType, PairOperator.EQUALSDOT)); + + if(lhsType instanceof ExtendsType) + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.EQUALSDOT)); + + return Optional.empty(); + } + + @Override + public Optional> reduceFunN(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + + if(!(lhsType instanceof FunNType) || !(rhsType instanceof FunNType)) + return Optional.empty(); + + FunNType funNLhsType = (FunNType) lhsType; + FunNType funNRhsType = (FunNType) rhsType; + + if(funNLhsType.getN() != funNRhsType.getN()) + return Optional.empty(); + + Set result = new HashSet(); + + result.add(new MPair(funNLhsType.getTypeParams().get(0), funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); + for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) + result.add(new MPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); + + return Optional.of(result); + } + + @Override + public Optional> greaterFunN(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + + if(!(lhsType instanceof FunNType) || !(rhsType instanceof PlaceholderType)) + return Optional.empty(); + + FunNType funNLhsType = (FunNType) lhsType; + + Set result = new HashSet(); + + UnifyType[] freshPlaceholders = new UnifyType[funNLhsType.getTypeParams().size()]; + for(int i = 0; i < freshPlaceholders.length; i++) + freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); + + result.add(new MPair(funNLhsType.getTypeParams().get(0), freshPlaceholders[0], PairOperator.SMALLERDOT)); + for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) + result.add(new MPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); + result.add(new MPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); + + return Optional.of(result); + } + + @Override + public Optional> smallerFunN(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + + if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof FunNType)) + return Optional.empty(); + + FunNType funNRhsType = (FunNType) rhsType; + + Set result = new HashSet(); + + UnifyType[] freshPlaceholders = new UnifyType[funNRhsType.getTypeParams().size()]; + for(int i = 0; i < freshPlaceholders.length; i++) + freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); + + result.add(new MPair(freshPlaceholders[0], funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); + for(int i = 1; i < funNRhsType.getTypeParams().size(); i++) + result.add(new MPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT)); + result.add(new MPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); + + return Optional.of(result); + } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 1f9b4fb4..54ca107c 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -4,6 +4,7 @@ import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; +import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.SimpleType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; @@ -45,11 +46,16 @@ public interface IFiniteClosure { public Set grArg(SuperType type); public Set smArg(SuperType type); - + public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); - - public Optional getGenericType(String typeName); + + public Set grArg(FunNType type); + public Set smArg(FunNType type); + + public Optional getLeftHandedType(UnifyType t); + public Set getAncestors(UnifyType t); + public Set getAllTypesByName(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index 840d7259..23c444e0 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -16,6 +16,24 @@ public interface IRuleSet { public Optional> reduce1(MPair pair); public Optional> reduce2(MPair pair); + /* + * Missing Rules + */ + public Optional reduceWildcardLow(MPair pair); + public Optional reduceWildcardLowRight(MPair pair); + public Optional reduceWildcardUp(MPair pair); + public Optional reduceWildcardUpRight(MPair pair); + public Optional reduceWildcardLowUp(MPair pair); + public Optional reduceWildcardUpLow(MPair pair); + public Optional reduceWildcardLeft(MPair pair); + + /* + * FunN Rules + */ + public Optional> reduceFunN(MPair pair); + public Optional> greaterFunN(MPair pair); + public Optional> smallerFunN(MPair pair); + public boolean erase1(MPair pair); public boolean erase2(MPair pair); public boolean erase3(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 3fb48ac9..f04ccfcd 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -4,27 +4,29 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; - + +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; -import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; public class FiniteClosure implements IFiniteClosure { - + private HashMap> inheritanceGraph; private HashMap>> strInheritanceGraph; - - public FiniteClosure() { - - } + private Set pairs; + private Set basicTypes; + //TODO im konstruktor mitgeben um typenabzuhandeln die keine extends beziehung haben. (Damit die FC diese Typen auch kennt) + //(ALternative: immer die extends zu object beziehung einfügen) public FiniteClosure(Set pairs) { - - inheritanceGraph = new HashMap>(); + this.pairs = new HashSet<>(pairs); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { @@ -62,117 +64,148 @@ public class FiniteClosure implements IFiniteClosure { /** * Returns all types of the finite closure that are subtypes of the argument. * @return The set of subtypes of the argument. - */ - @Override + */ + @Override public Set smaller(UnifyType type) { - // - if(T < T') then T <=* T' - Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : new HashSet<>(); - - result.add(type); - - // if T1 <=* T2 then sigma1(T1) <=* sigma1(T2) - // where foreach type var a in T2: - // sigma1(T1) <=* sigma2(T2) - /*if(strInheritanceGraph.containsKey(type.getName())) { - IUnify unify = new MartelliMontanariUnify(); - HashSet> candidateNodes = strInheritanceGraph.get(type.getName()); - for(Node candidateNode : candidateNodes) { - Type theta2 = candidateNode.getContent(); - Optional sigma2 = unify.unify(theta2, type); - if(!sigma2.isPresent()) - continue; - for(Type sigma1theta1 : candidateNode.getContentOfDescendants()) { - Type theta1 = sigma2.get().apply(sigma1theta1); - } - } - }*/ - - if(type.getTypeParams().size() == 0) - return result; - - ArrayList> paramCandidates = new ArrayList<>(); - for(UnifyType param : type.getTypeParams()) { - if(param instanceof ExtendsType || param instanceof SuperType) { - Set pc = param.smArg(this); - paramCandidates.add(pc); - } else { - HashSet pc = new HashSet<>(); - pc.add(param); - paramCandidates.add(pc); - } - } + if(inheritanceGraph.containsKey(type)) { + Set result = new HashSet<>(); + result.add(type); + result.addAll(inheritanceGraph.get(type).getContentOfDescendants()); + return result; + } + + IUnify unify = new MartelliMontanariUnify(); + Set result1 = new HashSet<>(); + // if T = T' then T <=* T' + result1.add(type); + + {ArrayList> paramCandidates = new ArrayList<>(); + for (UnifyType param : type.getTypeParams()) + paramCandidates.add(smArg(param)); + Set permResult = new HashSet<>(); permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]); - - for(TypeParams newParams : permResult) - result.add(type.setTypeParams(newParams)); - - return result; - } - - /** - * @param t1 - * @param t2 - * @return - */ - protected Optional match(UnifyType t1, UnifyType t2) { - if(!t1.getName().equals(t2.getName())) - return Optional.empty(); - - TypeParams t1Params = t1.getTypeParams(); - TypeParams t2Params = t2.getTypeParams(); - - if(t1Params.size() != t2Params.size()) - return Optional.empty(); - - Unifier result = new Unifier(); - for(int i = 0; i < t1Params.size(); i++) { - UnifyType t1i = t1Params.get(i); - UnifyType t2i = t2Params.get(i); + + for (TypeParams newParams : permResult) + result1.add(type.setTypeParams(newParams));} + + Set result2 = new HashSet<>(); + if (strInheritanceGraph.containsKey(type.getName())) { + HashSet candidates = new HashSet<>(); + strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); - boolean equal = t1i.equals(t2i); - if(!equal && !(t2i instanceof PlaceholderType)) - return Optional.empty(); - - if(!equal && t2i instanceof PlaceholderType) - result.Add((PlaceholderType) t2i, t1i); + for(UnifyType typePrime : result1) { + for (UnifyType theta2 : candidates) { + Optional sigma2 = unify.unify(typePrime, theta2); + if (!sigma2.isPresent()) + continue; + if(type.equals(theta2)) + continue; + Set theta1s = smaller(theta2); + for (UnifyType theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + UnifyType sigma1Theta1 = sigma2.get().apply(theta1); + result2.add(sigma1Theta1); + } + } + } } + else + result2 = result1; - return Optional.of(result); + Set result3 = new HashSet<>(); + for(UnifyType t : result2) { + ArrayList> paramCandidates = new ArrayList<>(); + for (UnifyType param : t.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]); + + for (TypeParams newParams : permResult) { + UnifyType tPrime = t.setTypeParams(newParams); + if(tPrime.equals(t)) + result3.add(t); + else + result3.addAll(smaller(tPrime)); + } + + } + + return result3; } /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. - */ - @Override - public Set greater(UnifyType type) { - Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfPredecessors() : new HashSet<>(); - result.add(type); - - if(type.getTypeParams().size() == 0) - return result; + */ + @Override + public Set greater(UnifyType type) { + IUnify unify = new MartelliMontanariUnify(); + Set result1 = new HashSet<>(); - ArrayList> paramCandidates = new ArrayList<>(); - for(UnifyType param : type.getTypeParams()) { - if(param instanceof ExtendsType || param instanceof SuperType) { - Set pc = param.grArg(this); - paramCandidates.add(pc); - } else { - HashSet pc = new HashSet<>(); - pc.add(param); - paramCandidates.add(pc); + if(inheritanceGraph.containsKey(type)) + result1.addAll(inheritanceGraph.get(type).getContentOfPredecessors()); + + // if T = T' then T <=* T' + result1.add(type); + + {ArrayList> paramCandidates = new ArrayList<>(); + for (UnifyType param : type.getTypeParams()) + paramCandidates.add(grArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]); + + for (TypeParams newParams : permResult) + result1.add(type.setTypeParams(newParams));} + + Set result2 = new HashSet<>(); + if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) { + HashSet candidates = new HashSet<>(); + strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); + + for(UnifyType typePrime : result1) { + for (UnifyType theta2 : candidates) { + Optional sigma2 = unify.unify(typePrime, theta2); + if (!sigma2.isPresent()) + continue; + if(type.equals(theta2)) + continue; + Set theta1s = greater(theta2); + for (UnifyType theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + UnifyType sigma1Theta1 = sigma2.get().apply(theta1); + result2.add(sigma1Theta1); + } + } } } - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]); + result2.addAll(result1); - for(TypeParams newParams : permResult) - result.add(type.setTypeParams(newParams)); + Set result3 = new HashSet<>(); + for(UnifyType t : result2) { + ArrayList> paramCandidates = new ArrayList<>(); + for (UnifyType param : t.getTypeParams()) + paramCandidates.add(grArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]); + + for (TypeParams newParams : permResult) { + UnifyType tPrime = t.setTypeParams(newParams); + if(tPrime.equals(t)) + result3.add(t); + else + result3.addAll(greater(tPrime)); + } + + } + + return result3; - return result; } @Override @@ -180,12 +213,9 @@ public class FiniteClosure implements IFiniteClosure { return type.grArg(this); } - @Override + @Override public Set grArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - - Set result = new HashSet(); + Set result = new HashSet(); result.add(type); smaller(type).forEach(x -> result.add(new SuperType(x))); @@ -194,11 +224,13 @@ public class FiniteClosure implements IFiniteClosure { return result; } + @Override + public Set grArg(FunNType type) { + throw new NotImplementedException(); + } + @Override public Set grArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -209,15 +241,12 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); - result.add(type); + result.add(type); - UnifyType t = type.getSuperedType(); + UnifyType t = type.getSuperedType(); smaller(t).forEach(x -> result.add(new SuperType(x))); @@ -227,9 +256,9 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(PlaceholderType type) { HashSet result = new HashSet<>(); - result.add(type); - result.add(new SuperType(type)); - result.add(new ExtendsType(type)); + result.add(type); + //result.add(new SuperType(type)); + //result.add(new ExtendsType(type)); return result; } @@ -238,25 +267,23 @@ public class FiniteClosure implements IFiniteClosure { return type.smArg(this); } - @Override + @Override public Set smArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - - Set result = new HashSet(); + Set result = new HashSet(); result.add(type); - smaller(type).forEach(x -> result.add(new ExtendsType(x))); - return result; + } + + @Override + public Set smArg(FunNType type) { + throw new NotImplementedException(); } - + + @Override public Set smArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); - result.add(type); + result.add(type); UnifyType t = type.getExtendedType(); @@ -270,11 +297,8 @@ public class FiniteClosure implements IFiniteClosure { } - @Override + @Override public Set smArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -292,26 +316,23 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); - result.add(type); - result.add(new SuperType(type)); - result.add(new ExtendsType(type)); - return result; + result.add(type); + return result; } - @Override - public Optional getGenericType(String typeName) { - if(!strInheritanceGraph.containsKey(typeName)) - return Optional.empty(); + + public boolean isGenericType(UnifyType t) { + if(t.getTypeParams().size() == 0) + return true; - HashSet> candidates = strInheritanceGraph.get(typeName); + if(!strInheritanceGraph.containsKey(t.getName())) + return false; - for(Node node : candidates) { - UnifyType candidate = node.getContent(); - if(candidate.getTypeParams().arePlaceholders()) - return Optional.of(candidate); - } + for(MPair pair : pairs) + if(pair.getLhsType().equals(t)) + return true; - return Optional.empty(); + return false; } @Override @@ -320,8 +341,27 @@ public class FiniteClosure implements IFiniteClosure { return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } + + @Override + public Optional getLeftHandedType(UnifyType t) { + if(!strInheritanceGraph.containsKey(t.getName())) + return Optional.empty(); + + for(MPair pair : pairs) + if(pair.getLhsType().getName().equals(t.getName())) + return Optional.of(pair.getLhsType()); + + return Optional.empty(); + } - protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { + @Override + public Set getAncestors(UnifyType t) { + if(!inheritanceGraph.containsKey(t)) + return new HashSet<>(); + return inheritanceGraph.get(t).getContentOfPredecessors(); + } + + protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); return; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java new file mode 100644 index 00000000..e62fd6ce --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java @@ -0,0 +1,44 @@ +package de.dhbwstuttgart.typeinference.unify.model; + +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + +public class FunNType extends UnifyType { + + public FunNType(TypeParams p) { + super("FuN", p); + if(p.size() == 0) + throw new IllegalArgumentException("Function types need at least one type parameter"); + } + + @Override + public UnifyType setTypeParams(TypeParams newTp) { + if(newTp.size() == 0) + throw new IllegalArgumentException("Function types need at least one type parameter"); + return new FunNType(newTp); + } + + public int getN() { + return typeParams.size()-1; + } + + @Override + Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } + + @Override + UnifyType apply(Unifier unif) { + // TODO Auto-generated method stub + return null; + } + + // TODO equals und hashcode + +} diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java index d7d17d52..dc4aa142 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/MPair.java @@ -1,30 +1,6 @@ package de.dhbwstuttgart.typeinference.unify.model; public class MPair { - - public enum PairOperator { - SMALLER, - SMALLERDOT, - SMALLERDOTWC, - EQUALS, - EQUALSDOT; - - @Override - public String toString() { - switch (this) { - case SMALLER: - return "<"; - case SMALLERDOT: - return "<."; - case SMALLERDOTWC: - return "<.?"; - case EQUALS: - return "="; - default: - return "=."; - } - }; - } private UnifyType lhs; private UnifyType rhs; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java b/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java new file mode 100644 index 00000000..0f55be30 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PairOperator.java @@ -0,0 +1,25 @@ +package de.dhbwstuttgart.typeinference.unify.model; + +public enum PairOperator { + SMALLER, + SMALLERDOT, + SMALLERDOTWC, + EQUALS, + EQUALSDOT; + + @Override + public String toString() { + switch (this) { + case SMALLER: + return "<"; + case SMALLERDOT: + return "<."; + case SMALLERDOTWC: + return "<.?"; + case EQUALS: + return "="; + default: + return "=."; + } + }; +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index f810e993..55da2325 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -1,13 +1,36 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; public final class PlaceholderType extends UnifyType{ + protected static final HashSet EXISTING_PLACEHOLDERS = new HashSet(); + protected static String nextName = "gen_"; + public PlaceholderType(String name) { super(name); + EXISTING_PLACEHOLDERS.add(name); + } + + public static PlaceholderType freshPlaceholder() { + String name = nextName + randomChar(); + + while(EXISTING_PLACEHOLDERS.contains(name)); + nextName += randomChar(); + + return new PlaceholderType(name); + } + + /** + * Returns random char between 'a' and 'z' + */ + private static char randomChar() { + return (char) (new Random().nextInt(22) + 97); } @Override diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index 294df4b4..0f39a621 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -2,7 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.Arrays; import java.util.Iterator; - + import de.dhbwstuttgart.typeinference.Menge; public final class TypeParams implements Iterable{ @@ -15,7 +15,7 @@ public final class TypeParams implements Iterable{ } } - public TypeParams(UnifyType... types) { + public TypeParams(UnifyType... types) { typeParams = types; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index aab24276..971566e6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -9,10 +9,8 @@ import java.util.function.Function; public class Unifier implements Function /*, Set*/ { // TODO set implementieren private HashMap substitutions = new HashMap<>(); - - public static Unifier IDENTITY = new Unifier(); - - public Unifier(PlaceholderType source, UnifyType target) { + + public Unifier(PlaceholderType source, UnifyType target) { substitutions.put(source, target); } @@ -22,8 +20,12 @@ public class Unifier implements Function /*, Set*/ public Unifier() { } + + public static Unifier Identity() { + return new Unifier(); + } - public void Add(PlaceholderType source, UnifyType target) { + public void Add(PlaceholderType source, UnifyType target) { Unifier tempU = new Unifier(source, target); for(PlaceholderType pt : substitutions.keySet()) substitutions.put(pt, substitutions.get(pt).apply(tempU)); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java new file mode 100644 index 00000000..5dd89a21 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -0,0 +1,491 @@ +package de.dhbwstuttgart.typeinference.unifynew; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.Pair; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; +import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations; +import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; +import de.dhbwstuttgart.typeinference.unify.RuleSet; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; +import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; +import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; +import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; +import de.dhbwstuttgart.typeinference.unify.model.MPair; +import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; +import de.dhbwstuttgart.typeinference.unify.model.SuperType; +import de.dhbwstuttgart.typeinference.unify.model.UnifyType; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; +import de.dhbwstuttgart.typeinference.unify.model.TypeParams; +import de.dhbwstuttgart.typeinference.unify.model.Unifier; + + +/** + * Implementation of the type unification algorithm + * @author Florian Steurer + */ +public class Unify { + + public Set> unify(Set eq, IFiniteClosure fc) { + /* + * Step 1: Repeated application of reduce, adapt, erase, swap + */ + + Set eq0 = applyTypeUnificationRules(eq, fc); + + /* + * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs + */ + + Set eq1s = new HashSet<>(); + Set eq2s = new HashSet<>(); + splitEq(eq0, eq1s, eq2s); + + /* + * Step 4: Create possible typings + * + * "Manche Autoren identifizieren die Paare (a, (b,c)) und ((a,b),c) + * mit dem geordneten Tripel (a,b,c), wodurch das kartesische Produkt auch assoziativ wird." - Wikipedia + */ + + // There are up to 10 toplevel set. 8 of 10 are the result of the + // cartesian product of the sets created by pattern matching. + List>> topLevelSets = new ArrayList<>(); + + if(eq1s.size() != 0) { + Set> wrap = new HashSet<>(); + wrap.add(eq1s); + topLevelSets.add(wrap); // Add Eq1' + } + + // Add the set of [a =. Theta | (a=. Theta) in Eq2'] + Set bufferSet = eq2s.stream() + .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) + .collect(Collectors.toSet()); + + if(bufferSet.size() != 0) { + Set> wrap = new HashSet<>(); + wrap.add(bufferSet); + topLevelSets.add(wrap); + } + + // Sets that originate from pair pattern matching + // Sets of the "second level" + Set>> secondLevelSets = calculatePairSets(eq2s, fc); + + /* Up to here, no cartesian products are calculated. + * filters for pairs and sets can be applied here */ + + ISetOperations setOps = new GuavaSetOperations(); + + // Sub cartesian products of the second level (pattern matched) sets + for(Set> secondLevelSet : secondLevelSets) { + List> secondLevelSetList = new ArrayList<>(secondLevelSet); + topLevelSets.add(setOps.cartesianProduct(secondLevelSetList) + .stream().map(x -> new HashSet<>(x)) + .collect(Collectors.toCollection(HashSet::new))); + } + + // Cartesian product over all (up to 10) top level sets + Set>> eqPrimeSet = setOps.cartesianProduct(topLevelSets) + .stream().map(x -> new HashSet<>(x)) + .collect(Collectors.toCollection(HashSet::new)); + //System.out.println(result); + + /* + * Step 5: Substitution + */ + + /* + * TODO hier das ergebnis schonh flach machen? (wird im unify old (glaub ich) so gemacht) + */ + Set> eqPrimeSetFlat = new HashSet<>(); + for(Set> setToFlatten : eqPrimeSet) { + Set buffer = new HashSet<>(); + setToFlatten.stream().forEach(x -> buffer.addAll(x)); + eqPrimeSetFlat.add(buffer); + } + + IRuleSet rules = new RuleSet(fc); + Set> changed = new HashSet<>(); + Set> eqPrimePrimeSet = new HashSet<>(); + + for(Set eqPrime : eqPrimeSetFlat) { + Optional> eqPrimePrime = rules.subst(eqPrime); + + if(eqPrimePrime.isPresent()) + changed.add(eqPrimePrime.get()); + else + eqPrimePrimeSet.add(eqPrime); + } + + /* + * Step 6 a) Restart for pairs where subst was applied + * b) Build the union over everything + */ + + for(Set eqss : changed) { + eqPrimePrimeSet.addAll(this.unify(eqss, fc)); + } + + /* + * Step 7: Filter result for solved pairs + */ + return eqPrimePrimeSet; + + } + + protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { + + /* + * Rule Application Strategy: + * + * 1. Swap all pairs and erase all erasable pairs + * 2. Apply all possible rules to a single pair, then move it to the result set. + * Iterating over pairs first, then iterating over rules prevents the application + * of rules to a "finished" pair over and over. + * 2.1 Apply all rules repeatedly except for erase rules. If + * the application of a rule creates new pairs, check immediately + * against the erase rules. + */ + + + LinkedHashSet targetSet = new LinkedHashSet(); + LinkedList eqQueue = new LinkedList<>(); + IRuleSet rules = new RuleSet(fc); + + /* + * Swap all pairs and erase all erasable pairs + */ + eq.forEach(x -> swapAddOrErase(x, rules, eqQueue)); + + /* + * Apply rules until the queue is empty + */ + while(!eqQueue.isEmpty()) { + MPair pair = eqQueue.pollFirst(); + + // ReduceUp, ReduceLow, ReduceUpLow + Optional opt = rules.reduceUpLow(pair); + opt = opt.isPresent() ? opt : rules.reduceLow(pair); + opt = opt.isPresent() ? opt : rules.reduceUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLow(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLowRight(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair); + + // One of the rules has been applied + if(opt.isPresent()) { + swapAddOrErase(opt.get(), rules, eqQueue); + continue; + } + + // Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq + Optional> optSet = rules.reduce1(pair); + optSet = optSet.isPresent() ? optSet : rules.reduce2(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceSup(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceEq(pair); + + // One of the rules has been applied + if(optSet.isPresent()) { + optSet.get().forEach(x -> swapAddOrErase(x, rules, eqQueue)); + continue; + } + + // Adapt, AdaptExt, AdaptSup + opt = rules.adapt(pair); + opt = opt.isPresent() ? opt : rules.adaptExt(pair); + opt = opt.isPresent() ? opt : rules.adaptSup(pair); + + // One of the rules has been applied + if(opt.isPresent()) { + swapAddOrErase(opt.get(), rules, eqQueue); + continue; + } + + // None of the rules has been applied + targetSet.add(pair); + } + + return targetSet; + } + + protected void swapAddOrErase(MPair pair, IRuleSet rules, Collection collection) { + Optional opt = rules.swap(pair); + MPair pair2 = opt.isPresent() ? opt.get() : pair; + + if(rules.erase1(pair2) || rules.erase3(pair2) || rules.erase2(pair2)) + return; + + collection.add(pair2); + } + + protected void splitEq(Set eq, Set eq1s, Set eq2s) { + for(MPair pair : eq) + if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) + eq1s.add(pair); + else + eq2s.add(pair); + } + + + protected Set>> calculatePairSets(Set eq2s, IFiniteClosure fc) { + List>> result = new ArrayList<>(); + + // Init all 8 cases + for(int i = 0; i < 8; i++) + result.add(new HashSet<>()); + + for(MPair pair : eq2s) { + + PairOperator pairOp = pair.getPairOp(); + UnifyType lhsType = pair.getLhsType(); + UnifyType rhsType = pair.getRhsType(); + + // Case 1: (a <. Theta') + if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) + result.get(0).add(unifyCase1((PlaceholderType) pair.getLhsType(), pair.getRhsType(), fc)); + + // Case 2: (a <.? ? ext Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType) + result.get(1).add(unifyCase2((PlaceholderType) pair.getLhsType(), (ExtendsType) pair.getRhsType(), fc)); + + // Case 3: (a <.? ? sup Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType) + result.get(2).add(unifyCase3((PlaceholderType) lhsType, (SuperType) rhsType, fc)); + + // Case 4: (a <.? Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType) + result.get(3).add(unifyCase4((PlaceholderType) lhsType, rhsType, fc)); + + // Case 5: (Theta <. a) + else if(pairOp == PairOperator.SMALLERDOT && rhsType instanceof PlaceholderType) + result.get(4).add(unifyCase5(lhsType, (PlaceholderType) rhsType, fc)); + + // Case 6: (? ext Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof ExtendsType && rhsType instanceof PlaceholderType) + result.get(5).add(unifyCase6((ExtendsType) lhsType, (PlaceholderType) rhsType, fc)); + + // Case 7: (? sup Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof SuperType && rhsType instanceof PlaceholderType) + result.get(6).add(unifyCase7((SuperType) lhsType, (PlaceholderType) rhsType, fc)); + + // Case 8: (Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType) + result.get(7).add(unifyCase8(lhsType, (PlaceholderType) rhsType, fc)); + } + + return result.stream().filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new)); + } + + protected Set unifyCase1(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) { + Set result = new HashSet<>(); + IUnify unify = new MartelliMontanariUnify(); + + Set cs = fc.getAllTypesByName(thetaPrime.getName()); + + for(UnifyType c : cs) { + + // Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig? + Set thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); + thetaQs.add(c); // reflexive + + Set thetaQPrimes = new HashSet<>(); + TypeParams cParams = c.getTypeParams(); + if(cParams.size() == 0) + thetaQPrimes.add(c); + else { + ArrayList> candidateParams = new ArrayList<>(); + for(UnifyType param : cParams) + candidateParams.add(fc.grArg(param)); + + for(TypeParams tp : permuteParams(candidateParams)) + thetaQPrimes.add(c.setTypeParams(tp)); + } + + for(UnifyType tqp : thetaQPrimes) { + Optional opt = unify.unify(tqp, thetaPrime); + if (!opt.isPresent()) + continue; + + Unifier unifier = opt.get(); + Set> substitutions = unifier.getSubstitutions(); + for (Entry sigma : substitutions) + result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); + for (UnifyType tq : thetaQs) { + Set smaller = fc.smaller(unifier.apply(tq)); + smaller.stream().map(x -> new MPair(a, x, PairOperator.EQUALSDOT)) + .forEach(x -> result.add(x)); + } + + } + } + + return result; + } + + protected Set unifyCase2(PlaceholderType a, ExtendsType extThetaPrime, IFiniteClosure fc) { + Set result = new HashSet<>(); + IUnify unify = new MartelliMontanariUnify(); + + UnifyType thetaPrime = extThetaPrime.getExtendedType(); + Set cs = fc.getAllTypesByName(thetaPrime.getName()); + + for(UnifyType c : cs) { + + // Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig? + Set thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); + thetaQs.add(c); // reflexive + + Set thetaQPrimes = new HashSet<>(); + TypeParams cParams = c.getTypeParams(); + if(cParams.size() == 0) + thetaQPrimes.add(c); + else { + ArrayList> candidateParams = new ArrayList<>(); + for(UnifyType param : cParams) + candidateParams.add(fc.grArg(param)); + + for(TypeParams tp : permuteParams(candidateParams)) + thetaQPrimes.add(c.setTypeParams(tp)); + } + + for(UnifyType tqp : thetaQPrimes) { + Optional opt = unify.unify(tqp, thetaPrime); + if (!opt.isPresent()) + continue; + + Unifier unifier = opt.get(); + Set> substitutions = unifier.getSubstitutions(); + for (Entry sigma : substitutions) + result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); + for (UnifyType tq : thetaQs) { + ExtendsType extTq = new ExtendsType(tq); + Set smaller = fc.smaller(unifier.apply(extTq)); + smaller.stream().map(x -> new MPair(a, x, PairOperator.EQUALSDOT)) + .forEach(x -> result.add(x)); + } + + } + } + + return result; + } + + protected Set unifyCase3(PlaceholderType a, SuperType subThetaPrime, IFiniteClosure fc) { + Set result = new HashSet<>(); + for(UnifyType theta : fc.smArg(subThetaPrime)) + result.add(new MPair(a, theta, PairOperator.EQUALSDOT)); + return result; + } + + protected Set unifyCase4(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) { + Set result = new HashSet<>(); + result.add(new MPair(a, thetaPrime, PairOperator.EQUALSDOT)); + return result; + } + + protected Set unifyCase5(UnifyType theta, PlaceholderType a, IFiniteClosure fc) { + Set result = new HashSet<>(); + for(UnifyType thetaS : fc.greater(theta)) + result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT)); + return result; + } + + protected Set unifyCase6(ExtendsType extTheta, PlaceholderType a, IFiniteClosure fc) { + Set result = new HashSet<>(); + for(UnifyType thetaS : fc.grArg(extTheta)) + result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT)); + return result; + } + + protected Set unifyCase7(SuperType supTheta, PlaceholderType a, IFiniteClosure fc) { + Set result = new HashSet<>(); + IUnify unify = new MartelliMontanariUnify(); + + UnifyType theta = supTheta.getSuperedType(); + Set cs = fc.getAllTypesByName(theta.getName()); + + for(UnifyType c : cs) { + + // Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig? + Set thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new)); + thetaQs.add(c); // reflexive + + Set thetaQPrimes = new HashSet<>(); + TypeParams cParams = c.getTypeParams(); + if(cParams.size() == 0) + thetaQPrimes.add(c); + else { + ArrayList> candidateParams = new ArrayList<>(); + for(UnifyType param : cParams) + candidateParams.add(fc.grArg(param)); + + for(TypeParams tp : permuteParams(candidateParams)) + thetaQPrimes.add(c.setTypeParams(tp)); + } + + for(UnifyType tqp : thetaQPrimes) { + Optional opt = unify.unify(tqp, theta); + if (!opt.isPresent()) + continue; + + Unifier unifier = opt.get(); + Set> substitutions = unifier.getSubstitutions(); + for (Entry sigma : substitutions) + result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); + for (UnifyType tq : thetaQs) { + Set smaller = fc.smaller(unifier.apply(tq)); + smaller.stream().map(x -> new MPair(a, new SuperType(x), PairOperator.EQUALSDOT)) + .forEach(x -> result.add(x)); + } + + } + } + + return result; + } + + protected Set unifyCase8(UnifyType theta, PlaceholderType a, IFiniteClosure fc) { + Set result = new HashSet<>(); + for(UnifyType thetaS : fc.grArg(theta)) + result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT)); + return result; + } + + protected Set permuteParams(ArrayList> candidates) { + Set result = new HashSet<>(); + permuteParams(candidates, 0, result, new UnifyType[candidates.size()]); + return result; + } + + private void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { + if(candidates.size() == idx) { + result.add(new TypeParams(Arrays.copyOf(current, current.length))); + return; + } + + Set localCandidates = candidates.get(idx); + + for(UnifyType t : localCandidates) { + current[idx] = t; + permuteParams(candidates, idx+1, result, current); + } + } +} diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index 30831a89..69ff63be 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -28,6 +28,7 @@ public class FiniteClosureBuilder { public IFiniteClosure getCollectionExample() { TypeFactory tf = new TypeFactory(); +<<<<<<< HEAD UnifyType collection = tf.getSimpleType("Collection"); UnifyType set = tf.getSimpleType("Set", "T"); UnifyType sortedSet = tf.getSimpleType("Set", "T"); @@ -41,10 +42,28 @@ public class FiniteClosureBuilder { UnifyType vector = tf.getSimpleType("Vector", "T"); UnifyType stack = tf.getSimpleType("Stack", "T"); UnifyType arrayList = tf.getSimpleType("ArrayList", "T"); +======= + /* Collection */ + + Type collection = tf.getSimpleType("Collection"); + Type set = tf.getSimpleType("Set", "T"); + //Type sortedSet = tf.getSimpleType("SortedSet", "T"); Sorted set bei den Unit-Tests vergessen + // nachträgliches einfügen zu aufwendig + Type TreeSet = tf.getSimpleType("TreeSet", "T"); + Type hashSet = tf.getSimpleType("HashSet", "T"); + Type linkedHashSet = tf.getSimpleType("LinkedHashSet", "T"); + Type queue = tf.getSimpleType("Queue", "T"); + Type deque = tf.getSimpleType("Deque", "T"); + Type linkedList = tf.getSimpleType("LinkedList", "T"); + Type list = tf.getSimpleType("List", "T"); + Type vector = tf.getSimpleType("Vector", "T"); + Type stack = tf.getSimpleType("Stack", "T"); + Type arrayList = tf.getSimpleType("ArrayList", "T"); +>>>>>>> unify add(set, collection); - add(sortedSet, set); - add(TreeSet, sortedSet); + //add(sortedSet, set); + add(TreeSet, set); add(hashSet, set); add(linkedHashSet, set); @@ -57,6 +76,22 @@ public class FiniteClosureBuilder { add(arrayList, list); add(stack, vector); + /* Map */ + Type map = tf.getSimpleType("Map", "K", "V"); + Type sortedMap = tf.getSimpleType("SortedMap", "K", "V"); + Type navigableMap = tf.getSimpleType("NavigableMap", "K", "V"); + Type treeMap = tf.getSimpleType("TreeMap", "K", "V"); + Type hashMap = tf.getSimpleType("HashMap", "K", "V"); + Type hashtable = tf.getSimpleType("Hashtable", "K", "V"); + Type linkedHashMap = tf.getSimpleType("LinkedHashMap", "K", "V"); + + add(sortedMap, map); + add(hashMap, map); + add(hashtable, map); + add(navigableMap, sortedMap); + add(treeMap, navigableMap); + add(linkedHashMap, hashMap); + IFiniteClosure fc = getFiniteClosure(); clear(); return fc; diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 314bed58..6ac50fe0 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -1,48 +1,636 @@ package unify; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + import org.junit.Assert; import org.junit.Test; -import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; -public class FiniteClosureTest extends FiniteClosure { +public class FiniteClosureTest { @Test - public void testMatch() { + public void testSmaller() { TypeFactory tf = new TypeFactory(); + + UnifyType integer = tf.getSimpleType("Integer"); + UnifyType number = tf.getSimpleType("Number"); - UnifyType a = tf.getPlaceholderType("a"); - UnifyType b = tf.getPlaceholderType("b"); - UnifyType c = tf.getPlaceholderType("c"); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + fcb.add(integer, number); + fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer"))); + fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection")); + IFiniteClosure fc = fcb.getCollectionExample(); + + /* + * Test Case 1: + * + * smaller(Set) = { HashSet, Set, LinkedHashSet } + */ - UnifyType A = tf.getSimpleType("A"); - UnifyType B = tf.getSimpleType("B"); - UnifyType C1 = tf.getSimpleType("C", a, b, c); - UnifyType C2 = tf.getSimpleType("C", a, A, b); - UnifyType C3 = tf.getSimpleType("C", A, B, A); - UnifyType D1 = tf.getSimpleType("D", C1, a, b, c); - UnifyType D2 = tf.getSimpleType("D", C3, A, B, A); + UnifyType setInt = tf.getSimpleType("Set", integer); + UnifyType hashSetInt = tf.getSimpleType("HashSet", integer); + UnifyType treeSetInt = tf.getSimpleType("TreeSet", integer); + UnifyType linkedHashSetInt = tf.getSimpleType("LinkedHashSet", integer); - System.out.println(match(C2, C1)); - System.out.println(match(C3, C1)); - System.out.println(match(D2, D1)); - Assert.assertFalse(match(C3, C2).isPresent()); - Assert.assertFalse(match(C1, C2).isPresent()); + Set expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setInt)); + + /* + * Test Case 2: + * + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + UnifyType extInt = tf.getExtendsType(integer); + UnifyType hashSetExtInt = tf.getSimpleType("HashSet", extInt); + UnifyType treeSetExtInt = tf.getSimpleType("TreeSet", extInt); + UnifyType linkedHashSetExtInt = tf.getSimpleType("LinkedHashSet", extInt); + UnifyType setExtInt = tf.getSimpleType("Set", extInt); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + hashSetExtInt, treeSetExtInt, linkedHashSetExtInt, setExtInt, + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtInt)); + + /* + * Test Case 3: + * + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet + * HashSet } + */ + + UnifyType hashSetNum = tf.getSimpleType("HashSet", number); + UnifyType treeSetNum = tf.getSimpleType("TreeSet", number); + UnifyType linkedHashSetNum = tf.getSimpleType("LinkedHashSet", number); + UnifyType setNum = tf.getSimpleType("Set", number); + + UnifyType extNum = tf.getExtendsType(number); + UnifyType hashSetExtNum = tf.getSimpleType("HashSet", extNum); + UnifyType treeSetExtNum = tf.getSimpleType("TreeSet", extNum); + UnifyType linkedHashSetExtNum = tf.getSimpleType("LinkedHashSet", extNum); + UnifyType setExtNum = tf.getSimpleType("Set", extNum); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + setNum, hashSetNum, linkedHashSetNum, treeSetNum, + setExtInt, hashSetExtInt, linkedHashSetExtInt, treeSetExtInt, + setExtNum, hashSetExtNum, linkedHashSetExtNum, treeSetExtNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtNum)); + + /* + * Test Case 4: + * TODO ist das ergebnis korrekt oder müssen die ? ext Ts raus weil der allgemeienste Typ T ausreicht? + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + UnifyType t = tf.getPlaceholderType("T"); + UnifyType setT = tf.getSimpleType("Set", t); + UnifyType hashSetT = tf.getSimpleType("HashSet", t); + UnifyType treeSetT = tf.getSimpleType("TreeSet", t); + UnifyType linkedHashSetT = tf.getSimpleType("LinkedHashSet", t); + UnifyType hashSetExtT = tf.getSimpleType("HashSet", t); + UnifyType treeSetExtT = tf.getSimpleType("TreeSet", t); + UnifyType linkedHashSetExtT = tf.getSimpleType("LinkedHashSet", t); + UnifyType setExtT = tf.getSimpleType("Set", t); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setT, hashSetT, treeSetT, linkedHashSetT, + setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setT)); + + /* + * Test Case 5 + * + * smaller(Set = + * { Set, HashSet, TreeSet, LinkedHashSet, + * Set, HashSet, TreeSet, LinkedHashSet, + * Set, HashSet, TreeSet, LinkedHashSet } + */ + + UnifyType superNum = tf.getSuperType(number); + UnifyType superInt = tf.getSuperType(integer); + + UnifyType setSupInt = tf.getSimpleType("Set", superInt); + UnifyType hashSetSupInt = tf.getSimpleType("HashSet", superInt); + UnifyType linkedHashSetSupInt = tf.getSimpleType("LinkedHashSet", superInt); + UnifyType treeSetSupInt = tf.getSimpleType("TreeSet", superInt); + UnifyType setSupNum = tf.getSimpleType("Set", superNum); + UnifyType hashSetSupNum = tf.getSimpleType("HashSet", superNum); + UnifyType linkedHashSetSupNum = tf.getSimpleType("LinkedHashSet", superNum); + UnifyType treeSetSupNum = tf.getSimpleType("TreeSet", superNum); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setSupInt, hashSetSupInt, linkedHashSetSupInt, treeSetSupInt, + setSupNum, hashSetSupNum, linkedHashSetSupNum, treeSetSupNum, + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + setNum, hashSetNum, linkedHashSetNum, treeSetNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setSupInt)); + + /* + * Test Case 6: + * + * smaller(Set, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + * + */ + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setT, hashSetT, treeSetT, linkedHashSetT, + setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtT)); + + /* + * Test Case 7: + * + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + UnifyType notInFc = tf.getSimpleType("notInFC"); + UnifyType setNotInFc = tf.getSimpleType("Set", notInFc); + UnifyType hashSetNotInFc = tf.getSimpleType("HashSet", notInFc); + UnifyType treeSetNotInFc = tf.getSimpleType("TreeSet", notInFc); + UnifyType linkedHashSetNotInFc = tf.getSimpleType("LinkedHashSet", notInFc); + UnifyType hashSetExtNotInFc = tf.getSimpleType("HashSet", notInFc); + UnifyType treeSetExtNotInFc = tf.getSimpleType("TreeSet", notInFc); + UnifyType linkedHashSetExtNotInFc = tf.getSimpleType("LinkedHashSet", notInFc); + UnifyType setExtNotInFc = tf.getSimpleType("Set", notInFc); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setNotInFc, hashSetNotInFc, treeSetNotInFc, linkedHashSetNotInFc, + setExtNotInFc, hashSetExtNotInFc, treeSetExtNotInFc, linkedHashSetExtNotInFc + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setNotInFc)); + + /* + * Test Case 8: + * + * smaller(Set) = + * { Set, HashSet, LinkedHashSet, TreeSet, + * Set, HashSet, LinkedHashSet, TreeSet } + */ + + UnifyType superNotInFc = tf.getSuperType(notInFc); + UnifyType setSuperNotInFc = tf.getSimpleType("Set", superNotInFc); + UnifyType hashSetSuperNotInFc = tf.getSimpleType("HashSet", superNotInFc); + UnifyType treeSetSuperNotInFc = tf.getSimpleType("TreeSet", superNotInFc); + UnifyType linkedHashSetSuperNotInFc = tf.getSimpleType("LinkedHashSet", superNotInFc); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + setNotInFc, hashSetNotInFc, treeSetNotInFc, linkedHashSetNotInFc, + setSuperNotInFc, hashSetSuperNotInFc, treeSetSuperNotInFc, linkedHashSetSuperNotInFc + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setSuperNotInFc)); + + /* + * Test Case 8: + * + * smaller(NotInFc) = + * { NotInFc, NotInFc, NotInFc, NotInFc } + */ + + UnifyType notInFcExtNumber = tf.getSimpleType("NotInFc", extNum); + UnifyType notInFcInteger = tf.getSimpleType("NotInFc", integer); + UnifyType notInFcNumber = tf.getSimpleType("NotInFc", number); + UnifyType notInFcExtInt = tf.getSimpleType("NotInFc", extInt); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + notInFcExtNumber, notInFcInteger, notInFcNumber, notInFcExtInt + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(notInFcExtNumber)); + + /* + * Test Case 9: + * + * smaller(NotInFc = + * { NotInFc, NotInFc } + */ + + UnifyType alsoNotInFc = tf.getSimpleType("AlsoNotInFc"); + UnifyType notInFcAlsoNotInFc = tf.getSimpleType("NotInFc", alsoNotInFc); + UnifyType notInFcSupAlsoNotInFc = tf.getSimpleType("NotInFc", tf.getSuperType(alsoNotInFc)); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + notInFcAlsoNotInFc, notInFcSupAlsoNotInFc + }).collect(Collectors.toSet())); + + Set actual = fc.smaller(notInFcSupAlsoNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 10: + * + * smaller(TreeMap) = + * { TreeMap, TreeMap, TreeMap, TreeMap + * TreeMap, TreeMap, TreeMap, TreeMap, + * TreeMap, TreeMap, TreeMap + * TreeMap, TreeMap, TreeMap, TreeMap } + */ + + UnifyType treeMapExtNumSupInt = tf.getSimpleType("TreeMap", extNum, superInt); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + treeMapExtNumSupInt, tf.getSimpleType("TreeMap", extNum, superNum), tf.getSimpleType("TreeMap", extNum, integer), tf.getSimpleType("TreeMap", extNum, number), + tf.getSimpleType("TreeMap", number, superInt), tf.getSimpleType("TreeMap", number, superNum), tf.getSimpleType("TreeMap", number, integer), tf.getSimpleType("TreeMap", number, number), + tf.getSimpleType("TreeMap", integer, superInt), tf.getSimpleType("TreeMap", integer, superNum), tf.getSimpleType("TreeMap", integer, integer), tf.getSimpleType("TreeMap", integer, number), + tf.getSimpleType("TreeMap", extInt, superInt), tf.getSimpleType("TreeMap", extInt, superNum), tf.getSimpleType("TreeMap", extInt, integer), tf.getSimpleType("TreeMap", extInt, number) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapExtNumSupInt); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 11: + * + * smaller(SortedMap) = { SortedMap, NavigableMap, TreeMap } + */ + + UnifyType sortedMapNumberT = tf.getSimpleType("SortedMap", number, t); + UnifyType navigableMapNumberT = tf.getSimpleType("NavigableMap", number, t); + UnifyType treeMapNumberT = tf.getSimpleType("TreeMap", number, t); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedMapNumberT, navigableMapNumberT, treeMapNumberT + }).collect(Collectors.toSet())); + + actual = fc.smaller(sortedMapNumberT); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 12: + * + * MyMap <* TreeMap> + * + * smaller(TreeMap) = { TreeMap>, MyMap } + */ + + fcb = new FiniteClosureBuilder(); + UnifyType k = tf.getPlaceholderType("K"); + UnifyType myMap = tf.getSimpleType("MyMap", k); + fcb.add(myMap, tf.getSimpleType("TreeMap", k, tf.getSimpleType("List", k))); + fcb.add(integer, number); + fc = fcb.getCollectionExample(); + + UnifyType treeMapNumberListNumber = tf.getSimpleType("TreeMap", number, tf.getSimpleType("List", number)); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + treeMapNumberListNumber, + tf.getSimpleType("MyMap", number) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapNumberListNumber); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 13: + * + * MyMap <* TreeMap> + * + * smaller(TreeMap) = + * { TreeMap, List>, + * TreeMap>, + * TreeMap>, + * TreeMap>, + * MyMap } + */ + + UnifyType listInteger = tf.getSimpleType("List", integer); + UnifyType treeMapExtNumberListInteger = tf.getSimpleType("TreeMap", extNum, listInteger); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + treeMapExtNumberListInteger, + tf.getSimpleType("TreeMap", extInt, listInteger), + tf.getSimpleType("TreeMap", number, listInteger), + tf.getSimpleType("TreeMap", integer, listInteger), + tf.getSimpleType("MyMap", integer) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapExtNumberListInteger); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 14 + * + * MyMap <* TreeMap> + * + * smaller(TreeMap) = + * { TreeMap, List>, + * TreeMap>, + * TreeMap>, + * TreeMap>, + * MyMap + * MyMap + * MyMap + * MyMap + */ + + UnifyType listExtNum = tf.getSimpleType("List", extNum); + UnifyType treeMapExtNumListExtNum = tf.getSimpleType("TreeMap", extNum, listExtNum); + UnifyType myMapInt = tf.getSimpleType("MyMap", integer); + UnifyType myMapNumber = tf.getSimpleType("MyMap", number); + UnifyType myMapExtInt = tf.getSimpleType("MyMap", extInt); + UnifyType myMapExtNum = tf.getSimpleType("MyMap", extNum); + + actual = fc.smaller(treeMapExtNumListExtNum); + + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + tf.getSimpleType("TreeMap", extNum, listExtNum), + tf.getSimpleType("TreeMap", extInt, listExtNum), + tf.getSimpleType("TreeMap", number, listExtNum), + tf.getSimpleType("TreeMap", integer, listExtNum), + myMapInt, myMapNumber, myMapExtInt, myMapExtNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 15: + * + * MyMap <* TreeMap> + * + * smaller(NavigableSet>) = + * { Permutationen der List, + * Permutationen der List in TreeSets, + * MyMap und MyMap + * } + */ + + UnifyType navSet = tf.getSimpleType("NavigableMap", extInt, tf.getExtendsType(tf.getSimpleType("List", extInt))); + + actual = fc.smaller(navSet); + + Assert.assertEquals(82, actual.size()); + Assert.assertTrue(actual.contains(myMapExtInt)); + Assert.assertTrue(actual.contains(myMapInt)); } @Test public void testGreater() { - IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + UnifyType k = tf.getPlaceholderType("K"); + UnifyType integer = tf.getSimpleType("Integer"); + UnifyType number = tf.getSimpleType("Number"); + UnifyType myMap = tf.getSimpleType("MyMap", k); + UnifyType myIntMap = tf.getSimpleType("MyIntMap"); + UnifyType collection = tf.getSimpleType("Collection"); + UnifyType sortedSet =tf.getSimpleType("SortedSet", "T"); + UnifyType extInt = tf.getExtendsType(integer); + UnifyType extNum = tf.getExtendsType(number); + UnifyType supInt = tf.getSuperType(integer); + UnifyType supNum = tf.getSuperType(number); + fcb.add(myMap, tf.getSimpleType("Map", k, tf.getSimpleType("List", k))); + fcb.add(myIntMap, tf.getSimpleType("MyMap", integer)); + fcb.add(sortedSet, tf.getSimpleType("Set", "T")); // sortedSet < Set missing in collection example + fcb.add(integer, number); + IFiniteClosure fc = fcb.getCollectionExample(); + + /* + * Test Case 1: + * + * greater(SortedSet) = + * { SortedSet, Set, Collection + * SortedSet, SortedSet, SortedSet, + * Set, Set, Set } + */ - System.out.println("\n\n----- Greater Test -----"); - System.out.println("Greater(LinkedList) = " + fc.greater(tf.getSimpleType("LinkedList", "T"))); - System.out.println("Greater(TreeSet) = " + fc.greater(tf.getSimpleType("TreeSet", "T"))); - System.out.println("Greater(Collection) = " + fc.greater(tf.getSimpleType("Collection"))); + UnifyType sortedSetInteger = tf.getSimpleType("SortedSet", integer); + Set expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetInteger, tf.getSimpleType("Set", integer), collection, + tf.getSimpleType("SortedSet", extInt), tf.getSimpleType("SortedSet", supInt), + tf.getSimpleType("SortedSet", extNum), tf.getSimpleType("Set", extInt), + tf.getSimpleType("Set", supInt), tf.getSimpleType("Set", extNum) + }).collect(Collectors.toSet())); + + Set actual = fc.greater(sortedSetInteger); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 2: + * + * greater(SortedSet) = + * { SortedSet, SortedSet, + * Set, Set, Collection } + */ + + UnifyType sortedSetExtInt = tf.getSimpleType("SortedSet", extInt); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetExtInt, tf.getSimpleType("SortedSet", extNum), collection, + tf.getSimpleType("Set", extInt), tf.getSimpleType("Set", extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetExtInt); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 3: + * + * TODO hier extends und super? (siehe test case 4 bei smaller) + * greater(SortedSet) = + * { SortedSet, SortedSet, SortedSet, + * Set, Set, Set, Collection } + */ + + /* + * Test Case 4: + * + * greater(SortedSet) = + * { SortedSet, SortedSet + * Set, Set, Collection } + */ + + UnifyType sortedSetSupNum = tf.getSimpleType("SortedSet", supNum); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetSupNum, tf.getSimpleType("SortedSet", supInt), collection, + tf.getSimpleType("Set", supNum), tf.getSimpleType("Set", supInt) + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetSupNum); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 5: + * + * TODO nicht unifizierbar bei T wenn Set deklariert wurde. Können die beiden T's verschieden sein? + * greater(SortedSet) = + * { SortedSet, Set, Collection } + */ + + UnifyType extT = tf.getExtendsType(tf.getPlaceholderType("T1")); + UnifyType sortedSetExtT = tf.getSimpleType("SortedSet", extT); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetExtT, tf.getSimpleType("Set", extT), collection, + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetExtT); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 6: + * + * greater(SortedSet) = + * { SortedSet, SortedSet, SortedSet, + * Set, Set, Set, Collection } + */ + + UnifyType notInFc = tf.getSimpleType("NotInFc"); + UnifyType extNotInFc = tf.getExtendsType(notInFc); + UnifyType supNotInFc = tf.getSuperType(notInFc); + UnifyType sortedSetNotInFc= tf.getSimpleType("SortedSet", notInFc); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetNotInFc, tf.getSimpleType("SortedSet", extNotInFc), tf.getSimpleType("SortedSet", supNotInFc), + tf.getSimpleType("Set", notInFc), tf.getSimpleType("Set", extNotInFc), tf.getSimpleType("Set", supNotInFc), + collection + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 7: + * + * greater(SortedSet, Set, Collection } + */ + + UnifyType sortedSetSupNotInFc= tf.getSimpleType("SortedSet", supNotInFc); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + sortedSetSupNotInFc, tf.getSimpleType("Set", supNotInFc), collection + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetSupNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 8: + * + * greater(NotInFc) = + * { NotInFc, NotInFc, NotInFC, + * NotInFc } + */ + + UnifyType notInFcInteger = tf.getSimpleType("NotInFc", integer); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + notInFcInteger, tf.getSimpleType("NotInFc", supInt), + tf.getSimpleType("NotInFc", extInt), tf.getSimpleType("NotInFc", extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(notInFcInteger); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 9: + * greater(NotInFc) = + * { NotInFc, NotInFc } + */ + + UnifyType notInFcAlsoNotInFc = tf.getSimpleType("NotInFc", tf.getSimpleType("AlsoNotInFc")); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + notInFcAlsoNotInFc, tf.getSimpleType("NotInFc", tf.getExtendsType(tf.getSimpleType("AlsoNotInFc"))), + tf.getSimpleType("NotInFc", tf.getSuperType(tf.getSimpleType("AlsoNotInFc"))) + }).collect(Collectors.toSet())); + + actual = fc.greater(notInFcAlsoNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 10: + * greater(Map) = + * { Map, Map, + * Map, Map, + * Map, Map, + * Map, Map } + */ + + UnifyType mapExtIntInt = tf.getSimpleType("Map", extInt, integer); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + mapExtIntInt, tf.getSimpleType("Map", extInt, extInt), + tf.getSimpleType("Map", extInt, supInt), tf.getSimpleType("Map", extInt, extNum), + tf.getSimpleType("Map", extNum, integer), tf.getSimpleType("Map", extNum, extInt), + tf.getSimpleType("Map", extNum, supInt), tf.getSimpleType("Map", extNum, extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(mapExtIntInt); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 11: + * + * MyIntMap < MyMap + * MyMap < Map> + * + * greater(MyIntMap) = + * { MyMap, MyMap, MyMap, MyMap, + * Map, Map, List, + * Map, List, Map, MyIntMap } + */ + + UnifyType listInteger = tf.getSimpleType("List", integer); + expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] { + myIntMap, tf.getSimpleType("MyMap", integer), tf.getSimpleType("MyMap", extInt), + tf.getSimpleType("MyMap", extNum), tf.getSimpleType("MyMap", supInt), + tf.getSimpleType("Map", integer, listInteger), tf.getSimpleType("Map", extInt, listInteger), + tf.getSimpleType("MyMap", extNum, listInteger), tf.getSimpleType("MyMap", supInt, listInteger) + }).collect(Collectors.toSet())); + + actual = fc.greater(myIntMap); + //Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 12: + * + * MyIntMap < MyMap + * MyMap < Map> + * + * TODO + * D d = null; + * A> a = null; + * a = d; ist nicht möglich! + * + * greater(MyMap) = + * { MyMap, MyMap, + * Map>, + * Map, List> } + */ + + /* + * Test Case 13: + * + * greater(SortedMap, ? super List>) = + * + */ } @Test @@ -56,20 +644,6 @@ public class FiniteClosureTest extends FiniteClosure { System.out.println("GrArg(? super List) = " + fc.grArg(tf.getSuperType(tf.getSimpleType("List", "T")))); } - @Test - public void testSmaller() { - FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - TypeFactory tf = new TypeFactory(); - - fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); - IFiniteClosure fc = fcb.getCollectionExample(); - - System.out.println("\n\n----- Smaller Test -----"); - System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", tf.getExtendsType(tf.getSimpleType("Number"))))); - System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", "T"))); - System.out.println("Smaller(TreeSet) = " + fc.smaller(tf.getSimpleType("TreeSet", "T"))); - System.out.println("Smaller(Collection) = " + fc.smaller(tf.getSimpleType("Collection"))); - } @Test public void testSmArg() { @@ -87,4 +661,12 @@ public class FiniteClosureTest extends FiniteClosure { // TODO } + + private void printDiff(Set expected, Set actual) { + System.out.println("Diff:"); + System.out.println("In expected but not in actual:"); + Set expected1 = new HashSet<>(expected); + expected1.removeAll(actual); + System.out.println(expected1); + } }