forked from JavaTX/JavaCompilerCore
Merge mit Unify und Einbinden der neuen Unifizierung. Nich lauffähige Version
This commit is contained in:
commit
e2d384e7f9
@ -2,6 +2,14 @@ package de.dhbwstuttgart.myexception;
|
||||
|
||||
public class NotImplementedException extends RuntimeException {
|
||||
|
||||
public NotImplementedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotImplementedException() {
|
||||
super("Nicht implementiert");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -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<MPair> constraints : xConstraints){
|
||||
//Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen:
|
||||
Menge<Menge<Pair>> result = new Menge<Menge<Pair>>();
|
||||
//Menge<Menge<Pair>> result = new Menge<Menge<Pair>>();
|
||||
|
||||
//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<Set<MPair>> unifyResult = new Unify().unify(constraints, finiteClosure);
|
||||
Set<Set<MPair>> unifyResult = new Unify().unify(constraints, finiteClosure);
|
||||
|
||||
Menge<Menge<Pair>> convertedResult = unifyResult.parallelStream().<Menge<Pair>>map((Set<MPair> resultSet)->{
|
||||
Menge<Pair> innerConvert = resultSet.stream().map((MPair mp)->UnifyTypeFactory.convert(mp))
|
||||
.collect(Menge<Pair>::new, Menge::add, Menge::addAll);
|
||||
return innerConvert;
|
||||
}).collect(Menge::new, Menge::add, Menge::addAll);
|
||||
|
||||
Menge<Pair> convertedConstraints = constraints.stream().map(
|
||||
(MPair mp)->{return UnifyTypeFactory.convert(mp);}
|
||||
).collect(Menge<Pair>::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<Pair> resultSet : result){
|
||||
for(Menge<Pair> 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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -36,20 +36,22 @@ public class ConstraintsSet extends UndMenge<Pair> implements Iterable<OderConst
|
||||
return constraintsSet.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
public void filterWrongConstraints(Unifier unify) {
|
||||
/*
|
||||
* Das ConstraintsSet enthält nur OderConstraints, welche UND-Verknüpft sind.
|
||||
* Hier werden Constraints in den OderConstraints kontrolliert:
|
||||
*/
|
||||
|
||||
// * Das ConstraintsSet enthält nur OderConstraints, welche UND-Verknüpft sind.
|
||||
// * Hier werden Constraints in den OderConstraints kontrolliert:
|
||||
|
||||
for(OderConstraint constraint : this){
|
||||
constraint.filterWrongConstraints(unify);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Nimmt alle UndConstraints und filtert mithilfe dieser die falschen Constraints aus den OderConstraints
|
||||
* @param unifier
|
||||
*/
|
||||
|
||||
public void unifyUndConstraints(Unifier unifier) {
|
||||
Vector<UndConstraint> uCons = this.filterUndConstraints();
|
||||
Vector<Pair> alleUndConstraints = new Vector<>();
|
||||
@ -67,7 +69,7 @@ public class ConstraintsSet extends UndMenge<Pair> implements Iterable<OderConst
|
||||
return unifyResult;
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Aus dem ConstraintsSet [ u1, u2, ... (OderConstraint), ... uN ] werden alle
|
||||
* UndConstraints, welche sich nicht innerhalb eines OderConstraints befinden, herausgefiltert
|
||||
|
@ -1,5 +1,7 @@
|
||||
package de.dhbwstuttgart.typeinference;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public class EinzelElement<A> implements KomplexeMenge<A>{
|
||||
@ -16,9 +18,9 @@ public class EinzelElement<A> implements KomplexeMenge<A>{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Menge<Menge<A>> cartesianProduct() {
|
||||
public Set<Set<A>> cartesianProduct() {
|
||||
Cloner cloner = new Cloner();
|
||||
Menge<Menge<A>> ret = new Menge<>();
|
||||
Set<Set<A>> ret = new Menge<>();
|
||||
Menge<A> i = new Menge<A>();
|
||||
i.add(cloner.deepClone(item));
|
||||
ret.add(i);
|
||||
|
@ -90,7 +90,7 @@ public class OderConstraint extends OderMenge<Pair>{
|
||||
* 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<UndConstraint> filteredConstraints = new Menge<>();
|
||||
for(UndConstraint cons : this.getUndConstraints()){
|
||||
@ -103,7 +103,6 @@ public class OderConstraint extends OderMenge<Pair>{
|
||||
}
|
||||
this.oderConstraintPairs = filteredConstraints;
|
||||
}
|
||||
|
||||
UndConstraint filterUndConstraints() {
|
||||
if(this.oderConstraintPairs.size()==1){
|
||||
return this.oderConstraintPairs.firstElement();
|
||||
@ -111,6 +110,7 @@ public class OderConstraint extends OderMenge<Pair>{
|
||||
return null;
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
public Set<? extends KomplexeMenge<Pair>> getSet() {
|
||||
return this.oderConstraintPairs;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,13 +22,13 @@ public class UndConstraint extends UndMenge<Pair> {
|
||||
return set;
|
||||
}
|
||||
|
||||
public Menge<Pair> getConstraintPairs() {
|
||||
Menge<Menge<Pair>> ret = this.cartesianProduct();
|
||||
public Set<Pair> getConstraintPairs() {
|
||||
Set<Set<Pair>> 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) {
|
||||
|
@ -14,7 +14,6 @@ public abstract class UndMenge<A> implements KomplexeMenge<A>{
|
||||
@Override
|
||||
public Set<Set<A>> cartesianProduct() {
|
||||
Set<Set<A>> ret = null;
|
||||
//Cloner cloner = new Cloner();
|
||||
for(KomplexeMenge<A> km : this.getSet()){
|
||||
if(ret == null){
|
||||
ret = km.cartesianProduct();
|
||||
@ -22,7 +21,7 @@ public abstract class UndMenge<A> implements KomplexeMenge<A>{
|
||||
Set<Set<A>> cartesianProduct = new Menge<>();
|
||||
for(Set<A> r : ret)for(Set<A> m : km.cartesianProduct()){ //Für jedes Element aus dem Karthesischen Produkt:
|
||||
Set<A> undElement = new Menge<A>();
|
||||
undElement.addAll(Unify.deepClone(r));
|
||||
undElement.addAll(r);
|
||||
undElement.addAll(m);
|
||||
cartesianProduct.add(undElement);
|
||||
}
|
||||
|
@ -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<Unifier> unify(Set<UnifyType> terms) {
|
||||
if(terms.size() < 2)
|
||||
return Optional.of(Unifier.IDENTITY);
|
||||
return Optional.of(Unifier.Identity());
|
||||
|
||||
ArrayList<MPair> termsQ = new ArrayList<MPair>();
|
||||
Iterator<UnifyType> 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();
|
||||
|
@ -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<MPair> 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<UnifyType> opt = finiteClosure.getGenericType(typeD.getName());
|
||||
|
||||
|
||||
Optional<UnifyType> opt = finiteClosure.getLeftHandedType(typeD);
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
// The generic Version of Type D (D<a1, a2, a3, ... >)
|
||||
// The generic Version of Type D (D<a1, a2, a3, ... >)
|
||||
UnifyType typeDgen = opt.get();
|
||||
|
||||
|
||||
// Actually greater+ because the types are ensured to have different names
|
||||
Set<UnifyType> greater = finiteClosure.greater(typeDgen);
|
||||
Set<UnifyType> 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<UnifyType> opt = finiteClosure.getGenericType(((ExtendsType) typeD).getExtendedType().getName());
|
||||
typeDgen = finiteClosure.getLeftHandedType(typeD).orElse(null);
|
||||
else {
|
||||
Optional<UnifyType> 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<UnifyType> opt = finiteClosure.getGenericType(((SuperType) typeSupD).getSuperedType().getName());
|
||||
|
||||
Optional<UnifyType> 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<UnifyType> opt = finiteClosure.getGenericType(((ExtendsType) C).getExtendedType().getName());
|
||||
if(opt.isPresent()) cFromFc = new ExtendsType(opt.get());
|
||||
}
|
||||
else if(C instanceof SuperType) {
|
||||
Optional<UnifyType> 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<UnifyType[]> typesFromFc = Optional.empty(); //TODO reduce regeln
|
||||
//finiteClosure.findCandD(simpleTypeCName, simpleTypeDName);
|
||||
|
||||
if(typesFromFc == null)
|
||||
return new int[0];
|
||||
|
||||
Optional<UnifyType> 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<MPair> 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<MPair> 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<MPair> 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<MPair> 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<MPair> 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<MPair> 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<MPair> 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<Set<MPair>> 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<MPair> result = new HashSet<MPair>();
|
||||
|
||||
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<Set<MPair>> 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<MPair> result = new HashSet<MPair>();
|
||||
|
||||
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<Set<MPair>> 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<MPair> result = new HashSet<MPair>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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<UnifyType> grArg(SuperType type);
|
||||
public Set<UnifyType> smArg(SuperType type);
|
||||
|
||||
|
||||
public Set<UnifyType> grArg(PlaceholderType type);
|
||||
public Set<UnifyType> smArg(PlaceholderType type);
|
||||
|
||||
public Optional<UnifyType> getGenericType(String typeName);
|
||||
|
||||
public Set<UnifyType> grArg(FunNType type);
|
||||
public Set<UnifyType> smArg(FunNType type);
|
||||
|
||||
public Optional<UnifyType> getLeftHandedType(UnifyType t);
|
||||
public Set<UnifyType> getAncestors(UnifyType t);
|
||||
|
||||
public Set<UnifyType> getAllTypesByName(String typeName);
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,24 @@ public interface IRuleSet {
|
||||
public Optional<Set<MPair>> reduce1(MPair pair);
|
||||
public Optional<Set<MPair>> reduce2(MPair pair);
|
||||
|
||||
/*
|
||||
* Missing Rules
|
||||
*/
|
||||
public Optional<MPair> reduceWildcardLow(MPair pair);
|
||||
public Optional<MPair> reduceWildcardLowRight(MPair pair);
|
||||
public Optional<MPair> reduceWildcardUp(MPair pair);
|
||||
public Optional<MPair> reduceWildcardUpRight(MPair pair);
|
||||
public Optional<MPair> reduceWildcardLowUp(MPair pair);
|
||||
public Optional<MPair> reduceWildcardUpLow(MPair pair);
|
||||
public Optional<MPair> reduceWildcardLeft(MPair pair);
|
||||
|
||||
/*
|
||||
* FunN Rules
|
||||
*/
|
||||
public Optional<Set<MPair>> reduceFunN(MPair pair);
|
||||
public Optional<Set<MPair>> greaterFunN(MPair pair);
|
||||
public Optional<Set<MPair>> smallerFunN(MPair pair);
|
||||
|
||||
public boolean erase1(MPair pair);
|
||||
public boolean erase2(MPair pair);
|
||||
public boolean erase3(MPair pair);
|
||||
|
@ -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<UnifyType, Node<UnifyType>> inheritanceGraph;
|
||||
private HashMap<String, HashSet<Node<UnifyType>>> strInheritanceGraph;
|
||||
|
||||
public FiniteClosure() {
|
||||
|
||||
}
|
||||
private Set<MPair> pairs;
|
||||
private Set<UnifyType> 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<MPair> pairs) {
|
||||
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
this.pairs = new HashSet<>(pairs);
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
|
||||
// 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<UnifyType> smaller(UnifyType type) {
|
||||
// - if(T < T') then T <=* T'
|
||||
Set<UnifyType> 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<Node<Type>> candidateNodes = strInheritanceGraph.get(type.getName());
|
||||
for(Node<Type> candidateNode : candidateNodes) {
|
||||
Type theta2 = candidateNode.getContent();
|
||||
Optional<Unifier> 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<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for(UnifyType param : type.getTypeParams()) {
|
||||
if(param instanceof ExtendsType || param instanceof SuperType) {
|
||||
Set<UnifyType> pc = param.smArg(this);
|
||||
paramCandidates.add(pc);
|
||||
} else {
|
||||
HashSet<UnifyType> pc = new HashSet<>();
|
||||
pc.add(param);
|
||||
paramCandidates.add(pc);
|
||||
}
|
||||
}
|
||||
if(inheritanceGraph.containsKey(type)) {
|
||||
Set<UnifyType> result = new HashSet<>();
|
||||
result.add(type);
|
||||
result.addAll(inheritanceGraph.get(type).getContentOfDescendants());
|
||||
return result;
|
||||
}
|
||||
|
||||
IUnify unify = new MartelliMontanariUnify();
|
||||
Set<UnifyType> result1 = new HashSet<>();
|
||||
|
||||
// if T = T' then T <=* T'
|
||||
result1.add(type);
|
||||
|
||||
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for (UnifyType param : type.getTypeParams())
|
||||
paramCandidates.add(smArg(param));
|
||||
|
||||
Set<TypeParams> 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<Unifier> 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<UnifyType> result2 = new HashSet<>();
|
||||
if (strInheritanceGraph.containsKey(type.getName())) {
|
||||
HashSet<UnifyType> 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<Unifier> sigma2 = unify.unify(typePrime, theta2);
|
||||
if (!sigma2.isPresent())
|
||||
continue;
|
||||
if(type.equals(theta2))
|
||||
continue;
|
||||
Set<UnifyType> 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<UnifyType> result3 = new HashSet<>();
|
||||
for(UnifyType t : result2) {
|
||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for (UnifyType param : t.getTypeParams())
|
||||
paramCandidates.add(smArg(param));
|
||||
|
||||
Set<TypeParams> 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<UnifyType> greater(UnifyType type) {
|
||||
Set<UnifyType> result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfPredecessors() : new HashSet<>();
|
||||
result.add(type);
|
||||
|
||||
if(type.getTypeParams().size() == 0)
|
||||
return result;
|
||||
*/
|
||||
@Override
|
||||
public Set<UnifyType> greater(UnifyType type) {
|
||||
IUnify unify = new MartelliMontanariUnify();
|
||||
Set<UnifyType> result1 = new HashSet<>();
|
||||
|
||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for(UnifyType param : type.getTypeParams()) {
|
||||
if(param instanceof ExtendsType || param instanceof SuperType) {
|
||||
Set<UnifyType> pc = param.grArg(this);
|
||||
paramCandidates.add(pc);
|
||||
} else {
|
||||
HashSet<UnifyType> 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<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for (UnifyType param : type.getTypeParams())
|
||||
paramCandidates.add(grArg(param));
|
||||
|
||||
Set<TypeParams> permResult = new HashSet<>();
|
||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
||||
|
||||
for (TypeParams newParams : permResult)
|
||||
result1.add(type.setTypeParams(newParams));}
|
||||
|
||||
Set<UnifyType> result2 = new HashSet<>();
|
||||
if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) {
|
||||
HashSet<UnifyType> candidates = new HashSet<>();
|
||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||
|
||||
for(UnifyType typePrime : result1) {
|
||||
for (UnifyType theta2 : candidates) {
|
||||
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
|
||||
if (!sigma2.isPresent())
|
||||
continue;
|
||||
if(type.equals(theta2))
|
||||
continue;
|
||||
Set<UnifyType> 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<TypeParams> permResult = new HashSet<>();
|
||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
||||
result2.addAll(result1);
|
||||
|
||||
for(TypeParams newParams : permResult)
|
||||
result.add(type.setTypeParams(newParams));
|
||||
Set<UnifyType> result3 = new HashSet<>();
|
||||
for(UnifyType t : result2) {
|
||||
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||
for (UnifyType param : t.getTypeParams())
|
||||
paramCandidates.add(grArg(param));
|
||||
|
||||
Set<TypeParams> 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<UnifyType> grArg(SimpleType type) {
|
||||
if(!inheritanceGraph.containsKey(type))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
|
||||
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<UnifyType> grArg(FunNType type) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> grArg(ExtendsType type) {
|
||||
if(!inheritanceGraph.containsKey(type.getExtendedType()))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
|
||||
@ -209,15 +241,12 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> grArg(SuperType type) {
|
||||
if(!inheritanceGraph.containsKey(type.getSuperedType()))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
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<UnifyType> grArg(PlaceholderType type) {
|
||||
HashSet<UnifyType> 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<UnifyType> smArg(SimpleType type) {
|
||||
if(!inheritanceGraph.containsKey(type))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
|
||||
result.add(type);
|
||||
smaller(type).forEach(x -> result.add(new ExtendsType(x)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> smArg(FunNType type) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> smArg(ExtendsType type) {
|
||||
if(!inheritanceGraph.containsKey(type.getExtendedType()))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
result.add(type);
|
||||
|
||||
UnifyType t = type.getExtendedType();
|
||||
|
||||
@ -270,11 +297,8 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> smArg(SuperType type) {
|
||||
if(!inheritanceGraph.containsKey(type.getSuperedType()))
|
||||
return new HashSet<UnifyType>();
|
||||
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
|
||||
@ -292,26 +316,23 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
@Override
|
||||
public Set<UnifyType> smArg(PlaceholderType type) {
|
||||
HashSet<UnifyType> 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<UnifyType> getGenericType(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
return Optional.empty();
|
||||
|
||||
public boolean isGenericType(UnifyType t) {
|
||||
if(t.getTypeParams().size() == 0)
|
||||
return true;
|
||||
|
||||
HashSet<Node<UnifyType>> candidates = strInheritanceGraph.get(typeName);
|
||||
if(!strInheritanceGraph.containsKey(t.getName()))
|
||||
return false;
|
||||
|
||||
for(Node<UnifyType> 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<UnifyType> 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<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
@Override
|
||||
public Set<UnifyType> getAncestors(UnifyType t) {
|
||||
if(!inheritanceGraph.containsKey(t))
|
||||
return new HashSet<>();
|
||||
return inheritanceGraph.get(t).getContentOfPredecessors();
|
||||
}
|
||||
|
||||
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
if(candidates.size() == idx) {
|
||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||
return;
|
||||
|
44
src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java
Normal file
44
src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java
Normal file
@ -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<UnifyType> smArg(IFiniteClosure fc) {
|
||||
return fc.smArg(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<UnifyType> grArg(IFiniteClosure fc) {
|
||||
return fc.grArg(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
UnifyType apply(Unifier unif) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO equals und hashcode
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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 "=.";
|
||||
}
|
||||
};
|
||||
}
|
@ -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<String> EXISTING_PLACEHOLDERS = new HashSet<String>();
|
||||
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
|
||||
|
@ -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<UnifyType>{
|
||||
@ -15,7 +15,7 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
}
|
||||
}
|
||||
|
||||
public TypeParams(UnifyType... types) {
|
||||
public TypeParams(UnifyType... types) {
|
||||
typeParams = types;
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,8 @@ import java.util.function.Function;
|
||||
public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/ { // TODO set implementieren
|
||||
private HashMap<PlaceholderType, UnifyType> 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<UnifyType, UnifyType> /*, Set<MPair>*/
|
||||
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));
|
||||
|
491
src/de/dhbwstuttgart/typeinference/unifynew/Unify.java
Normal file
491
src/de/dhbwstuttgart/typeinference/unifynew/Unify.java
Normal file
@ -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<Set<MPair>> unify(Set<MPair> eq, IFiniteClosure fc) {
|
||||
/*
|
||||
* Step 1: Repeated application of reduce, adapt, erase, swap
|
||||
*/
|
||||
|
||||
Set<MPair> 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<MPair> eq1s = new HashSet<>();
|
||||
Set<MPair> 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<Set<Set<MPair>>> topLevelSets = new ArrayList<>();
|
||||
|
||||
if(eq1s.size() != 0) {
|
||||
Set<Set<MPair>> wrap = new HashSet<>();
|
||||
wrap.add(eq1s);
|
||||
topLevelSets.add(wrap); // Add Eq1'
|
||||
}
|
||||
|
||||
// Add the set of [a =. Theta | (a=. Theta) in Eq2']
|
||||
Set<MPair> bufferSet = eq2s.stream()
|
||||
.filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if(bufferSet.size() != 0) {
|
||||
Set<Set<MPair>> wrap = new HashSet<>();
|
||||
wrap.add(bufferSet);
|
||||
topLevelSets.add(wrap);
|
||||
}
|
||||
|
||||
// Sets that originate from pair pattern matching
|
||||
// Sets of the "second level"
|
||||
Set<Set<Set<MPair>>> 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<Set<MPair>> secondLevelSet : secondLevelSets) {
|
||||
List<Set<MPair>> 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<Set<Set<MPair>>> 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<Set<MPair>> eqPrimeSetFlat = new HashSet<>();
|
||||
for(Set<Set<MPair>> setToFlatten : eqPrimeSet) {
|
||||
Set<MPair> buffer = new HashSet<>();
|
||||
setToFlatten.stream().forEach(x -> buffer.addAll(x));
|
||||
eqPrimeSetFlat.add(buffer);
|
||||
}
|
||||
|
||||
IRuleSet rules = new RuleSet(fc);
|
||||
Set<Set<MPair>> changed = new HashSet<>();
|
||||
Set<Set<MPair>> eqPrimePrimeSet = new HashSet<>();
|
||||
|
||||
for(Set<MPair> eqPrime : eqPrimeSetFlat) {
|
||||
Optional<Set<MPair>> 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<MPair> eqss : changed) {
|
||||
eqPrimePrimeSet.addAll(this.unify(eqss, fc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 7: Filter result for solved pairs
|
||||
*/
|
||||
return eqPrimePrimeSet;
|
||||
|
||||
}
|
||||
|
||||
protected Set<MPair> applyTypeUnificationRules(Set<MPair> 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<MPair> targetSet = new LinkedHashSet<MPair>();
|
||||
LinkedList<MPair> 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<MPair> 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<Set<MPair>> 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<MPair> collection) {
|
||||
Optional<MPair> 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<MPair> eq, Set<MPair> eq1s, Set<MPair> eq2s) {
|
||||
for(MPair pair : eq)
|
||||
if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType)
|
||||
eq1s.add(pair);
|
||||
else
|
||||
eq2s.add(pair);
|
||||
}
|
||||
|
||||
|
||||
protected Set<Set<Set<MPair>>> calculatePairSets(Set<MPair> eq2s, IFiniteClosure fc) {
|
||||
List<Set<Set<MPair>>> 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<MPair> unifyCase1(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
IUnify unify = new MartelliMontanariUnify();
|
||||
|
||||
Set<UnifyType> cs = fc.getAllTypesByName(thetaPrime.getName());
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
TypeParams cParams = c.getTypeParams();
|
||||
if(cParams.size() == 0)
|
||||
thetaQPrimes.add(c);
|
||||
else {
|
||||
ArrayList<Set<UnifyType>> 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<Unifier> opt = unify.unify(tqp, thetaPrime);
|
||||
if (!opt.isPresent())
|
||||
continue;
|
||||
|
||||
Unifier unifier = opt.get();
|
||||
Set<Entry<PlaceholderType, UnifyType>> substitutions = unifier.getSubstitutions();
|
||||
for (Entry<PlaceholderType, UnifyType> sigma : substitutions)
|
||||
result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
|
||||
for (UnifyType tq : thetaQs) {
|
||||
Set<UnifyType> 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<MPair> unifyCase2(PlaceholderType a, ExtendsType extThetaPrime, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
IUnify unify = new MartelliMontanariUnify();
|
||||
|
||||
UnifyType thetaPrime = extThetaPrime.getExtendedType();
|
||||
Set<UnifyType> cs = fc.getAllTypesByName(thetaPrime.getName());
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
TypeParams cParams = c.getTypeParams();
|
||||
if(cParams.size() == 0)
|
||||
thetaQPrimes.add(c);
|
||||
else {
|
||||
ArrayList<Set<UnifyType>> 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<Unifier> opt = unify.unify(tqp, thetaPrime);
|
||||
if (!opt.isPresent())
|
||||
continue;
|
||||
|
||||
Unifier unifier = opt.get();
|
||||
Set<Entry<PlaceholderType, UnifyType>> substitutions = unifier.getSubstitutions();
|
||||
for (Entry<PlaceholderType, UnifyType> sigma : substitutions)
|
||||
result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
|
||||
for (UnifyType tq : thetaQs) {
|
||||
ExtendsType extTq = new ExtendsType(tq);
|
||||
Set<UnifyType> 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<MPair> unifyCase3(PlaceholderType a, SuperType subThetaPrime, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
for(UnifyType theta : fc.smArg(subThetaPrime))
|
||||
result.add(new MPair(a, theta, PairOperator.EQUALSDOT));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Set<MPair> unifyCase4(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
result.add(new MPair(a, thetaPrime, PairOperator.EQUALSDOT));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Set<MPair> unifyCase5(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
for(UnifyType thetaS : fc.greater(theta))
|
||||
result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Set<MPair> unifyCase6(ExtendsType extTheta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
for(UnifyType thetaS : fc.grArg(extTheta))
|
||||
result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Set<MPair> unifyCase7(SuperType supTheta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
IUnify unify = new MartelliMontanariUnify();
|
||||
|
||||
UnifyType theta = supTheta.getSuperedType();
|
||||
Set<UnifyType> cs = fc.getAllTypesByName(theta.getName());
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
|
||||
// Wenn die fc nach spezifikation funktioniert ist das hier nicht mehr nötig?
|
||||
Set<UnifyType> thetaQs = fc.smaller(c).stream().filter(x -> x.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
|
||||
thetaQs.add(c); // reflexive
|
||||
|
||||
Set<UnifyType> thetaQPrimes = new HashSet<>();
|
||||
TypeParams cParams = c.getTypeParams();
|
||||
if(cParams.size() == 0)
|
||||
thetaQPrimes.add(c);
|
||||
else {
|
||||
ArrayList<Set<UnifyType>> 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<Unifier> opt = unify.unify(tqp, theta);
|
||||
if (!opt.isPresent())
|
||||
continue;
|
||||
|
||||
Unifier unifier = opt.get();
|
||||
Set<Entry<PlaceholderType, UnifyType>> substitutions = unifier.getSubstitutions();
|
||||
for (Entry<PlaceholderType, UnifyType> sigma : substitutions)
|
||||
result.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
|
||||
for (UnifyType tq : thetaQs) {
|
||||
Set<UnifyType> 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<MPair> unifyCase8(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<MPair> result = new HashSet<>();
|
||||
for(UnifyType thetaS : fc.grArg(theta))
|
||||
result.add(new MPair(a, thetaS, PairOperator.EQUALSDOT));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
|
||||
Set<TypeParams> result = new HashSet<>();
|
||||
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
if(candidates.size() == idx) {
|
||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||
return;
|
||||
}
|
||||
|
||||
Set<UnifyType> localCandidates = candidates.get(idx);
|
||||
|
||||
for(UnifyType t : localCandidates) {
|
||||
current[idx] = t;
|
||||
permuteParams(candidates, idx+1, result, current);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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<Integer>) = { HashSet<Integer>, Set<Integer, TreeSet<Integer>, LinkedHashSet<Integer> }
|
||||
*/
|
||||
|
||||
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<UnifyType> 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<? ext Integer>) =
|
||||
* { HashSet<Integer>, Set<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||
* HashSet<? ext Integer>, Set<? ext Integer>, TreeSet<? ext Integer>, LinkedHashSet<? ext Integer> }
|
||||
*/
|
||||
|
||||
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<? ext Number>) =
|
||||
* { HashSet<Integer>, Set<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||
* HashSet<Number>, Set<Number>, TreeSet<Number>, LinkedHashSet<Number>,
|
||||
* HashSet<? ext Integer>, Set<? ext Integer>, TreeSet<? ext Integer>, LinkedHashSet<? ext Integer>
|
||||
* HashSet<? ext Number, Set<? ext Number, TreeSet<? ext Number, LinkedHashSet<? ext Number> }
|
||||
*/
|
||||
|
||||
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<T>) =
|
||||
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||
*/
|
||||
|
||||
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<? super Integer> =
|
||||
* { Set<Integer>, HashSet<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||
* Set<? super Integer>, HashSet<? super Integer>, TreeSet<? super Integer>, LinkedHashSet<? super Integer>,
|
||||
* Set<? super Number>, HashSet<? super Number>, TreeSet<? super Number>, LinkedHashSet<? super Number> }
|
||||
*/
|
||||
|
||||
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<? ext T) =
|
||||
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||
*
|
||||
*/
|
||||
|
||||
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<NotInFc>) =
|
||||
* { HashSet<NotInFc>, Set<NotInFc>, TreeSet<NotInFc>, LinkedHashSet<NotInFc>,
|
||||
* HashSet<? ext NotInFc>, Set<? ext NotInFc>, TreeSet<? ext NotInFc>, LinkedHashSet<? ext NotInFc> }
|
||||
*/
|
||||
|
||||
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<? super NotInFC>) =
|
||||
* { Set<NotInFC>, HashSet<NotInFC>, LinkedHashSet<NotInFC>, TreeSet<NotInFC>,
|
||||
* Set<? super NotInFC>, HashSet<? super NotInFC>, LinkedHashSet<? super NotInFC>, TreeSet<? super NotInFc> }
|
||||
*/
|
||||
|
||||
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<? extends Number>) =
|
||||
* { NotInFc<Integer>, NotInFc<Number>, NotInFc<? extends Number>, NotInFc<? extends Integer> }
|
||||
*/
|
||||
|
||||
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<? super AlsoNotInFc> =
|
||||
* { NotInFc<AlsoNotInFc>, NotInFc<? super AlsoNotInFc> }
|
||||
*/
|
||||
|
||||
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<UnifyType> actual = fc.smaller(notInFcSupAlsoNotInFc);
|
||||
Assert.assertEquals(expectedResult, actual);
|
||||
|
||||
/*
|
||||
* Test Case 10:
|
||||
*
|
||||
* smaller(TreeMap<? extends Number, ? super Integer>) =
|
||||
* { TreeMap<? extends Number, ? super Integer>, TreeMap<? extends Number, ? super Number>, TreeMap<? extends Number, Integer>, TreeMap<? extends Number, Number>
|
||||
* TreeMap<Number, ? super Integer>, TreeMap<Number, ? super Number>, TreeMap<Number, Integer>, TreeMap<Number, Number>,
|
||||
* TreeMap<Integer, ? super Integer, TreeMap<Integer, ? super Number>, TreeMap<Integer, Integer>, TreeMap<Integer, Number>
|
||||
* TreeMap<? extends Integer, ? super Integer>, TreeMap<? extends Integer, ? super Number>, TreeMap<? extends Integer, Integer>, TreeMap<? extends Integer, Number> }
|
||||
*/
|
||||
|
||||
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<Number, T>) = { SortedMap<Number, T>, NavigableMap<Number, T>, TreeMap<Number, T> }
|
||||
*/
|
||||
|
||||
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<K> <* TreeMap<K, List<K>>
|
||||
*
|
||||
* smaller(TreeMap<Number, List<Number>) = { TreeMap<Number, List<Number>>, MyMap<Number> }
|
||||
*/
|
||||
|
||||
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<K> <* TreeMap<K, List<K>>
|
||||
*
|
||||
* smaller(TreeMap<? extends Number, List<Integer>) =
|
||||
* { TreeMap<? extends Integer>, List<Integer>>,
|
||||
* TreeMap<? extends Number, List<Integer>>,
|
||||
* TreeMap<Number, List<Integer>>,
|
||||
* TreeMap<Integer, List<Integer>>,
|
||||
* MyMap<Integer> }
|
||||
*/
|
||||
|
||||
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<K> <* TreeMap<K, List<K>>
|
||||
*
|
||||
* smaller(TreeMap<? extends Number, List<? extends Number>) =
|
||||
* { TreeMap<? extends Number>, List<? extends Number>>,
|
||||
* TreeMap<? extends Integer, List<? extends Number>>,
|
||||
* TreeMap<Number, List<? extends Number>>,
|
||||
* TreeMap<Integer, List<? extends Number>>,
|
||||
* MyMap<Integer>
|
||||
* MyMap<Number>
|
||||
* MyMap<? extends Integer>
|
||||
* MyMap<? extends Number>
|
||||
*/
|
||||
|
||||
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<K> <* TreeMap<K, List<K>>
|
||||
*
|
||||
* smaller(NavigableSet<? extends Integer, ? extends List<? extends Integer>>) =
|
||||
* { Permutationen der List,
|
||||
* Permutationen der List in TreeSets,
|
||||
* MyMap<Integer> und MyMap<? extends Integer>
|
||||
* }
|
||||
*/
|
||||
|
||||
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<Integer>) =
|
||||
* { SortedSet<Integer>, Set<Integer>, Collection
|
||||
* SortedSet<? extends Integer>, SortedSet<? super Integer>, SortedSet<? extends Number>,
|
||||
* Set<? extends Integer>, Set<? super Integer>, Set<? extends Number> }
|
||||
*/
|
||||
|
||||
System.out.println("\n\n----- Greater Test -----");
|
||||
System.out.println("Greater(LinkedList<T>) = " + fc.greater(tf.getSimpleType("LinkedList", "T")));
|
||||
System.out.println("Greater(TreeSet<T>) = " + fc.greater(tf.getSimpleType("TreeSet", "T")));
|
||||
System.out.println("Greater(Collection) = " + fc.greater(tf.getSimpleType("Collection")));
|
||||
UnifyType sortedSetInteger = tf.getSimpleType("SortedSet", integer);
|
||||
Set<UnifyType> 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<UnifyType> actual = fc.greater(sortedSetInteger);
|
||||
Assert.assertEquals(expectedResult, actual);
|
||||
|
||||
/*
|
||||
* Test Case 2:
|
||||
*
|
||||
* greater(SortedSet<? extends Integer>) =
|
||||
* { SortedSet<? extends Integer>, SortedSet<? extends Number>,
|
||||
* Set<? extends Integer>, Set<? extends Number>, 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<T>) =
|
||||
* { SortedSet<T>, SortedSet<? extends T>, SortedSet<? super T>,
|
||||
* Set<T>, Set<? extends T>, Set<? super T>, Collection }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test Case 4:
|
||||
*
|
||||
* greater(SortedSet<? super Number>) =
|
||||
* { SortedSet<? super Number>, SortedSet<? super Integer>
|
||||
* Set<? super Number>, Set<? super Integer>, 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<T> deklariert wurde. Können die beiden T's verschieden sein?
|
||||
* greater(SortedSet<? extends T1>) =
|
||||
* { SortedSet<? extends T1>, Set<? extends T1>, 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<NotInFc>) =
|
||||
* { SortedSet<NotInFc>, SortedSet<? extends NotInFC>, SortedSet<? super NotInFc>,
|
||||
* Set<NotInFc>, Set<? extends NotInFC>, Set<? super NotInFC>, 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<? super NotInFc) =
|
||||
* { SortedSet<? super NotInFc>, Set<? super NotInFc>, 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<Integer>) =
|
||||
* { NotInFc<Integer>, NotInFc<? super Integer>, NotInFC<? extends Integer>,
|
||||
* NotInFc<? extends Number> }
|
||||
*/
|
||||
|
||||
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<AlsoNotInFc>) =
|
||||
* { NotInFc<AlsoNotInFc>, NotInFc<? extends AlsoNotInFc, NotInFc<? super AlsoNotInFc> }
|
||||
*/
|
||||
|
||||
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<? extends Integer, Integer>) =
|
||||
* { Map<? extends Integer, Integer>, Map<? extends Integer, ? extends Integer>,
|
||||
* Map<? extends Integer, ? super Integer>, Map<? extends Integer, ? extends Number>,
|
||||
* Map<? extends Number, Integer>, Map<? extends Number, ? extends Integer>,
|
||||
* Map<? extends Number, ? super Integer>, Map<? extends Number, ? extends Number> }
|
||||
*/
|
||||
|
||||
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<Integer>
|
||||
* MyMap<K> < Map<K, List<K>>
|
||||
*
|
||||
* greater(MyIntMap) =
|
||||
* { MyMap<Integer>, MyMap<? extends Integer>, MyMap<? extends Number>, MyMap<? super Integer>,
|
||||
* Map<Integer, List<Integer>, Map<? extends Integer>, List<Integer>,
|
||||
* Map<? extends Number>, List<Integer>, Map<? super Integer, List<Integer>, 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<Integer>
|
||||
* MyMap<K> < Map<K, List<K>>
|
||||
*
|
||||
* TODO
|
||||
* D<? super Number> d = null;
|
||||
* A<? super Number, List<? super Number>> a = null;
|
||||
* a = d; ist nicht möglich!
|
||||
*
|
||||
* greater(MyMap<? super Number>) =
|
||||
* { MyMap<? super Number>, MyMap<? super Integer>,
|
||||
* Map<? super Number, List<? super Number>>,
|
||||
* Map<? super Integer>, List<? super Number>> }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test Case 13:
|
||||
*
|
||||
* greater(SortedMap<? super Number>, ? super List<? extends Integer>>) =
|
||||
*
|
||||
*/
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -56,20 +644,6 @@ public class FiniteClosureTest extends FiniteClosure {
|
||||
System.out.println("GrArg(? super List<T>) = " + 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<? extends Number>) = " + fc.smaller(tf.getSimpleType("List", tf.getExtendsType(tf.getSimpleType("Number")))));
|
||||
System.out.println("Smaller(List<T>) = " + fc.smaller(tf.getSimpleType("List", "T")));
|
||||
System.out.println("Smaller(TreeSet<T>) = " + 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<UnifyType> expected, Set<UnifyType> actual) {
|
||||
System.out.println("Diff:");
|
||||
System.out.println("In expected but not in actual:");
|
||||
Set<UnifyType> expected1 = new HashSet<>(expected);
|
||||
expected1.removeAll(actual);
|
||||
System.out.println(expected1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user