forked from JavaTX/JavaCompilerCore
Compare commits
8 Commits
refactorin
...
refactorin
Author | SHA1 | Date | |
---|---|---|---|
3019a0f513 | |||
9a0de3f193 | |||
378374fff1 | |||
0dc8a53fca | |||
2f37bb7313 | |||
a04316f629 | |||
3b062de612 | |||
c32ef1e31f |
pom.xml
src
main
java
de
dhbwstuttgart
bytecode
insertGenerics
core
syntaxtree
factory
typeinference
assumptions
constraints
typeAlgo
unify
unify2
test
10
pom.xml
10
pom.xml
@ -118,7 +118,15 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
@ -1,9 +1,9 @@
|
||||
package de.dhbwstuttgart.bytecode.insertGenerics;
|
||||
|
||||
import com.ibm.icu.text.CurrencyMetaInfo;
|
||||
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -17,6 +17,7 @@ public class FamilyOfGeneratedGenerics {
|
||||
public List<ClassConstraint> classConstraints = new ArrayList<>();
|
||||
public List<MethodConstraint> methodConstraints = new ArrayList<>();
|
||||
|
||||
|
||||
public FamilyOfGeneratedGenerics(TPHExtractor tphExtractor) {
|
||||
this.allConstraints = tphExtractor.allCons;
|
||||
this.posOfTPHs = positionConverter(tphExtractor.allTPHS, tphExtractor.ListOfMethodsAndTph);
|
||||
@ -47,16 +48,35 @@ public class FamilyOfGeneratedGenerics {
|
||||
return cs_cl;
|
||||
}
|
||||
|
||||
public static List<MethodConstraint> getMethodConstraints(List<TPHConstraint> cs, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) {
|
||||
public static List<MethodConstraint> getMethodConstraints(List<TPHConstraint> cs, List<ClassConstraint> cs_cl, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) {
|
||||
//TODO: Regeln
|
||||
List<MethodConstraint> cs_m = new ArrayList<>();
|
||||
List<MethodConstraint> methodConstraints1 = typeOfTheMethodInClSigma(cs, cs_m, posOfTphs);
|
||||
List<MethodConstraint> methodConstraints1 = typeOfTheMethodInClSigma(cs, posOfTphs);
|
||||
for (MethodConstraint cons: methodConstraints1) {
|
||||
if (!checkForDuplicates(cons, cs_m)) {
|
||||
cs_m.add(cons);
|
||||
}
|
||||
}
|
||||
//List<MethodConstraint> methodConstraints2 = firstTransitiveSubtypeForMethodTypes();
|
||||
List<MethodConstraint> methodConstraints2 = firstTransitiveSubtypeForMethodTypes(cs, cs_m);
|
||||
for (MethodConstraint cons: methodConstraints2) {
|
||||
if (!checkForDuplicates(cons, cs_m)) {
|
||||
cs_m.add(cons);
|
||||
}
|
||||
}
|
||||
List<MethodConstraint> methodConstraints3 = secondTransitiveSubtypeForMethodTypes(cs, cs_cl, cs_m);
|
||||
for (MethodConstraint cons: methodConstraints3) {
|
||||
if (!checkForDuplicates(cons, cs_m)) {
|
||||
cs_m.add(cons);
|
||||
}
|
||||
}
|
||||
List<MethodConstraint> methodConstraints4 = hasNoSupertypeForMethodTypes(cs, posOfTphs);
|
||||
for (MethodConstraint cons: methodConstraints4) {
|
||||
if (!checkForDuplicates(cons, cs_m)) {
|
||||
cs_m.add(cons);
|
||||
}
|
||||
}
|
||||
List<MethodConstraint> methodConstraints5 = methodTypesWithoutClassTypes(cs_cl, cs_m);
|
||||
cs_m = methodConstraints5;
|
||||
return cs_m;
|
||||
}
|
||||
|
||||
@ -131,83 +151,79 @@ public class FamilyOfGeneratedGenerics {
|
||||
return tempCC;
|
||||
}
|
||||
|
||||
public static boolean checkUpperBound(List<TPHConstraint> cs, String tph) {
|
||||
for(int i=0; i<cs.size(); i++) {
|
||||
if(cs.get(i).getLeft() == tph) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Def. FGG: erste Zeile von cs_m
|
||||
* {T < .T' | T is a type variable in a type of the method/constructor m in cl_\sigma, (T <. T') \in cs}
|
||||
*/
|
||||
|
||||
public static List<MethodConstraint> typeOfTheMethodInClSigma(List<TPHConstraint> allConstraints, List<MethodConstraint> cs_m, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) { // cl_\sigma??
|
||||
public static List<MethodConstraint> typeOfTheMethodInClSigma(List<TPHConstraint> allConstraints, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) { // cl_\sigma??
|
||||
//TODO:
|
||||
List<MethodConstraint> tempCC= new ArrayList<>();
|
||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
||||
for(TPHConstraint allCons: allConstraints){
|
||||
if(posOfTphs.containsKey(allCons.getLeft()) && allCons.getRight()!=null && allCons.getRel()==Relation.EXTENDS) {
|
||||
for(String tph: posOfTphs.keySet()) {
|
||||
if(tph == allCons.getLeft() && (posOfTphs.get(tph).fst == PositionFinder.Position.METHOD || posOfTphs.get(tph).fst == PositionFinder.Position.CONSTRUCTOR)) {
|
||||
MethodConstraint consToAdd = new MethodConstraint(allCons.getLeft(), allCons.getRight(), allCons.getRel());
|
||||
if (!checkForDuplicates(consToAdd, tempCC)) {
|
||||
tempCC.add(consToAdd);
|
||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
||||
tempMC.add(consToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempCC;
|
||||
return tempMC;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Def. FGG: zweite Zeile von cs_m
|
||||
* {R' <. S | (R <. R'), (S <. S') \in cs_m and (R',S) is in the transitive closure of cs}
|
||||
*/
|
||||
|
||||
public static List<MethodConstraint> firstTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<MethodConstraint> cs_m, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) { //transitive closure of cs
|
||||
public static List<MethodConstraint> firstTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<MethodConstraint> cs_m) { //transitive closure of cs
|
||||
//TODO:
|
||||
List<MethodConstraint> tempCC= new ArrayList<>();
|
||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
||||
List<TPHConstraint> tcOfCs = buildTransitiveClosure(allConstraints);
|
||||
for(MethodConstraint mC1 : cs_m) {
|
||||
for(MethodConstraint mC2 : cs_m) {
|
||||
String rightSide = mC1.getRight();
|
||||
String leftSide = mC2.getLeft();
|
||||
for(MethodConstraint mC1 : cs_m) { //(R <. R')
|
||||
for(MethodConstraint mC2 : cs_m) { //(S <. S')
|
||||
String lSide = mC1.getRight(); //R'
|
||||
String rSide = mC2.getLeft(); //S
|
||||
for(TPHConstraint tphC : tcOfCs) {
|
||||
if(tphC.getLeft().equals(leftSide)&&tphC.getRight().equals(rightSide)) {
|
||||
tempCC.add((MethodConstraint) tphC);
|
||||
if(tphC.getLeft().equals(lSide)&&tphC.getRight().equals(rSide)) { //is it (R',S)
|
||||
MethodConstraint consToAdd = new MethodConstraint(lSide, rSide, tphC.getRel()); //create (R'<.S)
|
||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
||||
tempMC.add(consToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempCC;
|
||||
return tempMC;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Def. FGG: dritte Zeile von cs_m
|
||||
* {R' <. S | (R <. R') \in cs_m, (S <. S') \in cs_cl and (R',S) is in the transitive closure of cs}
|
||||
*/
|
||||
|
||||
public static List<MethodConstraint> secondTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<ClassConstraint> cs_cl, List<MethodConstraint> cs_m, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) {
|
||||
public static List<MethodConstraint> secondTransitiveSubtypeForMethodTypes(List<TPHConstraint> allConstraints, List<ClassConstraint> cs_cl, List<MethodConstraint> cs_m) {
|
||||
//TODO:
|
||||
List<MethodConstraint> tempCC= new ArrayList<>();
|
||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
||||
List<TPHConstraint> tcOfCs = buildTransitiveClosure(allConstraints);
|
||||
for(ClassConstraint cC : cs_cl) {
|
||||
for(MethodConstraint mC : cs_m) {
|
||||
String rightSide = mC.getRight();
|
||||
String leftSide = cC.getLeft();
|
||||
String leftSide = mC.getRight();
|
||||
String rightSide = cC.getLeft();
|
||||
for(TPHConstraint tphC : tcOfCs) {
|
||||
if(tphC.getLeft().equals(leftSide)&&tphC.getRight().equals(rightSide)) {
|
||||
tempCC.add((MethodConstraint) tphC);
|
||||
MethodConstraint consToAdd = new MethodConstraint(tphC.getLeft(), tphC.getRight(), tphC.getRel());
|
||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
||||
tempMC.add(consToAdd);
|
||||
System.out.println(consToAdd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempCC;
|
||||
return tempMC;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,18 +231,54 @@ public class FamilyOfGeneratedGenerics {
|
||||
* {T <. Object | (T is a type variable in a type of a node of the method/constructor m in cl_\sigma),
|
||||
* (\existsnot T': T <. T') \in cs)}
|
||||
*/
|
||||
|
||||
public static List<MethodConstraint> hasNoSupertypeForMethodTypes() {
|
||||
public static List<MethodConstraint> hasNoSupertypeForMethodTypes(List<TPHConstraint> allConstraints, HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs) {
|
||||
//TODO:
|
||||
return null;
|
||||
List<MethodConstraint> tempMC= new ArrayList<>();
|
||||
for(String tph: posOfTphs.keySet()) {
|
||||
for(TPHConstraint allCons: allConstraints) {
|
||||
if((posOfTphs.get(tph).fst.equals(PositionFinder.Position.METHOD) || posOfTphs.get(tph).fst.equals(PositionFinder.Position.CONSTRUCTOR)) && checkUpperBound(allConstraints,tph)) {
|
||||
MethodConstraint consToAdd = new MethodConstraint(tph, "Object", Relation.EXTENDS);
|
||||
if (!checkForDuplicates(consToAdd, tempMC)) {
|
||||
tempMC.add(consToAdd);
|
||||
System.out.println(consToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempMC;
|
||||
}
|
||||
|
||||
/**
|
||||
* nimm die Menge cs_cl aus cs_m raus
|
||||
*/
|
||||
public static List<MethodConstraint> methodTypesWithoutClassTypes() {
|
||||
public static List<MethodConstraint> methodTypesWithoutClassTypes(List<ClassConstraint> cs_cl, List<MethodConstraint> cs_m) {
|
||||
//TODO:
|
||||
return null;
|
||||
List<TPHConstraint> tempCC = new ArrayList<>();
|
||||
for(ClassConstraint cc: cs_cl) {
|
||||
TPHConstraint tphC = new TPHConstraint(cc.getLeft(), cc.getRight(), cc.getRel());
|
||||
tempCC.add(tphC);
|
||||
}
|
||||
List<TPHConstraint> tempMC = new ArrayList<>();
|
||||
for(MethodConstraint mc: cs_m) {
|
||||
TPHConstraint tphC = new TPHConstraint(mc.getLeft(), mc.getRight(), mc.getRel());
|
||||
tempMC.add(tphC);
|
||||
}
|
||||
List<TPHConstraint> tempMC2 = new ArrayList<>();
|
||||
tempMC2.addAll(tempMC);
|
||||
List<MethodConstraint> tempMCToReturn = new ArrayList<>();
|
||||
|
||||
for(TPHConstraint cc: tempCC) {
|
||||
for(TPHConstraint mc: tempMC) {
|
||||
if(cc.getLeft().equals(mc.getLeft()) && cc.getRight().equals(mc.getRight())) {
|
||||
tempMC2.remove(mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(TPHConstraint tphC: tempMC2) {
|
||||
MethodConstraint mCons = new MethodConstraint(tphC.getLeft(), tphC.getRight(), tphC.getRel());
|
||||
tempMCToReturn.add(mCons);
|
||||
}
|
||||
return tempMCToReturn;
|
||||
}
|
||||
|
||||
public static boolean checkForDuplicates(TPHConstraint constraint, List list) {
|
||||
@ -264,6 +316,15 @@ public class FamilyOfGeneratedGenerics {
|
||||
return tcList;
|
||||
}
|
||||
|
||||
public static boolean checkUpperBound(List<TPHConstraint> cs, String tph) {
|
||||
for(int i=0; i<cs.size(); i++) {
|
||||
if(cs.get(i).getLeft() == tph) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static HashMap<String, PairTphMethod<PositionFinder.Position, String>> positionConverter(HashMap<String, Boolean> allTphs, List<MethodAndTPH> listOfMethodsAndTphs) {
|
||||
HashMap<String, PairTphMethod<PositionFinder.Position, String>> convertedPositions = new HashMap<>();
|
||||
|
@ -20,10 +20,12 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.TypeScope;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
@ -46,16 +48,26 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
@ -64,6 +76,7 @@ public class JavaTXCompiler {
|
||||
Boolean resultmodel = true;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
@ -181,7 +194,7 @@ public class JavaTXCompiler {
|
||||
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
|
||||
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
|
||||
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
@ -216,6 +229,321 @@ public class JavaTXCompiler {
|
||||
return new ArrayList<>(allClasses);
|
||||
}
|
||||
|
||||
/*
|
||||
* public List<ResultSet> typeInferenceOld() throws ClassNotFoundException {
|
||||
* List<ClassOrInterface> allClasses = new
|
||||
* ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten
|
||||
* Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf :
|
||||
* this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf));
|
||||
* allClasses.addAll(sf.getClasses()); }
|
||||
*
|
||||
* final ConstraintSet<Pair> cons = getConstraints();
|
||||
*
|
||||
* FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
|
||||
* System.out.println(finiteClosure); ConstraintSet<UnifyPair> unifyCons =
|
||||
* UnifyTypeFactory.convert(cons);
|
||||
*
|
||||
* TypeUnify unify = new TypeUnify(); Set<Set<UnifyPair>> results = new
|
||||
* HashSet<>(); try { File logPath = new
|
||||
* File(System.getProperty("user.dir")+"/target/logFiles/"); logPath.mkdirs();
|
||||
* FileWriter logFile = new FileWriter(new File(logPath, "log"));
|
||||
* logFile.write("FC:\\" + finiteClosure.toString()+"\n"); for(SourceFile sf :
|
||||
* this.sourceFiles.values()) { logFile.write(ASTTypePrinter.print(sf)); }
|
||||
* logFile.flush(); Set<List<Constraint<UnifyPair>>> cardProd =
|
||||
* unifyCons.cartesianProduct(); for (List<Constraint<UnifyPair>> xCons :
|
||||
* cardProd ){ Set<UnifyPair> xConsSet = new HashSet<>(); for
|
||||
* (Constraint<UnifyPair> constraint : xCons) { xConsSet.addAll(constraint); }
|
||||
* //.collect(Collectors.toCollection(ArrayList::new))))
|
||||
* System.out.println(xConsSet); Set<String> methodParaTypeVarNames =
|
||||
* allClasses.stream().map(x -> x.getMethods().stream().map(y ->
|
||||
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
|
||||
* instanceof TypePlaceholder) .map(z ->
|
||||
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
|
||||
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
|
||||
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
|
||||
* (a,b) -> { a.addAll(b); return a;} );
|
||||
*
|
||||
* Set<String> constructorParaTypeVarNames = allClasses.stream().map(x ->
|
||||
* x.getConstructors().stream().map(y ->
|
||||
* y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
|
||||
* instanceof TypePlaceholder) .map(z ->
|
||||
* ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
|
||||
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
|
||||
* a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
|
||||
* (a,b) -> { a.addAll(b); return a;} );
|
||||
*
|
||||
* Set<String> paraTypeVarNames = methodParaTypeVarNames;
|
||||
* paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
||||
*
|
||||
* Set<String> returnTypeVarNames = allClasses.stream().map(x ->
|
||||
* x.getMethods().stream().filter(y -> y.getReturnType() instanceof
|
||||
* TypePlaceholder) .map(z ->
|
||||
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
|
||||
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
|
||||
* ).get();
|
||||
*
|
||||
* Set<String> fieldTypeVarNames = allClasses.stream().map(x ->
|
||||
* x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof
|
||||
* TypePlaceholder) .map(z ->
|
||||
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
|
||||
* toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
|
||||
* ).get();
|
||||
*
|
||||
* returnTypeVarNames.addAll(fieldTypeVarNames);
|
||||
*
|
||||
* xConsSet = xConsSet.stream().map(x -> { //Hier muss ueberlegt werden, ob //1.
|
||||
* alle Argument- und Retuntyp-Variablen in allen UnifyPairs // mit
|
||||
* disableWildcardtable() werden. //2. alle Typvariablen mit Argument- oder
|
||||
* Retuntyp-Variablen //in Beziehung auch auf disableWildcardtable() gesetzt
|
||||
* werden muessen //PL 2018-04-23 if ((x.getLhsType() instanceof
|
||||
* PlaceholderType)) { if (paraTypeVarNames.contains(x.getLhsType().getName()))
|
||||
* { ((PlaceholderType)x.getLhsType()).setVariance((byte)1);
|
||||
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } if
|
||||
* (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
* ((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
|
||||
* ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } } if
|
||||
* ((x.getRhsType() instanceof PlaceholderType)) { if
|
||||
* (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
* ((PlaceholderType)x.getRhsType()).setVariance((byte)1);
|
||||
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } if
|
||||
* (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
* ((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
|
||||
* ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } } return x;//HIER
|
||||
* DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS
|
||||
* ANDERE SEITE }).map( y -> { if ((y.getLhsType() instanceof PlaceholderType)
|
||||
* && (y.getRhsType() instanceof PlaceholderType)) { if
|
||||
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
||||
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
|
||||
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
|
||||
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
|
||||
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
|
||||
* )).getVariance()); } } return y; } )
|
||||
* .collect(Collectors.toCollection(HashSet::new));
|
||||
* varianceInheritance(xConsSet); Set<Set<UnifyPair>> result =
|
||||
* unify.unifySequential(xConsSet, finiteClosure, logFile, log);
|
||||
* //Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
* System.out.println("RESULT: " + result); logFile.write("RES: " +
|
||||
* result.toString()+"\n"); logFile.flush(); results.addAll(result); }
|
||||
*
|
||||
* results = results.stream().map(x -> { Optional<Set<UnifyPair>> res = new
|
||||
* RuleSet().subst(x.stream().map(y -> { if (y.getPairOp() ==
|
||||
* PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); return y;
|
||||
* //alle Paare a <.? b erden durch a =. b ersetzt
|
||||
* }).collect(Collectors.toCollection(HashSet::new))); if (res.isPresent())
|
||||
* {//wenn subst ein Erg liefert wurde was veraendert return new
|
||||
* TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); } else
|
||||
* return x; //wenn nichts veraendert wurde wird x zurueckgegeben
|
||||
* }).collect(Collectors.toCollection(HashSet::new));
|
||||
* System.out.println("RESULT Final: " + results); logFile.write("RES_FINAL: " +
|
||||
* results.toString()+"\n"); logFile.flush(); logFile.write("PLACEHOLDERS: " +
|
||||
* PlaceholderType.EXISTING_PLACEHOLDERS); logFile.flush(); } catch (IOException
|
||||
* e) { e.printStackTrace(); } return results.stream().map((unifyPairs -> new
|
||||
* ResultSet(UnifyTypeFactory.convert(unifyPairs,
|
||||
* generateTPHMap(cons))))).collect(Collectors.toList()); }
|
||||
*/
|
||||
/**
|
||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
|
||||
* Variance !=0 hat auf alle Typvariablen in Theta.
|
||||
*
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
|
||||
* usedTPH = new HashSet<>(); Set<PlaceholderType> phSet = eq.stream().map(x ->
|
||||
* { Set<PlaceholderType> pair = new HashSet<>(); if (x.getLhsType() instanceof
|
||||
* PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if
|
||||
* (x.getRhsType() instanceof PlaceholderType)
|
||||
* pair.add((PlaceholderType)x.getRhsType()); return pair; }).reduce(new
|
||||
* HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d);
|
||||
* return c;});
|
||||
*
|
||||
* ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
|
||||
* phSetVariance.removeIf(x -> (x.getVariance() == 0));
|
||||
* while(!phSetVariance.isEmpty()) { PlaceholderType a =
|
||||
* phSetVariance.remove(0); usedTPH.add(a); //HashMap<PlaceholderType,Integer>
|
||||
* ht = new HashMap<>(); //ht.put(a, a.getVariance()); Set<UnifyPair> eq1 = new
|
||||
* HashSet<>(eq); eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType
|
||||
* && ((PlaceholderType)x.getLhsType()).equals(a))); eq1.stream().forEach(x -> {
|
||||
* x.getRhsType().accept(new distributeVariance(), a.getVariance());}); eq1 =
|
||||
* new HashSet<>(eq); eq1.removeIf(x -> !(x.getRhsType() instanceof
|
||||
* PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
|
||||
* eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(),
|
||||
* a.getVariance());}); phSetVariance = new ArrayList<>(phSet);
|
||||
* phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
|
||||
* }
|
||||
*/
|
||||
|
||||
public UnifyResultModel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile)
|
||||
throws ClassNotFoundException, IOException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
||||
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
||||
for (File f : this.sourceFiles.keySet()) {
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
UnifyResultModel urm = null;
|
||||
// urm.addUnifyResultListener(resultListener);
|
||||
try {
|
||||
logFile = logFile == null
|
||||
? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName()))
|
||||
: logFile;
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
|
||||
System.out.println(finiteClosure);
|
||||
urm = new UnifyResultModel(cons, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
|
||||
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
UnifyType lhs, rhs;
|
||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType)
|
||||
&& ((rhs = x.getRhsType()) instanceof PlaceholderType)
|
||||
&& (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||
((PlaceholderType) lhs).setInnerType(true);
|
||||
((PlaceholderType) rhs).setInnerType(true);
|
||||
}
|
||||
return x;
|
||||
|
||||
};
|
||||
logFile.write(unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logFile.write(unifyCons.toString());
|
||||
TypeUnify unify = new TypeUnify();
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
for (SourceFile sf : this.sourceFiles.values()) {
|
||||
logFile.write(ASTTypePrinter.print(sf));
|
||||
}
|
||||
logFile.flush();
|
||||
|
||||
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream()
|
||||
.map(y -> y.getParameterList().getFormalparalist().stream()
|
||||
.filter(z -> z.getType() instanceof TypePlaceholder)
|
||||
.map(z -> ((TypePlaceholder) z.getType()).getName())
|
||||
.collect(Collectors.toCollection(HashSet::new)))
|
||||
.reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream()
|
||||
.map(y -> y.getParameterList().getFormalparalist().stream()
|
||||
.filter(z -> z.getType() instanceof TypePlaceholder)
|
||||
.map(z -> ((TypePlaceholder) z.getType()).getName())
|
||||
.collect(Collectors.toCollection(HashSet::new)))
|
||||
.reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> paraTypeVarNames = methodParaTypeVarNames;
|
||||
paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
||||
|
||||
Set<String> returnTypeVarNames = allClasses.stream()
|
||||
.map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
||||
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
|
||||
.collect(Collectors.toCollection(HashSet::new)))
|
||||
.reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
Set<String> fieldTypeVarNames = allClasses.stream()
|
||||
.map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
||||
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
|
||||
.collect(Collectors.toCollection(HashSet::new)))
|
||||
.reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
returnTypeVarNames.addAll(fieldTypeVarNames);
|
||||
|
||||
unifyCons = unifyCons.map(x -> {
|
||||
// Hier muss ueberlegt werden, ob
|
||||
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
||||
// mit disableWildcardtable() werden.
|
||||
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
||||
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
||||
// PL 2018-04-23
|
||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
|
||||
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
|
||||
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
|
||||
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
|
||||
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
|
||||
* instanceof PlaceholderType)) { if
|
||||
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
||||
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
|
||||
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
|
||||
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
|
||||
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
|
||||
* )).getVariance()); } } return y; } ); } while
|
||||
* (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*.stream().map(x -> {
|
||||
Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
for (Constraint<UnifyPair> y : x) {
|
||||
ret.add(new HashSet<>(y));
|
||||
}
|
||||
return ret;
|
||||
}).collect(Collectors.toCollection(ArrayList::new))*/;
|
||||
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
|
||||
usedTasks);
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
}
|
||||
return urm;
|
||||
}
|
||||
|
||||
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
||||
@ -364,12 +692,46 @@ public class JavaTXCompiler {
|
||||
}
|
||||
})));
|
||||
*/
|
||||
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
|
||||
* 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
|
||||
* //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
|
||||
* varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
|
||||
* -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
|
||||
* instanceof PlaceholderType)) { if
|
||||
* (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
||||
* ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
|
||||
* )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
|
||||
* && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
|
||||
* ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
|
||||
* )).getVariance()); } } return y; } ); } while
|
||||
* (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()//.stream().map(x -> {
|
||||
/*Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
for (Constraint<UnifyPair> y : x) {
|
||||
ret.add(new HashSet<>(y));
|
||||
}
|
||||
return ret;
|
||||
}).collect(Collectors.toCollection(ArrayList::new))*/;
|
||||
if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
|
||||
usedTasks);
|
||||
System.out.println("RESULT Final: " + li.getResults());
|
||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
logFile.flush();
|
||||
@ -381,7 +743,7 @@ public class JavaTXCompiler {
|
||||
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
|
||||
// finiteClosure));
|
||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints,
|
||||
finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure));
|
||||
finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
||||
System.out.println("RESULT: " + result);
|
||||
logFile.write("RES: " + result.toString() + "\n");
|
||||
logFile.flush();
|
||||
@ -532,10 +894,6 @@ public class JavaTXCompiler {
|
||||
/**
|
||||
* @param path - can be null, then class file output is in the same directory as the parsed source files
|
||||
*/
|
||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles(
|
||||
typeinferenceResult);
|
||||
generateBytecode(path, typeinferenceResult, simplifyResultsForAllSourceFiles);
|
||||
public void generateBytecode(File path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
|
||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles(
|
||||
|
@ -154,7 +154,7 @@ public class UnifyTypeFactory {
|
||||
public static Constraint<UnifyPair> convert(Constraint<Pair> constraint){
|
||||
Constraint<UnifyPair> unifyPairConstraint = constraint.stream()
|
||||
.map(UnifyTypeFactory::convert)
|
||||
.collect(Collectors.toCollection( () -> new Constraint<UnifyPair> (constraint.isInherited(), convert(constraint.getExtendConstraint()))));
|
||||
.collect(Collectors.toCollection( () -> new Constraint<UnifyPair>(convert(constraint.getExtendConstraint()))));
|
||||
return unifyPairConstraint;
|
||||
}
|
||||
|
||||
|
@ -17,15 +17,13 @@ public class MethodAssumption extends Assumption{
|
||||
private ClassOrInterface receiver;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric retType;
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
|
||||
private final Boolean isInherited;
|
||||
|
||||
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, Boolean isInherited){
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){
|
||||
super(scope);
|
||||
this.receiver = receiver;
|
||||
this.retType = retType;
|
||||
this.params = params;
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -72,8 +70,4 @@ public class MethodAssumption extends Assumption{
|
||||
|
||||
return receiverType;
|
||||
}
|
||||
|
||||
public Boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
}
|
||||
|
@ -6,32 +6,17 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
//TODO: Remove this class
|
||||
public class Constraint<A> extends HashSet<A> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint(){}
|
||||
|
||||
public Constraint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Constraint(Boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public Constraint(Boolean isInherited, Constraint<A> extendConstraint) {
|
||||
this.isInherited = isInherited;
|
||||
public Constraint(Constraint<A> extendConstraint) {
|
||||
this.extendConstraint = extendConstraint;
|
||||
}
|
||||
|
||||
public void setIsInherited(Boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public Boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public Constraint<A> getExtendConstraint() {
|
||||
return extendConstraint;
|
||||
}
|
||||
@ -41,7 +26,7 @@ public class Constraint<A> extends HashSet<A> {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + " isInherited = " + isInherited
|
||||
return super.toString()
|
||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||
+ "\n" ;
|
||||
}
|
||||
|
@ -68,9 +68,8 @@ public class ConstraintSet<A> {
|
||||
Constraint<B> newConst = as.stream()
|
||||
.map(o)
|
||||
.collect(Collectors.toCollection((as.getExtendConstraint() != null)
|
||||
? () -> new Constraint<B> (as.isInherited(),
|
||||
as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)))
|
||||
: () -> new Constraint<B> (as.isInherited())
|
||||
? () -> new Constraint<B> (as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new)))
|
||||
: () -> new Constraint<B> ()
|
||||
));
|
||||
|
||||
//CSA2CSB.put(as, newConst);
|
||||
|
@ -0,0 +1,107 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class ConstraintSet2 {
|
||||
Set<OderConstraint> oderConstraints = new HashSet<>();
|
||||
|
||||
public ConstraintSet2(Set<OderConstraint> constraints){
|
||||
if(constraints.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
this.oderConstraints = constraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
BinaryOperator<String> b = (x,y) -> x+y;
|
||||
return "ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
|
||||
}
|
||||
|
||||
private class ConstraintSpliterator implements Spliterator<Set<Pair>> {
|
||||
private List<OderConstraint> constraints;
|
||||
private long i = 0;
|
||||
private long max = 0;
|
||||
private List<Integer> sizes;
|
||||
private List<Long> bases = new ArrayList<>();
|
||||
|
||||
ConstraintSpliterator(List<OderConstraint> constraints){
|
||||
this.constraints = constraints;
|
||||
sizes = constraints.stream().map(OderConstraint::getSize).collect(Collectors.toList());
|
||||
long base = 1;
|
||||
for(int size : sizes){
|
||||
bases.add(base);
|
||||
base *= size;
|
||||
}
|
||||
i = 0;
|
||||
max = estimateSize() - 1;
|
||||
}
|
||||
|
||||
ConstraintSpliterator(List<OderConstraint> constraints, long start, long end){
|
||||
this(constraints);
|
||||
i = start;
|
||||
max = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Set<Pair>> consumer) {
|
||||
if(i > max) return false;
|
||||
consumer.accept(get(i));
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<Pair> get(long num){
|
||||
Set<Pair> ret = new HashSet<>();
|
||||
Iterator<Long> baseIt = bases.iterator();
|
||||
for(OderConstraint constraint : constraints){
|
||||
ret.addAll(constraint.get((int) ((num/baseIt.next())%constraint.getSize())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Set<Pair>> trySplit() {
|
||||
if(max - i < 2) return null;
|
||||
long middle = i + ((max- i) / 2);
|
||||
long maxOld = max;
|
||||
max = middle - 1;
|
||||
return new ConstraintSpliterator(constraints, middle, maxOld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
long ret = 1;
|
||||
for (int size : sizes)ret*=size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return ORDERED | SIZED | IMMUTABLE | NONNULL;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream<Set<Pair>> cartesianProductParallel(){
|
||||
return StreamSupport.stream(new ConstraintSpliterator(oderConstraints.stream().collect(Collectors.toList())), true);
|
||||
}
|
||||
/*
|
||||
public Map<String, TypePlaceholder> generateTPHMap() {
|
||||
HashMap<String, TypePlaceholder> ret = new HashMap<>();
|
||||
constraints.map((Pair p) -> {
|
||||
if (p.TA1 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
|
||||
}
|
||||
if (p.TA2 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConstraintSetBuilder {
|
||||
private Set<Pair> undConstraints = new HashSet<>();
|
||||
private Set<OderConstraint> oderConstraints = new HashSet<>();
|
||||
private boolean done = false;
|
||||
|
||||
public void addUndConstraint(Pair p){
|
||||
undConstraints.add(p);
|
||||
}
|
||||
|
||||
public void addOderConstraint(OderConstraint orConstraint) {
|
||||
oderConstraints.add(orConstraint);
|
||||
}
|
||||
|
||||
public ConstraintSet2 build(){
|
||||
if(done)throw new RuntimeException("Trying to build cartesian product twice");
|
||||
this.done = true;
|
||||
if(!undConstraints.isEmpty())
|
||||
oderConstraints.add(new OderConstraint(Set.of(undConstraints)));
|
||||
return new ConstraintSet2(oderConstraints);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OderConstraint {
|
||||
private final List<Set<Pair>> cons;
|
||||
public OderConstraint(Set<Set<Pair>> orCons){
|
||||
if(orCons.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
for(Set<Pair> c : orCons){
|
||||
if(c.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
}
|
||||
this.cons = orCons.stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int getSize(){
|
||||
return cons.size();
|
||||
}
|
||||
|
||||
public Set<Pair> get(int l) {
|
||||
return cons.get(l);
|
||||
}
|
||||
}
|
@ -179,7 +179,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
!(x.TA2 instanceof TypePlaceholder))
|
||||
? new Pair(x.TA1, new ExtendsWildcardType(x.TA2, x.TA2.getOffset()), PairOperator.EQUALSDOT)
|
||||
: x)
|
||||
.collect(Collectors.toCollection(() -> new Constraint<Pair>(oneMethodConstraint.isInherited())));
|
||||
.collect(Collectors.toCollection(() -> new Constraint<Pair>()));
|
||||
oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint);
|
||||
extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint);
|
||||
methodConstraints.add(extendsOneMethodConstraint);
|
||||
@ -574,7 +574,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
|
||||
TypeInferenceBlockInformation info, GenericsResolver resolver){
|
||||
Constraint<Pair> methodConstraint = new Constraint<>(assumption.isInherited());
|
||||
Constraint<Pair> methodConstraint = new Constraint<>();
|
||||
ClassOrInterface receiverCl = assumption.getReceiver();
|
||||
/*
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
@ -636,7 +636,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}, false));
|
||||
}));
|
||||
}
|
||||
for(ClassOrInterface cl : info.getAvailableClasses()){
|
||||
for(Method m : cl.getMethods()){
|
||||
@ -645,7 +645,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
|
||||
|
||||
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
|
||||
createTypeScope(cl, m), m.isInherited));
|
||||
createTypeScope(cl, m)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -680,7 +680,7 @@ public class TYPEStmt implements StatementVisitor{
|
||||
for(Method m : cl.getConstructors()){
|
||||
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
|
||||
ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(),
|
||||
info), createTypeScope(cl, m), m.isInherited));
|
||||
info), createTypeScope(cl, m)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -682,9 +682,8 @@ public class RuleSet implements IRuleSet{
|
||||
Function<? super Constraint<UnifyPair>,? extends Constraint<UnifyPair>> applyUni = b -> b.stream().map(
|
||||
x -> uni.apply(pair,x)).collect(Collectors.toCollection((b.getExtendConstraint() != null)
|
||||
? () -> new Constraint<UnifyPair>(
|
||||
b.isInherited(),
|
||||
b.getExtendConstraint().stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(Constraint::new)))
|
||||
: () -> new Constraint<UnifyPair>(b.isInherited())
|
||||
: () -> new Constraint<UnifyPair>()
|
||||
));
|
||||
oderConstraints.replaceAll(oc -> oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new)));
|
||||
/*
|
||||
|
@ -28,8 +28,8 @@ public class TypeUnify {
|
||||
* @param cons
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
|
||||
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
@ -54,8 +54,8 @@ public class TypeUnify {
|
||||
* @param ret
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
|
||||
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
return ret;
|
||||
@ -68,11 +68,12 @@ public class TypeUnify {
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @param ret
|
||||
* @return
|
||||
*/
|
||||
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
|
||||
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
pool.invoke(unifyTask);
|
||||
Set<Set<UnifyPair>> res = unifyTask.join();
|
||||
@ -101,10 +102,11 @@ public class TypeUnify {
|
||||
* @param fc
|
||||
* @param logFile
|
||||
* @param log
|
||||
* @param cons
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret);
|
||||
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
|
||||
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret, usedTasks);
|
||||
Set<Set<UnifyPair>> res = unifyTask.compute();
|
||||
try {
|
||||
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
|
||||
|
@ -1,30 +0,0 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeUnify2Future {
|
||||
|
||||
Set<Set<UnifyPair>> setToFlatten;
|
||||
|
||||
public TypeUnify2Future(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm);
|
||||
this.setToFlatten = setToFlatten;
|
||||
this.nextSetElement = nextSetElement;
|
||||
}
|
||||
|
||||
Set<UnifyPair> getNextSetElement() {
|
||||
return nextSetElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Set<UnifyPair>> compute() {
|
||||
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField, true);
|
||||
return res;
|
||||
}
|
||||
}
|
@ -18,8 +18,8 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
|
||||
Set<Set<UnifyPair>> setToFlatten;
|
||||
|
||||
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm);
|
||||
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
|
||||
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
this.setToFlatten = setToFlatten;
|
||||
this.nextSetElement = nextSetElement;
|
||||
}
|
||||
@ -30,7 +30,35 @@ public class TypeUnify2Task extends TypeUnifyTask {
|
||||
|
||||
@Override
|
||||
protected Set<Set<UnifyPair>> compute() {
|
||||
if (one) {
|
||||
System.out.println("two");
|
||||
}
|
||||
one = true;
|
||||
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField, true);
|
||||
return res;
|
||||
/*if (isUndefinedPairSetSet(res)) {
|
||||
return new HashSet<>(); }
|
||||
else
|
||||
*/
|
||||
//writeLog("xxx");
|
||||
//noOfThread--;
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeLogFile() {
|
||||
|
||||
try {
|
||||
logFile.close();
|
||||
}
|
||||
catch (IOException ioE) {
|
||||
System.err.println("no log-File" + thNo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -60,33 +60,7 @@ import com.google.common.collect.Ordering;
|
||||
* Implementation of the type unification algorithm
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class TypeUnifyTask {
|
||||
|
||||
public static Set<Set<UnifyPair>> typeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm){
|
||||
Set<UnifyPair> neweq = new HashSet<>(eq);
|
||||
/* 1-elementige Oder-Constraints werden in und-Constraints umgewandelt */
|
||||
oderConstraints.stream()
|
||||
.filter(x -> x.size()==1)
|
||||
.map(y -> y.stream().findFirst().get()).forEach(x -> neweq.addAll(x));
|
||||
ArrayList<Set<Constraint<UnifyPair>>> remainingOderconstraints = oderConstraints.stream()
|
||||
.filter(x -> x.size()>1)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefe, true);
|
||||
try {
|
||||
logFile.close();
|
||||
}
|
||||
catch (IOException ioE) {
|
||||
System.err.println("no log-File");
|
||||
}
|
||||
if (isUndefinedPairSetSet(res)) {
|
||||
throw new TypeinferenceException("Unresolved constraints: " + res.toString(), new NullToken()); //return new HashSet<>();
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static int i = 0;
|
||||
@ -97,11 +71,16 @@ public class TypeUnifyTask {
|
||||
* Element, das aus dem nextSet den Gleichunen dieses Threads hinzugefuegt wurde
|
||||
*/
|
||||
Set<UnifyPair> nextSetElement;
|
||||
Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm
|
||||
|
||||
/**
|
||||
* Fuer die Threads
|
||||
*/
|
||||
UnifyResultModel urm;
|
||||
protected static int noOfThread = 0;
|
||||
private static int totalnoOfThread = 0;
|
||||
int thNo;
|
||||
protected boolean one = false;
|
||||
Integer MaxNoOfThreads = 8;
|
||||
|
||||
public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/";
|
||||
Writer logFile;
|
||||
@ -144,13 +123,31 @@ public class TypeUnifyTask {
|
||||
static int noBacktracking;
|
||||
|
||||
static Integer noShortendElements = 0;
|
||||
|
||||
|
||||
Boolean myIsCanceled = false;
|
||||
|
||||
volatile UnifyTaskModel usedTasks;
|
||||
|
||||
public TypeUnifyTask() {
|
||||
rules = new RuleSet();
|
||||
}
|
||||
|
||||
/*
|
||||
public TypeUnifyTask(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log) {
|
||||
this.eq = eq;
|
||||
this.fc = fc;
|
||||
this.oup = new OrderingUnifyPair(fc);
|
||||
this.parallel = parallel;
|
||||
this.logFile = logFile;
|
||||
this.log = log;
|
||||
rules = new RuleSet(logFile);
|
||||
noOfThread++;
|
||||
thNo = noOfThread;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) {
|
||||
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
|
||||
synchronized (this) {
|
||||
this.eq = eq;
|
||||
//this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new));
|
||||
@ -170,7 +167,21 @@ public class TypeUnifyTask {
|
||||
this.parallel = parallel;
|
||||
this.logFile = logFile;
|
||||
this.log = log;
|
||||
|
||||
|
||||
noOfThread++;
|
||||
totalnoOfThread++;
|
||||
//writeLog("thNo1 " + thNo);
|
||||
thNo = totalnoOfThread;
|
||||
writeLog("thNo2 " + thNo);
|
||||
try {
|
||||
this.logFile = //new OutputStreamWriter(new NullOutputStream());
|
||||
//new FileWriter(new File(System.getProperty("user.dir")+"/src/test/resources/logFiles/"+"Thread_"+thNo));
|
||||
new FileWriter(new File(System.getProperty("user.dir")+"/logFiles/"+"Thread_"+thNo));
|
||||
logFile.write("");
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("log-File nicht vorhanden");
|
||||
}
|
||||
/*Abbruchtest
|
||||
if (thNo > 10) {
|
||||
System.out.println("cancel");
|
||||
@ -188,10 +199,56 @@ public class TypeUnifyTask {
|
||||
rules = new RuleSet(logFile);
|
||||
this.rekTiefeField = rekTiefe;
|
||||
this.urm = urm;
|
||||
this.usedTasks = usedTasks;
|
||||
this.usedTasks.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vererbt alle Variancen
|
||||
* @param eq The set of constraints
|
||||
*/
|
||||
/* PL 2018-05- 17 verschoben nach JavaTXCompiler
|
||||
private void varianceInheritance(Set<UnifyPair> eq) {
|
||||
Set<PlaceholderType> usedTPH = new HashSet<>();
|
||||
Set<PlaceholderType> phSet = eq.stream().map(x -> {
|
||||
Set<PlaceholderType> pair = new HashSet<>();
|
||||
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType());
|
||||
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType());
|
||||
return pair;
|
||||
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;});
|
||||
|
||||
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
|
||||
phSetVariance.removeIf(x -> (x.getVariance() == 0));
|
||||
while(!phSetVariance.isEmpty()) {
|
||||
PlaceholderType a = phSetVariance.remove(0);
|
||||
usedTPH.add(a);
|
||||
//HashMap<PlaceholderType,Integer> ht = new HashMap<>();
|
||||
//ht.put(a, a.getVariance());
|
||||
Set<UnifyPair> eq1 = new HashSet<>(eq);
|
||||
eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a)));
|
||||
eq1.stream().forEach(x -> { x.getRhsType().accept(new distributeVariance(), a.getVariance());});
|
||||
eq1 = new HashSet<>(eq);
|
||||
eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
|
||||
eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(), a.getVariance());});
|
||||
phSetVariance = new ArrayList<>(phSet);
|
||||
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
|
||||
}
|
||||
}
|
||||
*/
|
||||
void myCancel(Boolean b) {
|
||||
myIsCanceled = true;
|
||||
}
|
||||
|
||||
public boolean myIsCancelled() {
|
||||
return myIsCanceled;
|
||||
}
|
||||
|
||||
protected Set<Set<UnifyPair>> compute() {
|
||||
if (one) {
|
||||
System.out.println("two");
|
||||
}
|
||||
one = true;
|
||||
Set<UnifyPair> neweq = new HashSet<>(eq);
|
||||
/* 1-elementige Oder-Constraints werden in und-Constraints umgewandelt */
|
||||
oderConstraintsField.stream()
|
||||
@ -201,6 +258,7 @@ public class TypeUnifyTask {
|
||||
.filter(x -> x.size()>1)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefeField, true);
|
||||
noOfThread--;
|
||||
try {
|
||||
logFile.close();
|
||||
}
|
||||
@ -211,10 +269,15 @@ public class TypeUnifyTask {
|
||||
throw new TypeinferenceException("Unresolved constraints: " + res.toString(), new NullToken()); //return new HashSet<>();
|
||||
}
|
||||
else {
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
@ -236,9 +299,28 @@ public class TypeUnifyTask {
|
||||
* @param fc The finite closure
|
||||
* @return The set of all principal type unifiers
|
||||
*/
|
||||
protected static Set<Set<UnifyPair>> unify(final Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
|
||||
protected Set<Set<UnifyPair>> unify(final Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
|
||||
//Set<UnifyPair> aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT)
|
||||
// ).collect(Collectors.toCollection(HashSet::new));
|
||||
//writeLog(nOfUnify.toString() + " AA: " + aas.toString());
|
||||
//if (aas.isEmpty()) {
|
||||
// System.out.println("");
|
||||
//}
|
||||
|
||||
//.collect(Collectors.toCollection(HashSet::new)));
|
||||
/*
|
||||
* Step 1: Repeated application of reduce, adapt, erase, swap
|
||||
*/
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
rekTiefe++;
|
||||
nOfUnify++;
|
||||
writeLog(nOfUnify.toString() + " Unifikation: " + eq.toString());
|
||||
writeLog(nOfUnify.toString() + " Oderconstraints: " + oderConstraints.toString());
|
||||
|
||||
/*
|
||||
* Variancen auf alle Gleichungen vererben
|
||||
@ -375,7 +457,7 @@ public class TypeUnifyTask {
|
||||
|
||||
//Aufruf von computeCartesianRecursive ANFANG
|
||||
//writeLog("topLevelSets: " + topLevelSets.toString());
|
||||
return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, oderConstraintsOutput, fc, rekTiefe, finalresult);
|
||||
return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, oderConstraintsOutput, fc, parallel, rekTiefe, finalresult);
|
||||
|
||||
}
|
||||
|
||||
@ -383,7 +465,22 @@ public class TypeUnifyTask {
|
||||
Set<Set<UnifyPair>> unify2(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
|
||||
//Aufruf von computeCartesianRecursive ENDE
|
||||
|
||||
|
||||
//keine Ahnung woher das kommt
|
||||
//Set<Set<UnifyPair>> setToFlatten = topLevelSets.stream().map(x -> x.iterator().next()).collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
|
||||
// Cartesian product over all (up to 10) top level sets
|
||||
//Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets)
|
||||
// .stream().map(x -> new HashSet<>(x))
|
||||
// .collect(Collectors.toCollection(HashSet::new));
|
||||
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
|
||||
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
|
||||
|
||||
Set<TypeUnifyTask> forks = new HashSet<>();
|
||||
@ -406,9 +503,47 @@ public class TypeUnifyTask {
|
||||
Set<Set<UnifyPair>> unifyres1 = null;
|
||||
Set<Set<UnifyPair>> unifyres2 = null;
|
||||
if (!ocString.equals(newOderConstraints.toString())) writeLog("nach Subst: " + newOderConstraints);
|
||||
{// sequentiell (Step 6b is included)
|
||||
//writeLog("nach Subst: " + eqPrimePrime);
|
||||
/*
|
||||
* Step 6 a) Restart (fork) for pairs where subst was applied
|
||||
*/
|
||||
/*
|
||||
if(parallel) {
|
||||
if (eqPrime.equals(eq) && !eqPrimePrime.isPresent()
|
||||
&& oderConstraints.isEmpty()) {
|
||||
&& oderConstraints.isEmpty()) //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch
|
||||
//PL 2017-09-29 dies ersetzt //(!eqPrimePrime.isPresent())
|
||||
//PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst
|
||||
//eqPrimePrime Veraenderungen in subst repraesentieren.
|
||||
eqPrimePrimeSet.add(eqPrime);
|
||||
else if(eqPrimePrime.isPresent()) {
|
||||
//System.out.println("nextStep: " + eqPrimePrime.get());
|
||||
TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true, logFile, log);
|
||||
forks.add(fork);
|
||||
fork.fork();
|
||||
}
|
||||
else {
|
||||
//System.out.println("nextStep: " + eqPrime);
|
||||
TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true, logFile, log);
|
||||
forks.add(fork);
|
||||
fork.fork();
|
||||
}
|
||||
}
|
||||
else */
|
||||
{// sequentiell (Step 6b is included)
|
||||
if (printtag) System.out.println("nextStep: " + eqPrimePrime);
|
||||
if (eqPrime.equals(eq) && !eqPrimePrime.isPresent()
|
||||
&& oderConstraints.isEmpty()) { //PL 2017-09-29 //(!eqPrimePrime.isPresent()) auskommentiert und durch
|
||||
//PL 2017-09-29 dies ersetzt //(!eqPrimePrime.isPresent())
|
||||
//PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst
|
||||
//eqPrimePrime Veraenderungen in subst repraesentieren.
|
||||
//try {
|
||||
//if (isSolvedForm(eqPrime)) {
|
||||
// writeLog("eqPrime:" + eqPrime.toString()+"\n");
|
||||
//}
|
||||
//}
|
||||
//catch (IOException e) {
|
||||
// System.err.println("log-File nicht vorhanden");
|
||||
//}
|
||||
eqPrimePrimeSet.add(eqPrime);
|
||||
if (finalresult && isSolvedForm(eqPrime)) {
|
||||
writeLog("eqPrime:" + eqPrime.toString()+"\n");
|
||||
@ -427,6 +562,23 @@ public class TypeUnifyTask {
|
||||
eqPrimePrimeSet.addAll(unifyres);
|
||||
}
|
||||
}
|
||||
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
|
||||
//}
|
||||
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
|
||||
|
||||
/*
|
||||
* Step 6 b) Build the union over everything.
|
||||
*/
|
||||
/*
|
||||
* PL 2019-01-22: geloescht
|
||||
|
||||
if(parallel)
|
||||
for(TypeUnifyTask fork : forks)
|
||||
eqPrimePrimeSet.addAll(fork.join());
|
||||
*/
|
||||
/*
|
||||
* Step 7: Filter empty sets;
|
||||
*/
|
||||
eqPrimePrimeSet = eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x) || this.isUndefinedPairSet(x)).collect(Collectors.toCollection(HashSet::new));
|
||||
if (!eqPrimePrimeSet.isEmpty() && !isUndefinedPairSetSet(eqPrimePrimeSet)) {
|
||||
writeLog("Result1 " + eqPrimePrimeSet.toString());
|
||||
@ -436,7 +588,9 @@ public class TypeUnifyTask {
|
||||
|
||||
|
||||
|
||||
Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<? extends Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, int rekTiefe, Boolean finalresult) {
|
||||
Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<? extends Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
|
||||
//ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets);
|
||||
|
||||
fstElems.addAll(topLevelSets.stream()
|
||||
.filter(x -> x.size()==1)
|
||||
.map(y -> y.stream().findFirst().get())
|
||||
@ -449,8 +603,17 @@ public class TypeUnifyTask {
|
||||
return result;
|
||||
}
|
||||
Set<? extends Set<UnifyPair>> nextSet = remainingSets.remove(0);
|
||||
//writeLog("nextSet: " + nextSet.toString());
|
||||
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
|
||||
|
||||
/*
|
||||
try {
|
||||
//List<Set<UnifyPair>>
|
||||
//nextSetasList = oup.sortedCopy(nextSet);//new ArrayList<>(nextSet);
|
||||
}
|
||||
catch (java.lang.IllegalArgumentException e) {
|
||||
System.out.print("");
|
||||
}
|
||||
*/
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
int variance = 0;
|
||||
|
||||
@ -507,15 +670,25 @@ public class TypeUnifyTask {
|
||||
System.out.print("");
|
||||
if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
|
||||
System.out.print("");
|
||||
|
||||
//writeLog("nextSetasList: " + nextSetasList.toString());
|
||||
Set<UnifyPair> nextSetElem = nextSetasList.get(0);
|
||||
//writeLog("BasePair1: " + nextSetElem + " " + nextSetElem.iterator().next().getBasePair());
|
||||
|
||||
/* sameEqSet-Bestimmung: Wenn a = ty \in nextSet dann enthaelt sameEqSet alle Paare a < ty1 oder ty2 < a aus fstElems */
|
||||
Set<UnifyPair> sameEqSet = new HashSet<>();
|
||||
Optional<UnifyPair> optOrigPair = null;
|
||||
//if (variance != 2) {
|
||||
if (!oderConstraint) {
|
||||
optOrigPair = nextSetElem.stream().filter(x -> (
|
||||
(x.getPairOp().equals(PairOperator.EQUALSDOT)
|
||||
//x.getBasePair() != null && ist gegeben wenn variance != 2
|
||||
//x.getBasePair().getPairOp().equals(PairOperator.SMALLERDOT) &&
|
||||
(x.getPairOp().equals(PairOperator.EQUALSDOT)
|
||||
/*
|
||||
(x.getBasePair().getLhsType() instanceof PlaceholderType
|
||||
&& x.getLhsType().equals(x.getBasePair().getLhsType()))
|
||||
|| (x.getBasePair().getRhsType() instanceof PlaceholderType
|
||||
&& x.getLhsType().equals(x.getBasePair().getRhsType())
|
||||
*/
|
||||
))).filter(x -> //Sicherstellen, dass bei a = ty a auch wirklich die gesuchte Typvariable ist
|
||||
x.getLhsType().equals(x.getBasePair().getLhsType()) ||
|
||||
x.getLhsType().equals(x.getBasePair().getRhsType())
|
||||
@ -664,7 +837,7 @@ public class TypeUnifyTask {
|
||||
}
|
||||
/* PL 2019-03-11 Ende eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
|
||||
|
||||
if(parallel && (variance == 1)) {
|
||||
if(parallel && (variance == 1) && noOfThread <= MaxNoOfThreads) {
|
||||
Set<TypeUnify2Task> forks = new HashSet<>();
|
||||
Set<UnifyPair> newEqOrig = new HashSet<>(eq);
|
||||
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
|
||||
@ -672,8 +845,14 @@ public class TypeUnifyTask {
|
||||
newElemsOrig.add(a);
|
||||
|
||||
/* FORK ANFANG */
|
||||
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm);
|
||||
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
//forks.add(forkOrig);
|
||||
synchronized(usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
forkOrig.fork();
|
||||
}
|
||||
/* FORK ENDE */
|
||||
|
||||
synchronized (this) {
|
||||
@ -722,14 +901,41 @@ public class TypeUnifyTask {
|
||||
Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
|
||||
newElems.add(nSaL);
|
||||
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm);
|
||||
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
forks.add(fork);
|
||||
synchronized(usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
fork.fork();
|
||||
}
|
||||
}
|
||||
//res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe);
|
||||
|
||||
res = forkOrig.join();
|
||||
|
||||
|
||||
/* FORK ANFANG */
|
||||
synchronized (this) {
|
||||
writeLog("wait "+ forkOrig.thNo);
|
||||
noOfThread--;
|
||||
res = forkOrig.join();
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
//noOfThread++;
|
||||
forkOrig.writeLog("final Orig 1");
|
||||
forkOrig.closeLogFile();
|
||||
//Set<Set<UnifyPair>> fork_res = forkOrig.join();
|
||||
writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString());
|
||||
//noOfThread--; an das Ende von compute verschoben
|
||||
//add_res.add(fork_res);
|
||||
};
|
||||
/* FORK ENDE */
|
||||
|
||||
forks.forEach(x -> writeLog("wait: " + x.thNo));
|
||||
for(TypeUnify2Task fork : forks) {
|
||||
synchronized (this) {
|
||||
noOfThread--;
|
||||
Set<Set<UnifyPair>> fork_res = fork.join();
|
||||
synchronized (usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
@ -746,18 +952,28 @@ public class TypeUnifyTask {
|
||||
aParDef.add(fork.getNextSetElement());
|
||||
}
|
||||
fork.writeLog("final 1");
|
||||
fork.closeLogFile();
|
||||
};
|
||||
}
|
||||
//noOfThread++;
|
||||
} else {
|
||||
if((variance == -1)) {
|
||||
if(parallel && (variance == -1) && noOfThread <= MaxNoOfThreads) {
|
||||
Set<TypeUnify2Task> forks = new HashSet<>();
|
||||
Set<UnifyPair> newEqOrig = new HashSet<>(eq);
|
||||
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
|
||||
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
|
||||
newElemsOrig.add(a);
|
||||
|
||||
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm);
|
||||
|
||||
/* FORK ANFANG */
|
||||
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
|
||||
//forks.add(forkOrig);
|
||||
synchronized(usedTasks) {
|
||||
if (this.myIsCancelled()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
forkOrig.fork();
|
||||
}
|
||||
/* FORK ENDE */
|
||||
|
||||
synchronized (this) {
|
||||
writeLog("a in " + variance + " "+ a);
|
||||
@ -1088,7 +1304,6 @@ public class TypeUnifyTask {
|
||||
Set<UnifyPair> a_new = aParDefIt.next();
|
||||
List<Set<UnifyPair>> smallerSetasList = oup.smallerThan(a_new, nextSetasList);
|
||||
List<Set<UnifyPair>> notInherited = smallerSetasList.stream()
|
||||
.filter(x -> !((Constraint<UnifyPair>)x).isInherited())
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
List<Set<UnifyPair>> notErased = new ArrayList<>();
|
||||
notInherited.stream().forEach(x -> { notErased.addAll(oup.smallerEqThan(x, smallerSetasList)); });
|
||||
@ -1130,11 +1345,10 @@ public class TypeUnifyTask {
|
||||
List<Set<UnifyPair>> greaterSetasList = oup.greaterThan(a_new, nextSetasList);
|
||||
|
||||
//a_new muss hingefuegt werden, wenn es nicht vererbt ist, dann wird es spaeter wieder geloescht
|
||||
if (!((Constraint<UnifyPair>)a_new).isInherited()) {
|
||||
greaterSetasList.add(a_new);
|
||||
}
|
||||
|
||||
greaterSetasList.add(a_new);
|
||||
|
||||
List<Set<UnifyPair>> notInherited = greaterSetasList.stream()
|
||||
.filter(x -> !((Constraint<UnifyPair>)x).isInherited())
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
List<Set<UnifyPair>> notErased = new ArrayList<>();
|
||||
|
||||
@ -1185,7 +1399,6 @@ public class TypeUnifyTask {
|
||||
writeLog("Removed: " + nextSetasListOderConstraints);
|
||||
List<Set<UnifyPair>> smallerSetasList = oup.smallerThan(a, nextSetasList);
|
||||
List<Set<UnifyPair>> notInherited = smallerSetasList.stream()
|
||||
.filter(x -> !((Constraint<UnifyPair>)x).isInherited())
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
List<Set<UnifyPair>> notErased = new ArrayList<>();
|
||||
notInherited.stream().forEach(x -> { notErased.addAll(oup.smallerEqThan(x, smallerSetasList)); });
|
||||
@ -1412,7 +1625,7 @@ public class TypeUnifyTask {
|
||||
return true;}).reduce((xx, yy) -> xx || yy).get();
|
||||
}
|
||||
|
||||
protected static boolean isUndefinedPairSet(Set<UnifyPair> s) {
|
||||
protected boolean isUndefinedPairSet(Set<UnifyPair> s) {
|
||||
if (s.size() >= 1 ) {
|
||||
Boolean ret = s.stream().map(x -> x.isUndefinedPair()).reduce(true, (x,y)-> (x && y));
|
||||
return ret;
|
||||
@ -1422,7 +1635,7 @@ public class TypeUnifyTask {
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean isUndefinedPairSetSet(Set<Set<UnifyPair>> s) {
|
||||
protected boolean isUndefinedPairSetSet(Set<Set<UnifyPair>> s) {
|
||||
if (s.size() >= 1) {
|
||||
Boolean ret = s.stream(). map(x -> isUndefinedPairSet(x)).reduce(true, (x,y)-> (x && y));
|
||||
return ret;
|
||||
@ -1481,7 +1694,7 @@ public class TypeUnifyTask {
|
||||
/*
|
||||
* Apply rules until the queue is empty
|
||||
*/
|
||||
while(!eqQueue.isEmpty()) {
|
||||
while(!eqQueue.isEmpty()) {
|
||||
UnifyPair pair = eqQueue.pollFirst();
|
||||
|
||||
// ReduceUp, ReduceLow, ReduceUpLow
|
||||
|
@ -0,0 +1,18 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
public class UnifyResultEvent {
|
||||
|
||||
private List<ResultSet> newTypeResult;
|
||||
|
||||
public UnifyResultEvent(List<ResultSet> newTypeResult) {
|
||||
this.newTypeResult = newTypeResult;
|
||||
}
|
||||
|
||||
public List<ResultSet> getNewTypeResult() {
|
||||
return newTypeResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
public interface UnifyResultListener {
|
||||
|
||||
void onNewTypeResultFound(UnifyResultEvent evt);
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
public class UnifyResultListenerImpl implements UnifyResultListener {
|
||||
|
||||
List<ResultSet> results = new ArrayList<>();
|
||||
|
||||
public synchronized void onNewTypeResultFound(UnifyResultEvent evt) {
|
||||
results.addAll(evt.getNewTypeResult());
|
||||
}
|
||||
|
||||
public List<ResultSet> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
public class UnifyResultModel {
|
||||
|
||||
ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons;
|
||||
|
||||
IFiniteClosure fc;
|
||||
|
||||
public UnifyResultModel(ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons,
|
||||
IFiniteClosure fc) {
|
||||
this.cons = cons;
|
||||
this.fc = fc;
|
||||
}
|
||||
|
||||
private List<UnifyResultListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addUnifyResultListener(UnifyResultListener listenerToAdd) {
|
||||
listeners.add(listenerToAdd);
|
||||
}
|
||||
|
||||
public void removeUnifyResultListener(UnifyResultListener listenerToRemove) {
|
||||
listeners.remove(listenerToRemove);
|
||||
}
|
||||
|
||||
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
|
||||
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
|
||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
|
||||
return y; //alle Paare a <.? b erden durch a =. b ersetzt
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
|
||||
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc);
|
||||
}
|
||||
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
|
||||
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
|
||||
.collect(Collectors.toList());
|
||||
UnifyResultEvent evt = new UnifyResultEvent(newResult);
|
||||
|
||||
for (UnifyResultListener listener : listeners) {
|
||||
listener.onNewTypeResultFound(evt);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UnifyTaskModel {
|
||||
|
||||
ArrayList<TypeUnifyTask> usedTasks = new ArrayList<>();
|
||||
|
||||
public synchronized void add(TypeUnifyTask t) {
|
||||
usedTasks.add(t);
|
||||
}
|
||||
|
||||
public synchronized void cancel() {
|
||||
for(TypeUnifyTask t : usedTasks) {
|
||||
t.myCancel(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,6 +29,8 @@ public class UnifyPair {
|
||||
*/
|
||||
private PairOperator pairOp;
|
||||
|
||||
private boolean undefinedPair = false;
|
||||
|
||||
/**
|
||||
* Unifier/substitute that generated this pair
|
||||
* PL 2018-03-15
|
||||
@ -112,7 +114,10 @@ public class UnifyPair {
|
||||
public void addSubstitutions(Set<UnifyPair> sup) {
|
||||
substitution.addAll(sup);
|
||||
}
|
||||
|
||||
|
||||
public void setUndefinedPair() {
|
||||
undefinedPair = true;
|
||||
}
|
||||
public Set<UnifyPair> getSubstitution() {
|
||||
return new HashSet<>(substitution);
|
||||
}
|
||||
@ -120,6 +125,10 @@ public class UnifyPair {
|
||||
public UnifyPair getBasePair() {
|
||||
return basePair;
|
||||
}
|
||||
public boolean isUndefinedPair() {
|
||||
return undefinedPair;
|
||||
}
|
||||
|
||||
public Set<UnifyPair> getAllSubstitutions () {
|
||||
Set<UnifyPair> ret = new HashSet<>();
|
||||
ret.addAll(new ArrayList<>(getSubstitution()));
|
||||
|
@ -0,0 +1,108 @@
|
||||
package de.dhbwstuttgart.unify2;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Implementation of the Martelli-Montanari unification algorithm.
|
||||
* @author Florian Steurer
|
||||
*/
|
||||
public class MartelliMontanariUnify {
|
||||
|
||||
/**
|
||||
* Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
|
||||
* sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
|
||||
* @param terms The set of terms to be unified
|
||||
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
|
||||
*/
|
||||
public static Optional<Unifier> unify(UnifyType... terms) {
|
||||
return unify(Arrays.stream(terms).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
public static Optional<Unifier> unify(Set<UnifyType> terms) {
|
||||
// Sets with less than 2 terms are trivially unified
|
||||
if(terms.size() < 2)
|
||||
return Optional.of(Unifier.identity());
|
||||
|
||||
// For the the set of terms {t1,...,tn},
|
||||
// build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....}
|
||||
ArrayList<UnifyPair> termsList = new ArrayList<UnifyPair>();
|
||||
Iterator<UnifyType> iter = terms.iterator();
|
||||
UnifyType prev = iter.next();
|
||||
while(iter.hasNext()) {
|
||||
UnifyType next = iter.next();
|
||||
termsList.add(new UnifyPair(prev, next, PairOperator.EQUALSDOT));
|
||||
prev = next;
|
||||
}
|
||||
|
||||
// Start with the identity unifier. Substitutions will be added later.
|
||||
Unifier mgu = Unifier.identity();
|
||||
|
||||
// Apply rules while possible
|
||||
int idx = 0;
|
||||
while(idx < termsList.size()) {
|
||||
UnifyPair pair = termsList.get(idx);
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
|
||||
// REDUCE - Rule
|
||||
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
// f<...> = g<...> with f != g are not unifiable
|
||||
if(!rhsType.getName().equals(lhsType.getName()))
|
||||
return Optional.empty(); // conflict
|
||||
// f<t1,...,tn> = f<s1,...,sm> are not unifiable
|
||||
if(rhsTypeParams.size() != lhsTypeParams.size())
|
||||
return Optional.empty(); // conflict
|
||||
// f = g is not unifiable (cannot be f = f because erase rule would have been applied)
|
||||
//if(rhsTypeParams.size() == 0)
|
||||
//return Optional.empty();
|
||||
|
||||
// Unpack the arguments
|
||||
for(int i = 0; i < rhsTypeParams.size(); i++)
|
||||
result.add(new UnifyPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT));
|
||||
|
||||
termsList.remove(idx);
|
||||
termsList.addAll(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
// DELETE - Rule
|
||||
if(pair.getRhsType().equals(pair.getLhsType())) {
|
||||
termsList.remove(idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
// SWAP - Rule
|
||||
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||
termsList.remove(idx);
|
||||
termsList.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
|
||||
continue;
|
||||
}
|
||||
|
||||
// OCCURS-CHECK
|
||||
if(pair.getLhsType() instanceof PlaceholderType
|
||||
&& pair.getRhsType().getTypeParams().occurs((PlaceholderType) pair.getLhsType()))
|
||||
return Optional.empty();
|
||||
|
||||
// SUBST - Rule
|
||||
if(lhsType instanceof PlaceholderType) {
|
||||
mgu.add((PlaceholderType) lhsType, rhsType);
|
||||
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
|
||||
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
|
||||
idx = idx+1 == termsList.size() ? 0 : idx+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
return Optional.of(mgu);
|
||||
}
|
||||
}
|
922
src/main/java/de/dhbwstuttgart/unify2/RuleSet.java
Normal file
922
src/main/java/de/dhbwstuttgart/unify2/RuleSet.java
Normal file
@ -0,0 +1,922 @@
|
||||
package de.dhbwstuttgart.unify2;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Implementation of the type inference rules.
|
||||
* @author Florian Steurer
|
||||
*
|
||||
*/
|
||||
public class RuleSet {
|
||||
|
||||
/**
|
||||
* Repeatedly applies type unification rules to a set of equations.
|
||||
* This is step one of the unification algorithm.
|
||||
* @return The set of pairs that results from repeated application of the inference rules.
|
||||
*/
|
||||
public static Set<UnifyPair> applyTypeUnificationRules(Set<UnifyPair> 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<UnifyPair> targetSet = new LinkedHashSet<UnifyPair>();
|
||||
LinkedList<UnifyPair> eqQueue = new LinkedList<>();
|
||||
|
||||
/*
|
||||
* Swap all pairs and erase all erasable pairs
|
||||
*/
|
||||
eq.forEach(x -> swapAddOrErase(x, fc, eqQueue));
|
||||
|
||||
/*
|
||||
* Apply rules until the queue is empty
|
||||
*/
|
||||
while(!eqQueue.isEmpty()) {
|
||||
UnifyPair pair = eqQueue.pollFirst();
|
||||
|
||||
// ReduceUp, ReduceLow, ReduceUpLow
|
||||
Optional<UnifyPair> opt = RuleSet.reduceUpLow(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceLow(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceUp(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceWildcardLow(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceWildcardLowRight(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceWildcardUp(pair);
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceWildcardUpRight(pair);
|
||||
//PL 2018-03-06 auskommentiert muesste falsch sein vgl. JAVA_BSP/Wildcard6.java
|
||||
//opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair);
|
||||
//opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair);
|
||||
//opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair);
|
||||
|
||||
// Reduce TPH
|
||||
opt = opt.isPresent() ? opt : RuleSet.reduceTph(pair);
|
||||
|
||||
// One of the rules has been applied
|
||||
if(opt.isPresent()) {
|
||||
swapAddOrErase(opt.get(), fc, eqQueue);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq
|
||||
//try {
|
||||
// logFile.write("PAIR1 " + pair + "\n");
|
||||
// logFile.flush();
|
||||
//}
|
||||
//catch (IOException e) { }
|
||||
|
||||
Optional<Set<UnifyPair>> optSet = RuleSet.reduce1(pair, fc);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduce2(pair);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceExt(pair, fc);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceSup(pair, fc);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceEq(pair);
|
||||
|
||||
// ReduceTphExt, ReduceTphSup
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceTphExt(pair);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceTphSup(pair);
|
||||
|
||||
|
||||
// FunN Rules
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.reduceFunN(pair);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.greaterFunN(pair);
|
||||
optSet = optSet.isPresent() ? optSet : RuleSet.smallerFunN(pair);
|
||||
|
||||
// One of the rules has been applied
|
||||
if(optSet.isPresent()) {
|
||||
optSet.get().forEach(x -> swapAddOrErase(x, fc, eqQueue));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Adapt, AdaptExt, AdaptSup
|
||||
//try {
|
||||
// logFile.write("PAIR2 " + pair + "\n");
|
||||
// logFile.flush();
|
||||
//}
|
||||
//catch (IOException e) { }
|
||||
opt = RuleSet.adapt(pair, fc);
|
||||
opt = opt.isPresent() ? opt : RuleSet.adaptExt(pair, fc);
|
||||
opt = opt.isPresent() ? opt : RuleSet.adaptSup(pair, fc);
|
||||
|
||||
// One of the rules has been applied
|
||||
if(opt.isPresent()) {
|
||||
swapAddOrErase(opt.get(), fc, eqQueue);
|
||||
continue;
|
||||
}
|
||||
|
||||
// None of the rules has been applied
|
||||
targetSet.add(pair);
|
||||
}
|
||||
|
||||
return targetSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the rule swap to a pair if possible. Then adds the pair to the set if no erase rule applies.
|
||||
* If an erase rule applies, the pair is not added (erased).
|
||||
* @param pair The pair to swap and add or erase.
|
||||
* @param collection The collection to which the pairs are added.
|
||||
*/
|
||||
static void swapAddOrErase(UnifyPair pair, IFiniteClosure fc, Collection<UnifyPair> collection) {
|
||||
Optional<UnifyPair> opt = RuleSet.swap(pair);
|
||||
UnifyPair pair2 = opt.isPresent() ? opt.get() : pair;
|
||||
|
||||
if(RuleSet.erase1(pair2, fc) || RuleSet.erase3(pair2) || RuleSet.erase2(pair2, fc))
|
||||
return;
|
||||
|
||||
collection.add(pair2);
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceUp(UnifyPair pair) {
|
||||
// Check if reduce up is applicable
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType))
|
||||
return Optional.empty();
|
||||
|
||||
// Rule is applicable, unpack the SuperType
|
||||
return Optional.of(new UnifyPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceLow(UnifyPair pair) {
|
||||
// Check if rule is applicable
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(!(lhsType instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType))
|
||||
return Optional.empty();
|
||||
|
||||
// Rule is applicable, unpack the ExtendsType
|
||||
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceUpLow(UnifyPair pair) {
|
||||
// Check if rule is applicable
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(!(lhsType instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
// Rule is applicable, unpack both sides
|
||||
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType x = pair.getLhsType();
|
||||
UnifyType sTypeX;
|
||||
|
||||
if(x instanceof ReferenceType)
|
||||
sTypeX = x;
|
||||
else if(x instanceof ExtendsType)
|
||||
sTypeX = ((ExtendsType) x).getExtendedType();
|
||||
else
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType extY = pair.getRhsType();
|
||||
|
||||
if(!(extY instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType xFromFc = fc.getLeftHandedType(sTypeX.getName()).orElse(null);
|
||||
|
||||
if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
if(x instanceof ExtendsType)
|
||||
xFromFc = new ExtendsType(xFromFc);
|
||||
|
||||
UnifyType extYFromFc = fc.grArg(xFromFc, new HashSet<>()).stream().filter(t -> t.getName().equals(extY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
|
||||
|
||||
if(extYFromFc == null || extYFromFc.getTypeParams() != xFromFc.getTypeParams())
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams extYParams = extY.getTypeParams();
|
||||
TypeParams xParams = x.getTypeParams();
|
||||
|
||||
int[] pi = pi(xParams, extYParams);
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++)
|
||||
result.add(new UnifyPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType x = pair.getLhsType();
|
||||
UnifyType sTypeX;
|
||||
|
||||
if(x instanceof ReferenceType)
|
||||
sTypeX = x;
|
||||
else if(x instanceof SuperType)
|
||||
sTypeX = ((SuperType) x).getSuperedType();
|
||||
else
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType supY = pair.getRhsType();
|
||||
|
||||
if(!(supY instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
if(x.getTypeParams().empty() || supY.getTypeParams().size() != x.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType xFromFc = fc.getLeftHandedType(sTypeX.getName()).orElse(null);
|
||||
|
||||
if(xFromFc == null || !xFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
if(x instanceof SuperType)
|
||||
xFromFc = new SuperType(xFromFc);
|
||||
|
||||
UnifyType supYFromFc = fc.grArg(xFromFc, new HashSet<>()).stream().filter(t -> t.getName().equals(supY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
|
||||
|
||||
if(supYFromFc == null || supYFromFc.getTypeParams() != xFromFc.getTypeParams())
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams supYParams = supY.getTypeParams();
|
||||
TypeParams xParams = x.getTypeParams();
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
int[] pi = pi(xParams, supYParams);
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++)
|
||||
result.add(new UnifyPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceEq(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(lhsType instanceof PlaceholderType || lhsType.getTypeParams().empty())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
|
||||
if(!rhsType.getName().equals(lhsType.getName()))
|
||||
return Optional.empty();
|
||||
|
||||
if(rhsType instanceof PlaceholderType || lhsType instanceof PlaceholderType || rhsType.getTypeParams().empty())
|
||||
return Optional.empty();
|
||||
|
||||
if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
// Keine Permutation wie im Paper nötig
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||
|
||||
for(int i = 0; i < lhsTypeParams.size(); i++)
|
||||
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType c = pair.getLhsType();
|
||||
if(!(c instanceof ReferenceType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType d = pair.getRhsType();
|
||||
if(!(d instanceof ReferenceType))
|
||||
return Optional.empty();
|
||||
|
||||
ReferenceType lhsSType = (ReferenceType) c;
|
||||
ReferenceType rhsSType = (ReferenceType) d;
|
||||
|
||||
//try {
|
||||
// logFile.write("PAIR Rules: " + pair + "\n");
|
||||
// logFile.flush();
|
||||
//}
|
||||
//catch (IOException e) { }
|
||||
|
||||
if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType cFromFc = fc.getLeftHandedType(c.getName()).orElse(null);
|
||||
//2018-02-23: liefert Vector<Vector<Integer>>: Das kann nicht sein.
|
||||
|
||||
//NOCHMAL UEBERPRUEFEN
|
||||
//PL 18-02-09 Eingfuegt Anfang
|
||||
//C und D koennen auch gleich sein.
|
||||
if (c.getName().equals(d.getName())) {
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
TypeParams rhsTypeParams = d.getTypeParams();
|
||||
TypeParams lhsTypeParams = c.getTypeParams();
|
||||
for(int rhsIdx = 0; rhsIdx < c.getTypeParams().size(); rhsIdx++)
|
||||
result.add(new UnifyPair(lhsTypeParams.get(rhsIdx), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
//PL 18-02-09 Eingfuegt ENDE
|
||||
|
||||
//try {
|
||||
// logFile.write("cFromFc: " + cFromFc);
|
||||
// logFile.flush();
|
||||
//}
|
||||
//catch (IOException e) { }
|
||||
|
||||
if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType dFromFc = fc.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null);
|
||||
|
||||
//try {
|
||||
// logFile.write("cFromFc: " + cFromFc);
|
||||
// logFile.flush();
|
||||
//}
|
||||
//catch (IOException e) { }
|
||||
|
||||
if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size())
|
||||
return Optional.empty();
|
||||
//System.out.println("cFromFc: " + cFromFc);
|
||||
//System.out.println("dFromFc: " + dFromFc);
|
||||
int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams());
|
||||
|
||||
if(pi.length == 0)
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams rhsTypeParams = d.getTypeParams();
|
||||
TypeParams lhsTypeParams = c.getTypeParams();
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
|
||||
result.add(new UnifyPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduce2(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.EQUALSDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
ReferenceType lhsSType;
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
ReferenceType rhsSType;
|
||||
|
||||
if ((lhsType instanceof ReferenceType) && (rhsType instanceof ReferenceType)) {
|
||||
lhsSType = (ReferenceType) lhsType;
|
||||
rhsSType = (ReferenceType) rhsType;
|
||||
}
|
||||
else if (((lhsType instanceof ExtendsType) && (rhsType instanceof ExtendsType))
|
||||
|| ((lhsType instanceof SuperType) && (rhsType instanceof SuperType))) {
|
||||
UnifyType lhsSTypeRaw = ((WildcardType) lhsType).getWildcardedType();
|
||||
UnifyType rhsSTypeRaw = ((WildcardType) rhsType).getWildcardedType();
|
||||
if ((lhsSTypeRaw instanceof ReferenceType) && (rhsSTypeRaw instanceof ReferenceType)) {
|
||||
lhsSType = (ReferenceType) lhsSTypeRaw;
|
||||
rhsSType = (ReferenceType) rhsSTypeRaw;
|
||||
}
|
||||
else
|
||||
return Optional.empty();
|
||||
}
|
||||
else
|
||||
return Optional.empty();
|
||||
|
||||
if(lhsSType.getTypeParams().empty())
|
||||
return Optional.empty();
|
||||
|
||||
if(!rhsSType.getName().equals(lhsSType.getName()))
|
||||
return Optional.empty();
|
||||
|
||||
if(!(lhsSType.getTypeParams().size()==rhsSType.getTypeParams().size()))throw new DebugException("Fehler in Unifizierung"+ " " + lhsSType.toString() + " " + rhsSType.toString());
|
||||
//if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size())
|
||||
// return Optional.empty();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
|
||||
TypeParams rhsTypeParams = rhsSType.getTypeParams();
|
||||
TypeParams lhsTypeParams = lhsSType.getTypeParams();
|
||||
for(int i = 0; i < rhsTypeParams.size(); i++)
|
||||
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static boolean erase1(UnifyPair pair, IFiniteClosure fc) {
|
||||
if((pair.getPairOp() != PairOperator.SMALLERDOT) && (pair.getPairOp() != PairOperator.SMALLERNEQDOT))
|
||||
return false;
|
||||
|
||||
if (pair.getPairOp() == PairOperator.SMALLERNEQDOT) {
|
||||
UnifyType lhs = pair.getLhsType();
|
||||
UnifyType rhs = pair.getRhsType();
|
||||
if (lhs instanceof WildcardType) {
|
||||
lhs = ((WildcardType)lhs).getWildcardedType();
|
||||
}
|
||||
if (rhs instanceof WildcardType) {
|
||||
rhs = ((WildcardType)rhs).getWildcardedType();
|
||||
}
|
||||
|
||||
if (lhs.equals(rhs)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType))
|
||||
return false;
|
||||
|
||||
return fc.greater(lhsType, new HashSet<>()).contains(rhsType);
|
||||
}
|
||||
|
||||
static boolean erase2(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return false;
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
|
||||
return fc.grArg(lhsType, new HashSet<>()).contains(rhsType);
|
||||
}
|
||||
|
||||
static boolean erase3(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.EQUALSDOT)
|
||||
return false;
|
||||
|
||||
return pair.getLhsType().equals(pair.getRhsType());
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> swap(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.EQUALSDOT)
|
||||
return Optional.empty();
|
||||
|
||||
if(pair.getLhsType() instanceof PlaceholderType)
|
||||
return Optional.empty();
|
||||
|
||||
if(!(pair.getRhsType() instanceof PlaceholderType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new UnifyPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeD = pair.getLhsType();
|
||||
if(!(typeD instanceof ReferenceType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeDs = pair.getRhsType();
|
||||
if(!(typeDs instanceof ReferenceType))
|
||||
return Optional.empty();
|
||||
|
||||
/*if(typeD.getTypeParams().size() == 0 || typeDs.getTypeParams().size() == 0)
|
||||
return Optional.empty();*/
|
||||
|
||||
if(typeD.getName().equals(typeDs.getName()))
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
Optional<UnifyType> opt = fc.getLeftHandedType(typeD.getName());
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
// 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 = fc.getAncestors(typeDgen);
|
||||
opt = greater.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny();
|
||||
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType newLhs = opt.get();
|
||||
|
||||
TypeParams typeDParams = typeD.getTypeParams();
|
||||
TypeParams typeDgenParams = typeDgen.getTypeParams();
|
||||
|
||||
Unifier unif = Unifier.identity();
|
||||
for(int i = 0; i < typeDParams.size(); i++) {
|
||||
//System.out.println("ADAPT" +typeDgenParams);
|
||||
if (typeDgenParams.get(i) instanceof PlaceholderType)
|
||||
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
|
||||
else System.out.println("ERROR");
|
||||
}
|
||||
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeD = pair.getLhsType();
|
||||
if(!(typeD instanceof ReferenceType) && !(typeD instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeExtDs = pair.getRhsType();
|
||||
if(!(typeExtDs instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
if(typeD.getTypeParams().size() == 0 || typeExtDs.getTypeParams().size() == 0)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeDgen;
|
||||
if(typeD instanceof ReferenceType)
|
||||
typeDgen = fc.getLeftHandedType(typeD.getName()).orElse(null);
|
||||
else {
|
||||
Optional<UnifyType> opt = fc.getLeftHandedType(((ExtendsType) typeD).getExtendedType().getName());
|
||||
typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null;
|
||||
}
|
||||
|
||||
if(typeDgen == null)
|
||||
return Optional.empty();
|
||||
|
||||
Set<UnifyType> grArg = fc.grArg(typeDgen, new HashSet<>());
|
||||
|
||||
Optional<UnifyType> opt = grArg.stream().filter(x -> x.getName().equals(typeExtDs.getName())).findAny();
|
||||
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType newLhs = ((ExtendsType) opt.get()).getExtendedType();
|
||||
|
||||
TypeParams typeDParams = typeD.getTypeParams();
|
||||
TypeParams typeDgenParams = typeDgen.getTypeParams();
|
||||
|
||||
Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0));
|
||||
for(int i = 1; i < typeDParams.size(); i++)
|
||||
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
|
||||
|
||||
return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeDs = pair.getLhsType();
|
||||
if(!(typeDs instanceof ReferenceType) && !(typeDs instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeSupD = pair.getRhsType();
|
||||
if(!(typeSupD instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
if(typeDs.getTypeParams().size() == 0 || typeSupD.getTypeParams().size() == 0)
|
||||
return Optional.empty();
|
||||
|
||||
|
||||
Optional<UnifyType> opt = fc.getLeftHandedType(((SuperType) typeSupD).getSuperedType().getName());
|
||||
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType typeDgen = opt.get();
|
||||
UnifyType typeSupDgen = new SuperType(typeDgen);
|
||||
|
||||
// Use of smArg instead of grArg because
|
||||
// a in grArg(b) => b in smArg(a)
|
||||
Set<UnifyType> smArg = fc.smArg(typeSupDgen, new HashSet<>());
|
||||
opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny();
|
||||
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
// New RHS
|
||||
UnifyType newRhs = null;
|
||||
if(typeDs instanceof ReferenceType)
|
||||
newRhs = new ExtendsType(typeDs);
|
||||
else
|
||||
newRhs = new ExtendsType(((SuperType) typeDs).getSuperedType());
|
||||
|
||||
// New LHS
|
||||
UnifyType newLhs = opt.get();
|
||||
TypeParams typeDParams = typeSupD.getTypeParams();
|
||||
TypeParams typeSupDsgenParams = typeSupDgen.getTypeParams();
|
||||
|
||||
Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0));
|
||||
for(int i = 1; i < typeDParams.size(); i++)
|
||||
unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i));
|
||||
|
||||
return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the permutation pi of the type arguments of two types based on the finite closure
|
||||
* @param cArgs The type which arguments are permuted
|
||||
* @param dArgs 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 static int[] pi(TypeParams cArgs, TypeParams dArgs) {
|
||||
if(!(cArgs.size()==dArgs.size()))throw new DebugException("Fehler in Unifizierung");
|
||||
|
||||
int[] permutation = new int[dArgs.size()];
|
||||
|
||||
boolean succ = true;
|
||||
for (int dArgIdx = 0; dArgIdx < dArgs.size() && succ; dArgIdx++) {
|
||||
UnifyType dArg = dArgs.get(dArgIdx);
|
||||
succ = false;
|
||||
for (int pi = 0; pi < cArgs.size(); pi++)
|
||||
if (cArgs.get(pi).getName().equals(dArg.getName())) {
|
||||
permutation[dArgIdx] = pi;
|
||||
succ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return succ ? permutation : new int[0];
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceWildcardLow(UnifyPair 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 UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceWildcardUp(UnifyPair 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 UnifyPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) {
|
||||
if((pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||
&& (pair.getPairOp() != PairOperator.EQUALSDOT)) //PL 2017-10-03 hinzugefuegt
|
||||
//da Regel auch fuer EQUALSDOT anwendbar
|
||||
//TODO: fuer allen anderen Relationen noch pruefen
|
||||
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<UnifyPair> result = new HashSet<UnifyPair>();
|
||||
if (pair.getPairOp() == PairOperator.SMALLERDOT) {
|
||||
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
||||
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
}
|
||||
else {// pair.getPairOp() == PairOperator.EQUALDOT
|
||||
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
||||
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
}
|
||||
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
|
||||
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
|
||||
UnifyType r = x.getRhsType();
|
||||
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
|
||||
} );
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> greaterFunN(UnifyPair 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<UnifyPair> result = new HashSet<UnifyPair>();
|
||||
|
||||
Integer variance = ((PlaceholderType)rhsType).getVariance();
|
||||
Integer inversVariance = distributeVariance.inverseVariance(variance);
|
||||
|
||||
UnifyType[] freshPlaceholders = new UnifyType[funNLhsType.getTypeParams().size()];
|
||||
for(int i = 0; i < freshPlaceholders.length-1; i++) {
|
||||
freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
|
||||
((PlaceholderType)freshPlaceholders[i]).setVariance(inversVariance);
|
||||
}
|
||||
freshPlaceholders[freshPlaceholders.length-1] = PlaceholderType.freshPlaceholder();
|
||||
((PlaceholderType)freshPlaceholders[freshPlaceholders.length-1]).setVariance(variance);
|
||||
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), freshPlaceholders[funNLhsType.getTypeParams().size()-1], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
||||
result.add(new UnifyPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
|
||||
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
|
||||
UnifyType r = x.getRhsType();
|
||||
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
|
||||
} );
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> smallerFunN(UnifyPair 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<UnifyPair> result = new HashSet<UnifyPair>();
|
||||
|
||||
Integer variance = ((PlaceholderType)lhsType).getVariance();
|
||||
Integer inversVariance = distributeVariance.inverseVariance(variance);
|
||||
|
||||
UnifyType[] freshPlaceholders = new UnifyType[funNRhsType.getTypeParams().size()];
|
||||
for(int i = 0; i < freshPlaceholders.length-1; i++) {
|
||||
freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
|
||||
((PlaceholderType)freshPlaceholders[i]).setVariance(inversVariance);
|
||||
}
|
||||
freshPlaceholders[freshPlaceholders.length-1] = PlaceholderType.freshPlaceholder();
|
||||
((PlaceholderType)freshPlaceholders[freshPlaceholders.length-1]).setVariance(variance);
|
||||
|
||||
result.add(new UnifyPair(freshPlaceholders[funNRhsType.getTypeParams().size()-1], funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
for(int i = 0; i < funNRhsType.getTypeParams().size()-1; i++) {
|
||||
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
|
||||
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
|
||||
UnifyType r = x.getRhsType();
|
||||
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
|
||||
} );
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<UnifyPair> reduceTph(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType))
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceTphExt(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof PlaceholderType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType extendedType = ((ExtendsType)lhsType).getExtendedType();
|
||||
|
||||
if (extendedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? extends a <.? a
|
||||
|
||||
boolean isGen = extendedType instanceof PlaceholderType && !((PlaceholderType) extendedType).isGenerated();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
if(isGen)
|
||||
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
else {
|
||||
UnifyType freshTph = PlaceholderType.freshPlaceholder();
|
||||
result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
}
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair) {
|
||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType lhsType = pair.getLhsType();
|
||||
UnifyType rhsType = pair.getRhsType();
|
||||
if(!(lhsType instanceof SuperType) || !(rhsType instanceof PlaceholderType))
|
||||
return Optional.empty();
|
||||
|
||||
UnifyType superedType = ((SuperType)lhsType).getSuperedType();
|
||||
|
||||
if (superedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? super a <.? a
|
||||
|
||||
boolean isGen = superedType instanceof PlaceholderType && !((PlaceholderType) superedType).isGenerated();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
if(isGen)
|
||||
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
else {
|
||||
UnifyType freshTph = PlaceholderType.freshPlaceholder();
|
||||
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
Set<UnifyType> fBounded = pair.getfBounded();
|
||||
fBounded.add(lhsType);
|
||||
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair(), fBounded));
|
||||
}
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
}
|
54
src/main/java/de/dhbwstuttgart/unify2/TypeUnify.java
Normal file
54
src/main/java/de/dhbwstuttgart/unify2/TypeUnify.java
Normal file
@ -0,0 +1,54 @@
|
||||
package de.dhbwstuttgart.unify2;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
import de.dhbwstuttgart.unify2.model.UnifyConstraintSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TypeUnify {
|
||||
|
||||
public static Optional<Set<UnifyPair>> unifyOrConstraints(UnifyConstraintSet eq, FiniteClosure fc){
|
||||
return eq.cartesianProductParallel().map(eqPrime -> unify(eqPrime, fc)).filter(Optional::isPresent).map(Optional::get).findAny();
|
||||
}
|
||||
|
||||
public static Optional<Set<UnifyPair>> unify(Set<UnifyPair> eq, FiniteClosure fc){
|
||||
/*
|
||||
TODO: Hier könnte man prüfen, ob es überhaupt einen Sinn macht mit eq weiterzumachen
|
||||
Es könnte eine über threads geteiltes Objekt geben (Feld in TypeUnify), welches unmögliche Klauseln lernt
|
||||
*/
|
||||
|
||||
//Apply Reduce und Apply rules
|
||||
Set<UnifyPair> res = RuleSet.applyTypeUnificationRules(eq, fc);
|
||||
//Split result
|
||||
|
||||
/*
|
||||
* Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs
|
||||
*/
|
||||
Set<UnifyPair> eq1s = new HashSet<>();
|
||||
Set<UnifyPair> eq2s = new HashSet<>();
|
||||
for(UnifyPair pair : res) {
|
||||
if (pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType)
|
||||
eq1s.add(pair);
|
||||
else
|
||||
eq2s.add(pair);
|
||||
}
|
||||
|
||||
Optional<UnifyConstraintSet> step4Res = Unify.step4(eq1s, eq2s, fc);
|
||||
|
||||
//Falls step4 etwas liefert, dann subst und rekursiver unify aufruf anwenden:
|
||||
return step4Res.flatMap(constraintSet ->
|
||||
constraintSet.cartesianProductParallel().map(toSubst -> {
|
||||
Optional<Set<UnifyPair>> substitutionResult = Unify.subst(toSubst); //hier substituieren
|
||||
//if it changed:
|
||||
if (substitutionResult.isPresent()) {
|
||||
return unify(substitutionResult.get(), fc);
|
||||
}else{
|
||||
//TODO: return the result
|
||||
return Optional.of(toSubst);
|
||||
}
|
||||
}).filter(it -> it.isPresent()).map(Optional::get).findAny());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
340
src/main/java/de/dhbwstuttgart/unify2/Unify.java
Normal file
340
src/main/java/de/dhbwstuttgart/unify2/Unify.java
Normal file
@ -0,0 +1,340 @@
|
||||
package de.dhbwstuttgart.unify2;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
import de.dhbwstuttgart.unify2.model.UnifyConstraintSet;
|
||||
import de.dhbwstuttgart.unify2.model.UnifyOderConstraint;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Unify {
|
||||
|
||||
/**
|
||||
* Creates sets of pairs specified in the fourth step. Does not calculate cartesian products.
|
||||
* @return The set of the eight cases (without empty sets). Each case is a set, containing sets generated
|
||||
* from the pairs that matched the case. Each generated set contains singleton sets or sets with few elements
|
||||
* (as in case 1 where sigma is added to the innermost set).
|
||||
*/
|
||||
public static Optional<UnifyConstraintSet> step4(Set<UnifyPair> eq1s, Set<UnifyPair> eq2s, FiniteClosure fc) {
|
||||
Set<UnifyOderConstraint> result = new HashSet<>(8);
|
||||
|
||||
for(UnifyPair 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.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.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.add(unifyCase3((PlaceholderType) lhsType, (SuperType) rhsType, fc));
|
||||
|
||||
// Case 4 was replaced by an inference rule
|
||||
// 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.add(unifyCase5(lhsType, (PlaceholderType) rhsType, fc));
|
||||
|
||||
// Case 6 was replaced by an inference rule.
|
||||
// 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 was replaced by an inference rule
|
||||
// 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.add(unifyCase8(lhsType, (PlaceholderType) rhsType, fc));
|
||||
// Case unknown: If a pair fits no other case, then the type unification has failed.
|
||||
// Through application of the rules, every pair should have one of the above forms.
|
||||
// Pairs that do not have one of the aboves form are contradictory.
|
||||
else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
result.add(new UnifyOderConstraint(Set.of(eq1s)));
|
||||
// Filter empty sets or sets that only contain an empty set.
|
||||
//Andi: Why? Should they exist? this should be an error then
|
||||
return Optional.of(new UnifyConstraintSet(result));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cartesian product Case 1: (a <. Theta')
|
||||
*/
|
||||
static UnifyOderConstraint unifyCase1(PlaceholderType a, UnifyType thetaPrime, FiniteClosure fc) {
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
|
||||
boolean allGen = thetaPrime.getTypeParams().size() > 0;
|
||||
for(UnifyType t : thetaPrime.getTypeParams())
|
||||
if(!(t instanceof PlaceholderType) || !((PlaceholderType) t).isGenerated()) {
|
||||
allGen = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Set<UnifyType> cs = fc.getAllTypesByName(thetaPrime.getName());
|
||||
cs.add(thetaPrime);
|
||||
|
||||
for(UnifyType c : cs) {
|
||||
Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new));
|
||||
//thetaQs.add(thetaPrime);
|
||||
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, new HashSet<>()));
|
||||
|
||||
for(TypeParams tp : permuteParams(candidateParams))
|
||||
thetaQPrimes.add(c.setTypeParams(tp));
|
||||
}
|
||||
|
||||
for(UnifyType tqp : thetaQPrimes) {
|
||||
Optional<Unifier> opt = MartelliMontanariUnify.unify(tqp, thetaPrime);
|
||||
if (!opt.isPresent())
|
||||
continue;
|
||||
|
||||
Unifier unifier = opt.get();
|
||||
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams());
|
||||
Set<UnifyPair> substitutionSet = new HashSet<>();
|
||||
for (Map.Entry<PlaceholderType, UnifyType> sigma : unifier)
|
||||
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
|
||||
|
||||
List<UnifyType> freshTphs = new ArrayList<>();
|
||||
for (UnifyType tq : thetaQs) {
|
||||
Set<UnifyType> smaller = fc.smaller(unifier.apply(tq), new HashSet<>());
|
||||
for(UnifyType theta : smaller) {
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
|
||||
for(int i = 0; !allGen && i < theta.getTypeParams().size(); i++) {
|
||||
if(freshTphs.size()-1 < i)
|
||||
freshTphs.add(PlaceholderType.freshPlaceholder());
|
||||
resultPrime.add(new UnifyPair(freshTphs.get(i), theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC));
|
||||
}
|
||||
|
||||
if(allGen)
|
||||
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
|
||||
else
|
||||
resultPrime.add(new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT));
|
||||
resultPrime.addAll(substitutionSet);
|
||||
result.add(resultPrime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new UnifyOderConstraint(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of candidates for each position and computes all possible permutations.
|
||||
* @param candidates The length of the list determines the number of type params. Each set
|
||||
* contains the candidates for the corresponding position.
|
||||
*/
|
||||
static Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
|
||||
Set<TypeParams> result = new HashSet<>();
|
||||
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of candidates for each position and computes all possible permutations.
|
||||
* @param candidates The length of the list determines the number of type params. Each set
|
||||
* contains the candidates for the corresponding position.
|
||||
* @param idx Idx for the current permutatiton.
|
||||
* @param result Set of all permutations found so far
|
||||
* @param current The permutation of type params that is currently explored
|
||||
*/
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cartesian Product Case 2: (a <.? ? ext Theta')
|
||||
*/
|
||||
static UnifyOderConstraint unifyCase2(PlaceholderType a, ExtendsType extThetaPrime, IFiniteClosure fc) {
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
|
||||
UnifyType aPrime = PlaceholderType.freshPlaceholder();
|
||||
UnifyType extAPrime = new ExtendsType(aPrime);
|
||||
UnifyType thetaPrime = extThetaPrime.getExtendedType();
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, thetaPrime, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
|
||||
resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT));
|
||||
resultPrime.add(new UnifyPair(aPrime, thetaPrime, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
return new UnifyOderConstraint(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cartesian Product Case 3: (a <.? ? sup Theta')
|
||||
*/
|
||||
static UnifyOderConstraint unifyCase3(PlaceholderType a, SuperType subThetaPrime, IFiniteClosure fc) {
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
|
||||
UnifyType aPrime = PlaceholderType.freshPlaceholder();
|
||||
UnifyType supAPrime = new SuperType(aPrime);
|
||||
UnifyType thetaPrime = subThetaPrime.getSuperedType();
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
|
||||
resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT));
|
||||
resultPrime.add(new UnifyPair(thetaPrime, aPrime, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
|
||||
return new UnifyOderConstraint(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cartesian Product Case 5: (Theta <. a)
|
||||
*/
|
||||
static UnifyOderConstraint unifyCase5(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
|
||||
boolean allGen = theta.getTypeParams().size() > 0;
|
||||
for(UnifyType t : theta.getTypeParams())
|
||||
if(!(t instanceof PlaceholderType) || !((PlaceholderType) t).isGenerated()) {
|
||||
allGen = false;
|
||||
break;
|
||||
}
|
||||
|
||||
for(UnifyType thetaS : fc.greater(theta, new HashSet<>())) {
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
|
||||
UnifyType[] freshTphs = new UnifyType[thetaS.getTypeParams().size()];
|
||||
for(int i = 0; !allGen && i < freshTphs.length; i++) {
|
||||
freshTphs[i] = PlaceholderType.freshPlaceholder();
|
||||
resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC));
|
||||
}
|
||||
|
||||
if(allGen)
|
||||
resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT));
|
||||
else
|
||||
resultPrime.add(new UnifyPair(a, thetaS.setTypeParams(new TypeParams(freshTphs)), PairOperator.EQUALSDOT));
|
||||
result.add(resultPrime);
|
||||
}
|
||||
|
||||
return new UnifyOderConstraint(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cartesian Product Case 8: (Theta <.? a)
|
||||
*/
|
||||
static UnifyOderConstraint unifyCase8(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
|
||||
Set<Set<UnifyPair>> result = new HashSet<>();
|
||||
//for(UnifyType thetaS : fc.grArg(theta)) {
|
||||
Set<UnifyPair> resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
|
||||
result.add(resultPrime);
|
||||
|
||||
UnifyType freshTph = PlaceholderType.freshPlaceholder();
|
||||
resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT));
|
||||
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
|
||||
resultPrime = new HashSet<>();
|
||||
resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT));
|
||||
resultPrime.add(new UnifyPair(freshTph, theta, PairOperator.SMALLERDOT));
|
||||
result.add(resultPrime);
|
||||
//}
|
||||
|
||||
return new UnifyOderConstraint(result);
|
||||
}
|
||||
|
||||
static Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs) {
|
||||
HashMap<UnifyType, Integer> typeMap = new HashMap<>();
|
||||
|
||||
Stack<UnifyType> occuringTypes = new Stack<>();
|
||||
|
||||
for(UnifyPair pair : pairs) {
|
||||
occuringTypes.push(pair.getLhsType());
|
||||
occuringTypes.push(pair.getRhsType());
|
||||
}
|
||||
|
||||
while(!occuringTypes.isEmpty()) {
|
||||
UnifyType t1 = occuringTypes.pop();
|
||||
if(!typeMap.containsKey(t1))
|
||||
typeMap.put(t1, 0);
|
||||
typeMap.put(t1, typeMap.get(t1)+1);
|
||||
|
||||
if(t1 instanceof ExtendsType)
|
||||
occuringTypes.push(((ExtendsType) t1).getExtendedType());
|
||||
if(t1 instanceof SuperType)
|
||||
occuringTypes.push(((SuperType) t1).getSuperedType());
|
||||
else
|
||||
t1.getTypeParams().forEach(x -> occuringTypes.push(x));
|
||||
}
|
||||
|
||||
Queue<UnifyPair> result1 = new LinkedList<UnifyPair>(pairs);
|
||||
ArrayList<UnifyPair> result = new ArrayList<UnifyPair>();
|
||||
boolean applied = false;
|
||||
|
||||
while(!result1.isEmpty()) {
|
||||
UnifyPair pair = result1.poll();
|
||||
PlaceholderType lhsType = null;
|
||||
UnifyType rhsType;
|
||||
|
||||
if(pair.getPairOp() == PairOperator.EQUALSDOT
|
||||
&& pair.getLhsType() instanceof PlaceholderType)
|
||||
lhsType = (PlaceholderType) pair.getLhsType();
|
||||
rhsType = pair.getRhsType(); //PL eingefuegt 2017-09-29 statt !((rhsType = pair.getRhsType()) instanceof PlaceholderType)
|
||||
if(lhsType != null
|
||||
//&& !((rhsType = pair.getRhsType()) instanceof PlaceholderType) //PL geloescht am 2017-09-29 Begründung: auch Typvariablen muessen ersetzt werden.
|
||||
&& typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
|
||||
&& !rhsType.getTypeParams().occurs(lhsType)
|
||||
&& !((rhsType instanceof WildcardType) && ((WildcardType)rhsType).getWildcardedType().equals(lhsType))) //PL eigefuegt 2018-02-18
|
||||
{
|
||||
Unifier uni = new Unifier(lhsType, rhsType);
|
||||
result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
|
||||
result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
|
||||
|
||||
Function<? super Constraint<UnifyPair>,? extends Constraint<UnifyPair>> applyUni = b -> b.stream().map(
|
||||
x -> uni.apply(pair,x)).collect(Collectors.toCollection((b.getExtendConstraint() != null)
|
||||
? () -> new Constraint<UnifyPair>(
|
||||
b.getExtendConstraint().stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(Constraint::new)))
|
||||
: () -> new Constraint<UnifyPair>()
|
||||
));
|
||||
applied = true;
|
||||
}
|
||||
result.add(pair);
|
||||
}
|
||||
|
||||
return applied ? Optional.of(new HashSet<>(result)) : Optional.empty();
|
||||
}
|
||||
|
||||
}
|
11
src/main/java/de/dhbwstuttgart/unify2/UnifyResult.java
Normal file
11
src/main/java/de/dhbwstuttgart/unify2/UnifyResult.java
Normal file
@ -0,0 +1,11 @@
|
||||
package de.dhbwstuttgart.unify2;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class UnifyResult {
|
||||
public UnifyResult(Set<UnifyPair> toSubst) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package de.dhbwstuttgart.unify2.model;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/*
|
||||
OrC1 OrC2 OrC3 -> Constraints
|
||||
Step4: OrC1 OrC2/c OrC3 OrC4
|
||||
|
||||
Tiefensuche, neue UnifyConstraints erstellen
|
||||
|
||||
Wie wird ConstraintSet geändert?
|
||||
|
||||
wird nicht gebraucht:
|
||||
( map -> bei subst
|
||||
Alle Constraints ändern, neues ConstraintSet zurückgeben )
|
||||
|
||||
Step 4 bildet anschließend das karthesische Produkt und muss über alle Möglichkeiten iterieren
|
||||
die erste möglichkeit vom karthesischen produkt nehmen, subst schritt ausführen und mit dem Ergebnis (einzelnes Constraint Set) weiterarbeiten
|
||||
|
||||
*/
|
||||
|
||||
public class UnifyConstraintSet {
|
||||
Set<UnifyOderConstraint> oderConstraints = new HashSet<>();
|
||||
|
||||
public UnifyConstraintSet(Set<UnifyOderConstraint> constraints){
|
||||
if(constraints.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
this.oderConstraints = constraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
BinaryOperator<String> b = (x, y) -> x+y;
|
||||
return "ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
|
||||
}
|
||||
|
||||
/*
|
||||
Cartesian product als optimierter Stream
|
||||
|
||||
- Ein Split teilt das Set so auf, dass der zweite Thread jedes zweite Element behandelt
|
||||
- Ein thread der jedes zweite element behandelt wird gesplittet indem
|
||||
|
||||
1 2 1 2 1 2 1 2 => (o = 0, n = 2), (o = 1, n = 2)
|
||||
1 2 1 3 1 2 1 3 => (o = 0, n = 2), (o = 1, n = 4), (o = 3, n = 4)
|
||||
|
||||
*/
|
||||
private class ConstraintSpliterator implements Spliterator<Set<UnifyPair>> {
|
||||
private List<UnifyOderConstraint> constraints;
|
||||
private long i = 0;
|
||||
private long iterationFactor = 1;
|
||||
private long max = 0;
|
||||
private List<Integer> sizes;
|
||||
private List<Long> bases = new ArrayList<>();
|
||||
|
||||
ConstraintSpliterator(List<UnifyOderConstraint> constraints){
|
||||
this.constraints = constraints;
|
||||
sizes = constraints.stream().map(UnifyOderConstraint::getSize).collect(Collectors.toList());
|
||||
long base = 1;
|
||||
for(int size : sizes){
|
||||
bases.add(base);
|
||||
base *= size;
|
||||
}
|
||||
i = 0;
|
||||
max = estimateSize() - 1;
|
||||
}
|
||||
|
||||
ConstraintSpliterator(List<UnifyOderConstraint> constraints, long start, long factor){
|
||||
this(constraints);
|
||||
i = start;
|
||||
this.iterationFactor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Set<UnifyPair>> consumer) {
|
||||
if(i > max) return false;
|
||||
consumer.accept(get(i));
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<UnifyPair> get(long num){
|
||||
Set<UnifyPair> ret = new HashSet<>();
|
||||
Iterator<Long> baseIt = bases.iterator();
|
||||
for(UnifyOderConstraint constraint : constraints){
|
||||
ret.addAll(constraint.get((int) ((num/baseIt.next())%constraint.getSize())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Set<UnifyPair>> trySplit() {
|
||||
if(max - (i+iterationFactor * 2) < 0) return null;
|
||||
long iNext = i + iterationFactor;
|
||||
iterationFactor *= 2;
|
||||
return new UnifyConstraintSet.ConstraintSpliterator(constraints, iNext, iterationFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
long ret = 1;
|
||||
for (int size : sizes)ret*=size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return ORDERED | SIZED | IMMUTABLE | NONNULL;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream<Set<UnifyPair>> cartesianProductParallel(){
|
||||
return StreamSupport.stream(new UnifyConstraintSet.ConstraintSpliterator(oderConstraints.stream().collect(Collectors.toList())), true);
|
||||
}
|
||||
|
||||
public Stream<Set<UnifyPair>> cartesianProductParallel(Comparator<Set<UnifyPair>> prioritiser){
|
||||
return StreamSupport.stream(new UnifyConstraintSet.ConstraintSpliterator(oderConstraints.stream().collect(Collectors.toList())), true);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package de.dhbwstuttgart.unify2.model;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class UnifyConstraintSetBuilder {
|
||||
|
||||
private Set<UnifyPair> undConstraints = new HashSet<>();
|
||||
private Set<UnifyOderConstraint> oderConstraints = new HashSet<>();
|
||||
private boolean done = false;
|
||||
|
||||
public void addUndConstraint(UnifyPair p){
|
||||
undConstraints.add(p);
|
||||
}
|
||||
|
||||
public void addOderConstraint(UnifyOderConstraint orConstraint) {
|
||||
oderConstraints.add(orConstraint);
|
||||
}
|
||||
|
||||
public UnifyConstraintSet build(){
|
||||
if(done)throw new RuntimeException("Trying to build cartesian product twice");
|
||||
this.done = true;
|
||||
if(!undConstraints.isEmpty())
|
||||
oderConstraints.add(new UnifyOderConstraint(Set.of(undConstraints)));
|
||||
return new UnifyConstraintSet(oderConstraints);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package de.dhbwstuttgart.unify2.model;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UnifyOderConstraint {
|
||||
|
||||
private final List<Set<UnifyPair>> cons;
|
||||
public UnifyOderConstraint(Set<Set<UnifyPair>> orCons){
|
||||
if(orCons.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
for(Set<UnifyPair> c : orCons){
|
||||
if(c.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
}
|
||||
this.cons = orCons.stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int getSize(){
|
||||
return cons.size();
|
||||
}
|
||||
|
||||
public Set<UnifyPair> get(int l) {
|
||||
return cons.get(l);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ public class FamilyOfGeneratedGenericsTest extends TestCase {
|
||||
/*
|
||||
Example method:
|
||||
A id(B i) return i;
|
||||
gives constraint: B <. A, which is a method constraint
|
||||
gives constraint: B <. A and A <. Object, which are method constraints
|
||||
*/
|
||||
|
||||
List<TPHConstraint> inputConstraints = new ArrayList<>();
|
||||
@ -32,8 +32,8 @@ public class FamilyOfGeneratedGenericsTest extends TestCase {
|
||||
/*
|
||||
MethodConstraints should be the same as the input constraint
|
||||
*/
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(inputConstraints, tphPositions);
|
||||
assertTrue(methodConstraints.size() == 1);
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(inputConstraints, new ArrayList<ClassConstraint>(), tphPositions);
|
||||
assertTrue(methodConstraints.size() == 2);
|
||||
assertTrue(methodConstraints.get(0).getLeft().equals("B"));
|
||||
assertTrue(methodConstraints.get(0).getRight().equals("A"));
|
||||
}
|
||||
@ -46,7 +46,7 @@ public class FamilyOfGeneratedGenericsTest extends TestCase {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
gives constraint: A <. B, which is a class constraint
|
||||
gives constraint: A <. B and B <. Object which are class constraints
|
||||
*/
|
||||
|
||||
List<TPHConstraint> inputConstraints = new ArrayList<>();
|
||||
@ -109,8 +109,12 @@ public class FamilyOfGeneratedGenericsTest extends TestCase {
|
||||
|
||||
List<ClassConstraint> classConstraints = FamilyOfGeneratedGenerics.getClassConstraints(inputConstraints, tphPositions);
|
||||
System.out.println(classConstraints);
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(inputConstraints, classConstraints, tphPositions);
|
||||
System.out.println(methodConstraints);
|
||||
assertFalse(classConstraints.isEmpty());
|
||||
assertTrue(classConstraints.size() == 6);
|
||||
assertFalse(methodConstraints.isEmpty());
|
||||
assertTrue(methodConstraints.size() == 5);
|
||||
|
||||
}
|
||||
|
||||
@ -165,9 +169,13 @@ public class FamilyOfGeneratedGenericsTest extends TestCase {
|
||||
|
||||
List<ClassConstraint> classConstraints = FamilyOfGeneratedGenerics.getClassConstraints(inputConstraints, tphPositions);
|
||||
System.out.println(classConstraints);
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(inputConstraints, classConstraints, tphPositions);
|
||||
System.out.println(methodConstraints);
|
||||
|
||||
assertFalse(classConstraints.isEmpty());
|
||||
assertTrue(classConstraints.size() == 3);
|
||||
assertFalse(methodConstraints.isEmpty());
|
||||
assertTrue(methodConstraints.size()==9);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,12 +1,8 @@
|
||||
/*
|
||||
package insertGenerics;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.ClassConstraint;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.FamilyOfGeneratedGenerics;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.MethodConstraint;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.PositionFinder;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.*;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -27,19 +23,31 @@ public class TestExample42 {
|
||||
return cs;
|
||||
}
|
||||
|
||||
public HashMap<String, PositionFinder.Position> fillPosOfTphs() {
|
||||
BufferedReader l;
|
||||
HashMap<String, PositionFinder.Position> posOfTphs = new HashMap<>();
|
||||
posOfTphs.put("K", PositionFinder.Position.FIELD);
|
||||
posOfTphs.put("L", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("M", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("N", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("P", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("Q", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("U", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("V", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("W", PositionFinder.Position.METHOD);
|
||||
posOfTphs.put("Z", PositionFinder.Position.METHOD);
|
||||
public HashMap<String, PairTphMethod<PositionFinder.Position, String>> fillPosOfTphs() {
|
||||
HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs = new HashMap<>();
|
||||
|
||||
// TPHs "U" und "L" auskommentiert, da nach Vorgaben L zu Z umbenannt und U als void interpretiert wird
|
||||
PairTphMethod<PositionFinder.Position, String> posOfK = new PairTphMethod<>(PositionFinder.Position.FIELD, null);
|
||||
// PairTphMethod<PositionFinder.Position, String> posOfL = new PairTphMethod<>(PositionFinder.Position.METHOD, "id");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfM = new PairTphMethod<>(PositionFinder.Position.METHOD, "id");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfN = new PairTphMethod<>(PositionFinder.Position.METHOD, "id");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfP = new PairTphMethod<>(PositionFinder.Position.METHOD, "setA");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfQ = new PairTphMethod<>(PositionFinder.Position.METHOD, "setA");
|
||||
// PairTphMethod<PositionFinder.Position, String> posOfU = new PairTphMethod<>(PositionFinder.Position.METHOD, "m");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfV = new PairTphMethod<>(PositionFinder.Position.METHOD, "m");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfW = new PairTphMethod<>(PositionFinder.Position.METHOD, "m");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfZ = new PairTphMethod<>(PositionFinder.Position.METHOD, "m");
|
||||
|
||||
posOfTphs.put("K", posOfK);
|
||||
// posOfTphs.put("L", posOfL);
|
||||
posOfTphs.put("M", posOfM);
|
||||
posOfTphs.put("N", posOfN);
|
||||
posOfTphs.put("P", posOfP);
|
||||
posOfTphs.put("Q", posOfQ);
|
||||
// posOfTphs.put("U", posOfU);
|
||||
posOfTphs.put("V", posOfV);
|
||||
posOfTphs.put("W", posOfW);
|
||||
posOfTphs.put("Z", posOfZ);
|
||||
return posOfTphs;
|
||||
}
|
||||
|
||||
@ -47,10 +55,9 @@ public class TestExample42 {
|
||||
public void genericTest() {
|
||||
List<ClassConstraint> classConstraints = FamilyOfGeneratedGenerics.getClassConstraints(fillConstraintsList(),fillPosOfTphs());
|
||||
System.out.println("ClassConstraints: " + classConstraints);
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(fillConstraintsList(),fillPosOfTphs());
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(fillConstraintsList(),classConstraints,fillPosOfTphs());
|
||||
System.out.println("MethodConstraints: " + methodConstraints);
|
||||
|
||||
List<TPHConstraint> testCons;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -0,0 +1,61 @@
|
||||
package insertGenerics;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||
import de.dhbwstuttgart.bytecode.insertGenerics.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class TestExample42_allInOneMethod {
|
||||
public List<TPHConstraint> fillConstraintsList() {
|
||||
List<TPHConstraint> cs = new ArrayList<>();
|
||||
cs.add(new TPHConstraint("M", "N", Relation.EXTENDS));
|
||||
cs.add(new TPHConstraint("N", "Z", Relation.EXTENDS));
|
||||
cs.add(new TPHConstraint("Q", "K", Relation.EXTENDS));
|
||||
cs.add(new TPHConstraint("K", "P", Relation.EXTENDS));
|
||||
cs.add(new TPHConstraint("W", "M", Relation.EXTENDS));
|
||||
cs.add(new TPHConstraint("Z", "V", Relation.EXTENDS));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public HashMap<String, PairTphMethod<PositionFinder.Position, String>> fillPosOfTphs() {
|
||||
HashMap<String, PairTphMethod<PositionFinder.Position, String>> posOfTphs = new HashMap<>();
|
||||
|
||||
// TPHs "U" und "L" auskommentiert, da nach Vorgaben L zu Z umbenannt und U als void interpretiert wird
|
||||
PairTphMethod<PositionFinder.Position, String> posOfK = new PairTphMethod<>(PositionFinder.Position.FIELD, null);
|
||||
// PairTphMethod<PositionFinder.Position, String> posOfL = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfM = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfN = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfP = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfQ = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
// PairTphMethod<PositionFinder.Position, String> posOfU = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfV = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfW = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
PairTphMethod<PositionFinder.Position, String> posOfZ = new PairTphMethod<>(PositionFinder.Position.METHOD, "sameMethod");
|
||||
|
||||
posOfTphs.put("K", posOfK);
|
||||
// posOfTphs.put("L", posOfL);
|
||||
posOfTphs.put("M", posOfM);
|
||||
posOfTphs.put("N", posOfN);
|
||||
posOfTphs.put("P", posOfP);
|
||||
posOfTphs.put("Q", posOfQ);
|
||||
// posOfTphs.put("U", posOfU);
|
||||
posOfTphs.put("V", posOfV);
|
||||
posOfTphs.put("W", posOfW);
|
||||
posOfTphs.put("Z", posOfZ);
|
||||
return posOfTphs;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericTest() {
|
||||
List<ClassConstraint> classConstraints = FamilyOfGeneratedGenerics.getClassConstraints(fillConstraintsList(),fillPosOfTphs());
|
||||
System.out.println("ClassConstraints: " + classConstraints);
|
||||
List<MethodConstraint> methodConstraints = FamilyOfGeneratedGenerics.getMethodConstraints(fillConstraintsList(),classConstraints,fillPosOfTphs());
|
||||
System.out.println("MethodConstraints: " + methodConstraints);
|
||||
|
||||
List<TPHConstraint> testCons;
|
||||
}
|
||||
}
|
62
src/test/java/typeinference/ConstraintSetTests.java
Normal file
62
src/test/java/typeinference/ConstraintSetTests.java
Normal file
@ -0,0 +1,62 @@
|
||||
package typeinference;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSetBuilder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.OderConstraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConstraintSetTests {
|
||||
@Test
|
||||
public void cartesianProductTestSingleConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestSingleOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestTwoOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 4;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestThreeOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 4;
|
||||
|
||||
ConstraintSetBuilder builder2 = new ConstraintSetBuilder();
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result2 = builder2.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
|
||||
assert result2.stream().map( a -> a.stream().map(p -> p.TA1.toString()).reduce("", (x, y)-> x+" "+y)).collect(Collectors.toSet()).size() == 8;
|
||||
assert result2.size() == 8;
|
||||
}
|
||||
|
||||
public Pair generatePair(){
|
||||
return new Pair(TypePlaceholder.fresh(new NullToken()), TypePlaceholder.fresh(new NullToken()));
|
||||
}
|
||||
}
|
62
src/test/java/typeinference/UnifyConstraintSetTests.java
Normal file
62
src/test/java/typeinference/UnifyConstraintSetTests.java
Normal file
@ -0,0 +1,62 @@
|
||||
package typeinference;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSetBuilder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.OderConstraint;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UnifyConstraintSetTests {
|
||||
@Test
|
||||
public void cartesianProductTestSingleConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestSingleOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestTwoOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 4;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductTestThreeOderConstraint(){
|
||||
ConstraintSetBuilder builder = new ConstraintSetBuilder();
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
|
||||
List<Set<Pair>> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
assert result.size() == 4;
|
||||
|
||||
ConstraintSetBuilder builder2 = new ConstraintSetBuilder();
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
|
||||
List<Set<Pair>> result2 = builder2.build().cartesianProductParallel().collect(Collectors.toList());
|
||||
|
||||
assert result2.stream().map( a -> a.stream().map(p -> p.TA1.toString()).reduce("", (x, y)-> x+" "+y)).collect(Collectors.toSet()).size() == 8;
|
||||
assert result2.size() == 8;
|
||||
}
|
||||
|
||||
public Pair generatePair(){
|
||||
return new Pair(TypePlaceholder.fresh(new NullToken()), TypePlaceholder.fresh(new NullToken()));
|
||||
}
|
||||
}
|
4
src/test/java/unify/RuleSetTest.java
Normal file
4
src/test/java/unify/RuleSetTest.java
Normal file
@ -0,0 +1,4 @@
|
||||
package unify;
|
||||
|
||||
public class RuleSetTest {
|
||||
}
|
47
src/test/java/unify/TypeUnifyTest.java
Normal file
47
src/test/java/unify/TypeUnifyTest.java
Normal file
@ -0,0 +1,47 @@
|
||||
package unify;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.unify2.TypeUnify;
|
||||
import de.dhbwstuttgart.unify2.model.UnifyConstraintSet;
|
||||
import de.dhbwstuttgart.unify2.model.UnifyOderConstraint;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeUnifyTest {
|
||||
@Test
|
||||
public void emptyInput(){
|
||||
UnifyConstraintSet empty = new UnifyConstraintSet(new HashSet<>());
|
||||
TypeUnify.unifyOrConstraints(empty, emptyFC());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleOrConstraintOnlyTPHs(){
|
||||
Set<UnifyPair> pairs = Set.of(new UnifyPair(PlaceholderType.freshPlaceholder(), PlaceholderType.freshPlaceholder(), PairOperator.EQUALSDOT));
|
||||
UnifyOderConstraint orConstraint = new UnifyOderConstraint(Set.of(pairs));
|
||||
UnifyConstraintSet input = new UnifyConstraintSet(Set.of(orConstraint));
|
||||
Optional<Set<UnifyPair>> res = TypeUnify.unifyOrConstraints(input, emptyFC());
|
||||
assert res.isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unifyTest1(){
|
||||
PlaceholderType tph1 = PlaceholderType.freshPlaceholder();
|
||||
PlaceholderType tph2 = PlaceholderType.freshPlaceholder();
|
||||
UnifyPair p1 = new UnifyPair(tph1, tph2, PairOperator.SMALLERDOT);
|
||||
Set<UnifyPair> pairs = Set.of(p1);
|
||||
UnifyOderConstraint orConstraint = new UnifyOderConstraint(Set.of(pairs));
|
||||
UnifyConstraintSet input = new UnifyConstraintSet(Set.of(orConstraint));
|
||||
Optional<Set<UnifyPair>> res = TypeUnify.unifyOrConstraints(input, emptyFC());
|
||||
assert res.isPresent();
|
||||
}
|
||||
|
||||
private FiniteClosure emptyFC(){
|
||||
return new FiniteClosure(new HashSet<>(), null);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user