Merge mit Unify und Einbinden der neuen Unifizierung. Nich lauffähige Version

This commit is contained in:
JanUlrich 2016-03-30 18:16:27 +02:00
commit e2d384e7f9
52 changed files with 1788 additions and 353 deletions

View File

@ -2,6 +2,14 @@ package de.dhbwstuttgart.myexception;
public class NotImplementedException extends RuntimeException {
public NotImplementedException(String message) {
super(message);
}
public NotImplementedException() {
super("Nicht implementiert");
}
/**
*
*/

View File

@ -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 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
//¼r jede Klasse in diesem SourceFile gilt das selbe ResultSet:
for(Class klasse : this.KlassenVektor){
//Der Unifikationsalgorithmus kann wiederum auch mehrere 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);

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
/**

View File

@ -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) {

View File

@ -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()){ //¼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);
}

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View 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
}

View File

@ -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;

View File

@ -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 "=.";
}
};
}

View File

@ -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

View File

@ -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;
}

View File

@ -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));

View 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);
}
}
}

View File

@ -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;

View File

@ -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);
}
}