3 Commits

110 changed files with 5874 additions and 7092 deletions

View File

@@ -1,4 +1,3 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core;
import com.google.common.collect.Lists;
@@ -13,7 +12,6 @@ import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.*;
@@ -24,22 +22,16 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModelParallel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.apache.commons.io.output.NullOutputStream;
import javax.annotation.Nullable;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
public class JavaTXCompiler {
//public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment;
Boolean useResultModel = true;
Optional<String> unificationServer = Optional.empty();
@@ -51,13 +43,16 @@ public class JavaTXCompiler {
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null);
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null);
}
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
//statistics = new FileWriter(new File(System.getProperty("user.dir") + "/" + sources.get(0).getName() + "_"+ new Timestamp(System.currentTimeMillis())));
statistics = new OutputStreamWriter(new NullOutputStream());
@@ -73,6 +68,7 @@ public class JavaTXCompiler {
}
//INSTANCE = this;
}
public JavaTXCompiler(List<File> source, List<File> contextPath, String unificationServer) throws IOException, ClassNotFoundException {
this(source, contextPath);
this.unificationServer = unificationServer == null ? Optional.empty() : Optional.of(unificationServer);
@@ -82,7 +78,9 @@ public class JavaTXCompiler {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
List<ClassOrInterface> importedClasses = new ArrayList<>();
ClassOrInterface objectClass = ASTFactory.createClass(
classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
classLoader.loadClass(new JavaClassName("java.lang.Object").toString())
);
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (File forSourceFile : sourceFiles.keySet()) {
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
@@ -91,7 +89,7 @@ public class JavaTXCompiler {
classLoader.loadClass(name.toString()));
importedClasses.add(importedClass);
}
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){
for (Class<?> c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass);
}
@@ -120,23 +118,20 @@ public class JavaTXCompiler {
ClassOrInterface superclass = null;
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
superclass = objectClass;
}
else {
} else {
Optional<ClassOrInterface> optSuperclass =
importedClasses.stream().filter(x -> x.getClassName().equals(
cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) {
superclass = optSuperclass.get();
}
else {
} else {
optSuperclass =
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) {
superclass = optSuperclass.get();
addMethods(sf, superclass, importedClasses, objectClass);
}
else {
} else {
//throw new ClassNotFoundException("");
}
}
@@ -148,10 +143,8 @@ public class JavaTXCompiler {
while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next());
}
Iterator<Method> methodIt = superclass.getMethods().iterator();
//TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden
while(methodIt.hasNext()) {
Method m = methodIt.next();
for (Method m : superclass.getMethods()) {
ParameterList newParaList = new ParameterList(
m.getParameterList()
.getFormalparalist()
@@ -169,31 +162,11 @@ 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
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
Set<ClassOrInterface> allClasses = new HashSet<>();
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
}
allClasses.addAll(importedClasses);
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// 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<>();
/*
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses());
* }
*/
List<ClassOrInterface> importedClasses = new ArrayList<>();
for (JavaClassName name : forSourceFile.getImports()) {
@@ -319,11 +292,10 @@ public class JavaTXCompiler {
* 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>
@@ -350,45 +322,6 @@ public class JavaTXCompiler {
* phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
* }
*/
/**
* TODO: can this be removed?
*
* @param resultListener
* @param logFile
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
public UnifyResultModelParallel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile)
throws ClassNotFoundException, IOException {
/*
* Gather all available (imported) classes from all parsed source files for putting them into the finite closure
*/
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
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()));
}
/*
* Run the actual type inference process
*/
TypeInference typeInference = new TypeInference(
getConstraints(),
allClasses,
classLoader,
useResultModel,
log,
logFile,
statistics
);
return typeInference.executeAsync(resultListener);
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
/*
@@ -410,8 +343,7 @@ public class JavaTXCompiler {
// TODO: check if this makes sense and does not only always use the first source file key...
logFile = log ? new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())
: new OutputStreamWriter(new NullOutputStream());
}
catch (IOException ioException) {
} catch (IOException ioException) {
System.err.println("IO Exception: " + ioException.getMessage());
logFile = new OutputStreamWriter(new NullOutputStream());
}
@@ -461,7 +393,7 @@ public class JavaTXCompiler {
generateBytecode(path, typeinferenceResult);
}
private Map<File, List<GenericsResult>> generatedGenerics = new HashMap<>();
private final Map<File, List<GenericsResult>> generatedGenerics = new HashMap<>();
// TODO This is a temporary solution, we should integrate with the old API for getting Generics
public Map<File, List<GenericsResult>> getGeneratedGenerics() {
@@ -473,9 +405,8 @@ public class JavaTXCompiler {
* @param typeinferenceResult
* @throws IOException
*/
public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult) throws IOException {
public void generateBytecode(@Nullable File outputPath, List<ResultSet> typeinferenceResult) throws IOException {
for (File f : sourceFiles.keySet()) {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f);
File path;
if (outputPath == null) {
@@ -521,6 +452,7 @@ public class JavaTXCompiler {
}
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/
@@ -538,14 +470,12 @@ public class JavaTXCompiler {
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
params.add(param.acceptTV(this));
}
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret;
return new RefType(refType.getName(), params, new NullToken());
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
return ret;
return new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
}
@Override
@@ -555,14 +485,13 @@ public class JavaTXCompiler {
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
return ret;
return new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if (!gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
throw new DebugException("Cannot visit unknown generic type variable!");
return gtvs.get(genericRefType.getParsedName());
}

View File

@@ -1,26 +1,21 @@
package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.packet.ErrorPacket;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.InvalidPacket;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.server.packet.*;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
/**

View File

@@ -1,24 +1,21 @@
package de.dhbwstuttgart.server;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.server.packet.*;
import de.dhbwstuttgart.typeinference.TypeInference;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SocketServer extends WebSocketServer {

View File

@@ -7,7 +7,6 @@ package de.dhbwstuttgart.server.packet;
* - Have only serializable public properties (or disable them via jackson annotations)
* A packet should have, for easy usage and consisteny:
* - a static create() method
*
*/
public interface IPacket {

View File

@@ -16,7 +16,7 @@ public class PacketContainer {
/*
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
* They have to be private (for the moment) to let jackson fill them in while deserializing
* They have to be public (for the moment) to let jackson fill them in while deserializing
*/
public ErrorPacket errorPacket = null;
public MessagePacket messagePacket = null;

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedResultSet;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Arrays;
import java.util.List;

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import java.util.Arrays;
import java.util.HashSet;

View File

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

View File

@@ -4,13 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* Serializable container of

View File

@@ -8,11 +8,7 @@ import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairT
import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.server.packet.dataContainers.resultPairs.SerializedPairTPHsmallerTPH;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.PairNoResult;
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.*;
/**
* Serializable container of

View File

@@ -2,6 +2,7 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.Arrays;
import java.util.HashSet;

View File

@@ -3,19 +3,9 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedExtendsWildcardType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedGenericRefType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedPlaceholderType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedRefType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedSuperWildcardType;
import de.dhbwstuttgart.server.packet.dataContainers.token.SerializedVoidType;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.server.packet.dataContainers.token.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.type.*;
/**
* Serializable container of

View File

@@ -4,11 +4,8 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* Serializable container of

View File

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.Arrays;
import java.util.HashSet;

View File

@@ -3,17 +3,8 @@ package de.dhbwstuttgart.server.packet.dataContainers;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedExtendsType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedFunNType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedPlaceholderType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedReferenceType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.SerializedSuperType;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.server.packet.dataContainers.unifyType.*;
import de.dhbwstuttgart.typeinference.unify.model.*;
/**
* Serializable container of

View File

@@ -6,6 +6,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedTokenWrapper;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import java.util.Arrays;
/**

View File

@@ -4,6 +4,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import java.util.Arrays;
/**

View File

@@ -5,6 +5,7 @@ import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import java.util.Arrays;
/**

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.server.packet.dataContainers.unifyType;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.dhbwstuttgart.server.packet.dataContainers.SerializedUnifyTypeWrapper;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.Arrays;
/**

View File

@@ -182,7 +182,7 @@ public class UnifyTypeFactory {
if (lhs.getName().equals("AQ")) {
System.out.println("");
}
((PlaceholderType)rhs).enableWildcardtable();
((PlaceholderType)rhs).enableWildcardable();
}
if (((rhs = ret.getLhsType()) instanceof PlaceholderType)
@@ -191,7 +191,7 @@ public class UnifyTypeFactory {
if (rhs.getName().equals("AQ")) {
System.out.println("");
}
((PlaceholderType)lhs).enableWildcardtable();
((PlaceholderType)lhs).enableWildcardable();
}
return ret;
}

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
@@ -8,17 +7,15 @@ import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModelParallel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModelParallel;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.NullWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
@@ -27,8 +24,6 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.NullWriter;
/**
* Provides the entry point of the type inference and unification algorithm via the methods
@@ -64,115 +59,31 @@ public class TypeInference {
this.statisticFileWriter = statisticFileWriter;
}
public UnifyResultModelParallel executeAsync(
UnifyResultListener resultListener
) throws ClassNotFoundException, IOException {
// generate finite closure
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
System.out.println(finiteClosure);
// generate unifyConstraints
ConstraintSet<UnifyPair> unifyConstraints = TypeInferenceHelper.constraintsToUnifyConstraints(constraints);
logFileWriter.write("\nUnify_distributeInnerVars: " + unifyConstraints.toString());
TypeUnify unify = new TypeUnify();
TypeUnify.statistics = statisticFileWriter;
Set<String> paraTypeVarNames = new HashSet<>();
paraTypeVarNames.addAll(TypeInferenceHelper.methodParaTypeVarNames(allClasses));
paraTypeVarNames.addAll(TypeInferenceHelper.constructorParaTypeVarNames(allClasses));
Set<String> returnAndFieldTypeVarNames = new HashSet<>();
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.returnTypeVarNames(allClasses));
returnAndFieldTypeVarNames.addAll(TypeInferenceHelper.fieldTypeVarNames(allClasses));
public static List<ResultSet> executeWithoutContext(
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
urm.addUnifyResultListener(resultListener);
TypeUnify.statistics = new NullWriter();
unifyConstraints = unifyConstraints.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 (returnAndFieldTypeVarNames.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 (returnAndFieldTypeVarNames.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 = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
/*
* 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,
// logFileWriter, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.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))*/;
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
unify.unifyAsync(
(new TypeUnify()).unifyParallel(
unifyConstraints.getUndConstraints(),
oderConstraints,
unifyConstraints.getOderConstraints(),
finiteClosure,
logFileWriter,
shouldLog,
new OutputStreamWriter(new NullOutputStream()),
false,
urm,
usedTasks
new UnifyTaskModelParallel() // TODO: move this to SocketData to cancel the pool once a client disconnects
);
return urm;
return urm.getResults();
}
public List<ResultSet> execute(Optional<String> remoteServer) throws ClassNotFoundException, IOException {
// generate finite closure
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFileWriter, classLoader);
logFileWriter.write("FC:\\" + finiteClosure.toString() + "\n");
logFileWriter.write("FC:\\" + finiteClosure + "\n");
System.out.println(finiteClosure);
// generate unifyConstraints
@@ -196,17 +107,6 @@ public class TypeInference {
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen
/*
unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) {
((PlaceholderType) x.getLhsType()).setVariance((byte)1);
}
else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) {
((PlaceholderType) x.getRhsType()).setVariance((byte)-1);
}
})));
*/
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyConstraints.toString());
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = TypeInferenceHelper.varianceInheritanceConstraintSet(unifyConstraints);
@@ -228,17 +128,8 @@ public class TypeInference {
* (!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 = unifyConstraints.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))*/;
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyConstraints.getOderConstraints();
UnifyTaskModelParallel usedTasks = new UnifyTaskModelParallel();
List<ResultSet> results;
@@ -262,8 +153,7 @@ public class TypeInference {
unify,
unifyConstraints,
oderConstraints,
finiteClosure,
usedTasks
finiteClosure
);
}
@@ -280,9 +170,7 @@ public class TypeInference {
TypeUnify unify,
ConstraintSet<UnifyPair> unifyCons,
List<Set<Constraint<UnifyPair>>> oderConstraints,
IFiniteClosure finiteClosure,
UnifyTaskModelParallel taskModel
IFiniteClosure finiteClosure
) throws IOException {
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(
unifyCons.getUndConstraints(),
@@ -290,29 +178,14 @@ public class TypeInference {
finiteClosure,
logFileWriter,
shouldLog,
new UnifyResultModelParallel(constraints, finiteClosure),
taskModel
new UnifyResultModelParallel(constraints, finiteClosure)
);
System.out.println("RESULT: " + result);
logFileWriter.write("RES: " + result.toString() + "\n");
logFileWriter.flush();
Set<Set<UnifyPair>> results = new HashSet<>(result);
Set<Set<UnifyPair>> results = TypeInferenceHelper.resolveSubstitutions(new HashSet<>(result), finiteClosure);
results = results.stream().map(x -> {
// alle Paare a <.? b erden durch a =. b ersetzt
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y;
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {
// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} else
// wenn nichts veraendert wurde wird x zurueckgegeben
return x;
}).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + results.toString() + "\n");
@@ -332,40 +205,22 @@ public class TypeInference {
UnifyTaskModelParallel taskModel
) throws IOException {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFileWriter, shouldLog, urm,
taskModel);
System.out.println("RESULT Final: " + li.getResults());
unify.unifyParallel(
unifyCons.getUndConstraints(),
oderConstraints,
finiteClosure,
logFileWriter,
shouldLog,
urm,
taskModel
);
System.out.println("RESULT Final: " + urm.getResults());
System.out.println("Constraints for Generated Generics: " + " ???");
logFileWriter.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFileWriter.write("RESULT_FINAL: " + urm.getResults().toString() + "\n");
logFileWriter.flush();
statisticFileWriter.close();
return li.getResults();
}
public static List<ResultSet> executeWithoutContext(
IFiniteClosure finiteClosure,
ConstraintSet<Pair> constraints,
ConstraintSet<UnifyPair> unifyConstraints
) {
UnifyResultModelParallel urm = new UnifyResultModelParallel(constraints, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
TypeUnify.statistics = new NullWriter();
(new TypeUnify()).unifyParallel(
unifyConstraints.getUndConstraints(),
unifyConstraints.getOderConstraints(),
finiteClosure,
new OutputStreamWriter(new NullOutputStream()),
false,
urm,
new UnifyTaskModelParallel() // TODO: move this to SocketData to cancel the pool once a client disconnects
);
return li.getResults();
return urm.getResults();
}
}

View File

@@ -5,23 +5,43 @@ import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.DistributeVariance;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Provides static helper methods for the TypeInferenceAlgorithm to reduce method size
* Provides static helper methods for the TypeInferenceAlgorithm to reduce method size and prevent duplicate code
*/
public class TypeInferenceHelper {
public static Set<Set<UnifyPair>> resolveSubstitutions(Set<Set<UnifyPair>> results, IFiniteClosure finiteClosure) {
return results.stream().map(x -> {
// replace all (a <.? b) constraints with (a =. b) and apply the substitution rule
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y;
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {
// if any constraints have been changed by the substitution, apply all the unification rules again
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} else {
// Otherwise return the constraints, if nothing was changes
return x;
}
}).collect(Collectors.toCollection(HashSet::new));
}
public static ConstraintSet<UnifyPair> constraintsToUnifyConstraints(ConstraintSet<Pair> constraints) {
ConstraintSet<UnifyPair> unifyConstraints = UnifyTypeFactory.convert(constraints);
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
@@ -35,9 +55,8 @@ public class TypeInferenceHelper {
return x;
};
System.out.println("Unify:" + unifyConstraints.toString());
unifyConstraints = unifyConstraints.map(distributeInnerVars);
return unifyConstraints;
return unifyConstraints.map(distributeInnerVars);
}
public static ConstraintSet<UnifyPair> makeFixedPlaceholdersNonWildcardable(
@@ -55,25 +74,25 @@ public class TypeInferenceHelper {
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
((PlaceholderType) x.getLhsType()).disableWildcardable();
}
if (returnAndFieldTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
((PlaceholderType) x.getLhsType()).disableWildcardable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
((PlaceholderType) x.getRhsType()).disableWildcardable();
}
if (returnAndFieldTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
((PlaceholderType) x.getRhsType()).disableWildcardable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
// Hier die jeweils rechte bzw. linke Seite auf die gleiche Varianz setzen, wie die jeweils andere Seite
return x;
});
}
@@ -89,7 +108,7 @@ public class TypeInferenceHelper {
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
})).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b);
return a;
});
@@ -107,7 +126,7 @@ public class TypeInferenceHelper {
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
})).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b);
return a;
});
@@ -138,8 +157,6 @@ public class TypeInferenceHelper {
/**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
* Variance !=0 hat auf alle Typvariablen in Theta.
*
*
*/
public static Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) {
Set<UnifyPair> eq = cons.getAll();
@@ -162,7 +179,7 @@ public class TypeInferenceHelper {
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0));
while (!phSetVariance.isEmpty()) {
PlaceholderType a = phSetVariance.remove(0);
PlaceholderType a = phSetVariance.removeFirst();
usedTPH.add(a);
// HashMap<PlaceholderType,Integer> ht = new HashMap<>();
// ht.put(a, a.getVariance());
@@ -171,8 +188,8 @@ public class TypeInferenceHelper {
// ((PlaceholderType)x.getLhsType()).equals(a)));
// durch if-Abfrage im foreach geloest
cons.forEach(x -> {
if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) {
x.getRhsType().accept(new distributeVariance(), a.getVariance());
if (x.getLhsType() instanceof PlaceholderType && x.getLhsType().equals(a)) {
x.getRhsType().accept(new DistributeVariance(), a.getVariance());
}
});
// ` eq1 = new HashSet<>(eq);
@@ -180,8 +197,8 @@ public class TypeInferenceHelper {
// ((PlaceholderType)x.getRhsType()).equals(a)));
// durch if-Abfrage im foreach geloest
cons.forEach(x -> {
if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) {
x.getLhsType().accept(new distributeVariance(), a.getVariance());
if (x.getRhsType() instanceof PlaceholderType && x.getRhsType().equals(a)) {
x.getLhsType().accept(new DistributeVariance(), a.getVariance());
}
});
phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
@@ -14,9 +13,9 @@ import java.util.ArrayList;
import java.util.List;
public class FieldAssumption extends Assumption {
private ClassOrInterface receiverClass;
private RefTypeOrTPHOrWildcardOrGeneric type;
private String name;
private final ClassOrInterface receiverClass;
private final RefTypeOrTPHOrWildcardOrGeneric type;
private final String name;
public FieldAssumption(String fieldName, ClassOrInterface receiverType,
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope) {

View File

@@ -7,13 +7,7 @@ import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
import java.util.List;

View File

@@ -14,10 +14,10 @@ import java.util.ArrayList;
import java.util.List;
public class MethodAssumption extends Assumption {
private ClassOrInterface receiver;
private RefTypeOrTPHOrWildcardOrGeneric retType;
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
private final Boolean isInherited;
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
private final ClassOrInterface receiver;
private final RefTypeOrTPHOrWildcardOrGeneric retType;
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, Boolean isInherited) {
@@ -28,13 +28,6 @@ public class MethodAssumption extends Assumption{
this.isInherited = isInherited;
}
/*
public RefType getReceiverType() {
return receiver;
}
*/
public ClassOrInterface getReceiver() {
return receiver;
}
@@ -60,11 +53,7 @@ public class MethodAssumption extends Assumption{
return ret;
}
/**
*
* @param resolver
* @return
*/
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar gtv : receiver.getGenerics()) {

View File

@@ -1,22 +1,13 @@
package de.dhbwstuttgart.typeinference.assumptions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.Stack;
import java.util.stream.Collectors;
public class TypeInferenceBlockInformation extends TypeInferenceInformation {
private TypeScope methodContext;
private ClassOrInterface currentClass;
private final TypeScope methodContext;
private final ClassOrInterface currentClass;
public TypeInferenceBlockInformation(Collection<ClassOrInterface> availableClasses,
ClassOrInterface currentClass, TypeScope methodContext) {
@@ -24,12 +15,15 @@ public class TypeInferenceBlockInformation extends TypeInferenceInformation {
this.methodContext = new TypeScopeContainer(currentClass, methodContext);
this.currentClass = currentClass;
}
public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) {
this(oldScope.getAvailableClasses(), oldScope.currentClass, new TypeScopeContainer(oldScope.methodContext, newScope));
}
public ClassOrInterface getCurrentClass() {
return currentClass;
}
public TypeScope getCurrentTypeScope() {
return methodContext;
}

View File

@@ -1,20 +1,15 @@
package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/*
Anmerkung:
@@ -27,7 +22,7 @@ Zweiteres hat den Vorteil, dass bei der Entwicklung leichter Dinge hinzugefügt
Die ganze Logik steckt in dieser Klasse.
*/
public class TypeInferenceInformation {
private Collection<ClassOrInterface> classes;
private final Collection<ClassOrInterface> classes;
public TypeInferenceInformation(Collection<ClassOrInterface> availableClasses) {
classes = availableClasses;

View File

@@ -12,6 +12,7 @@ import java.util.stream.Collectors;
public class TypeScopeContainer implements TypeScope {
ArrayList<TypeScope> scopes = new ArrayList<>();
Stack<RefTypeOrTPHOrWildcardOrGeneric> types = new Stack<>();
public TypeScopeContainer(TypeScope scope1, TypeScope scope2) {
scopes.add(scope1);
scopes.add(scope2);

View File

@@ -1,21 +1,16 @@
package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
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
/*
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
* auszuwaehlen
*/
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
private Constraint<A> extendConstraint = null;
public Constraint() {

View File

@@ -1,9 +1,7 @@
package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.util.*;
import java.util.function.BinaryOperator;
@@ -40,7 +38,7 @@ public class ConstraintSet<A> {
public String toString() {
BinaryOperator<String> b = (x, y) -> x + y;
return "\nUND:" + this.undConstraints.toString() + "\n" +
"ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
"ODER:" + this.oderConstraints.stream().reduce("", (x, y) -> x + "\n" + y, b);
//cartesianProduct().toString();
}

View File

@@ -1,14 +1,11 @@
package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/**
* Wird für Generics benötigt
* TODO: Erklörung!
*/
public interface GenericsResolver {
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic);
RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic);
}

View File

@@ -1,15 +1,15 @@
package de.dhbwstuttgart.typeinference.constraints;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class Pair implements Serializable
{
public class Pair implements Serializable {
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
@@ -17,8 +17,7 @@ public class Pair implements Serializable
private Boolean noUnification = false;
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
{
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
this.TA1 = TA1;
this.TA2 = TA2;
if (TA1 == null || TA2 == null)
@@ -26,24 +25,35 @@ public class Pair implements Serializable
eOperator = PairOperator.SMALLER;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp)
{
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
{
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
this.noUnification = noUnification;
}
public String toString()
{
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
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;
}
public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL";
String strElement2 = "NULL";
@@ -71,11 +81,11 @@ public class Pair implements Serializable
/**
* <br/>Author: J�rg B�uerle
*
* @param obj
* @return
*/
public boolean equals(Object obj)
{
public boolean equals(Object obj) {
boolean ret = true;
ret &= (obj instanceof Pair);
if (!ret) return ret;
@@ -88,8 +98,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist.
*/
public boolean OperatorEqual()
{
public boolean OperatorEqual() {
return eOperator == PairOperator.EQUALSDOT;
}
@@ -97,8 +106,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist.
*/
public boolean OperatorSmaller()
{
public boolean OperatorSmaller() {
return eOperator == PairOperator.SMALLER;
}
@@ -106,8 +114,7 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist.
*/
public boolean OperatorSmallerExtends()
{
public boolean OperatorSmallerExtends() {
return eOperator == PairOperator.SMALLERDOTWC;
}
@@ -115,28 +122,12 @@ public class Pair implements Serializable
* Author: Arne Lüdtke<br/>
* Gibt den Operator zurück.
*/
public PairOperator GetOperator()
{
public PairOperator GetOperator() {
return eOperator;
}
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
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;
}
}
// ino.end

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.constraints.Pair;
@@ -13,15 +12,9 @@ public class GenericInsertPair {
TA2 = superType;
}
public GenericInsertPair(Pair pair) {
TA1 = (TypePlaceholder) pair.TA1;
TA2 = (TypePlaceholder) pair.TA2;
}
public boolean contains(TypePlaceholder additionalTPH) {
if (TA1.equals(additionalTPH)) return true;
if(TA2.equals(additionalTPH))return true;
return false;
return TA2.equals(additionalTPH);
}
@Override

View File

@@ -2,22 +2,13 @@ package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/**
* enthaelt alle Paare, die in einem Ergebnis nicht vorkommen koennen
* sie sind noetig fuer origPairs in PairTPHsmallerTPH, da hier auch
* Paare vorkommen koennen die keine Result sind (z.B. bei FunN$$)
* Contains all pairs, that cannot be in a result.
* They are required for origPairs in PairTPHsmallerTPH, because there can
* be pairs as well, that are no results (e.g. FunN$$)
*/
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric> {
//public final TypePlaceholder left;
//public final TypePlaceholder right;
/*
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
* wichtig fuer generated Generics
*/
ResultPair origPair;
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right) {
super(left, right);

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {

View File

@@ -1,13 +1,12 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/**
* Steht für A =. RefType
*/
public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
public class PairTPHequalRefTypeOrWildcardType extends ResultPair<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> {
public final TypePlaceholder left;
public final RefTypeOrTPHOrWildcardOrGeneric right;

View File

@@ -6,15 +6,14 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/**
* Steht für: A <. B
*/
public class PairTPHsmallerTPH extends ResultPair{
public class PairTPHsmallerTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {
public final TypePlaceholder left;
public final TypePlaceholder right;
/*
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
* wichtig fuer generated Generics
/**
* the original pair from which this result pair was generated. Important for generated generics
*/
ResultPair origPair;
ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair;
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right) {
super(left, right);
@@ -22,7 +21,11 @@ public class PairTPHsmallerTPH extends ResultPair{
this.right = right;
}
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right, ResultPair origPair){
public PairTPHsmallerTPH(
TypePlaceholder left,
TypePlaceholder right,
ResultPair<? extends RefTypeOrTPHOrWildcardOrGeneric, ? extends RefTypeOrTPHOrWildcardOrGeneric> origPair
) {
this(left, right);
this.origPair = origPair;
}

View File

@@ -1,27 +1,20 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.util.Set;
public class ResolvedType {
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
private ResultPair<?, ?> resultPair;
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
//public final Set<GenericInsertPair> additionalGenerics;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType) {
this.resolvedType = resolvedType;
//this.additionalGenerics = additionalGenerics;
}
public void setResultPair(ResultPair<?, ?> resultPair) {
this.resultPair = resultPair;
}
public ResultPair<?, ?> getResultPair() {
return resultPair;
}
public void setResultPair(ResultPair<?, ?> resultPair) {
this.resultPair = resultPair;
}
}

View File

@@ -9,13 +9,13 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
private final A left;
private final B right;
public abstract void accept(ResultPairVisitor visitor);
public ResultPair(A left, B right) {
this.left = left;
this.right = right;
}
public abstract void accept(ResultPairVisitor visitor);
public A getLeft() {
return left;
}
@@ -52,11 +52,8 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
} else if (!left.getOffset().equals(other.left.getOffset()))
return false;
if (right == null) {
if (other.right != null)
return false;
} else if (!right.getOffset().equals(other.right.getOffset()))
return false;
return true;
return other.right == null;
} else return right.getOffset().equals(other.right.getOffset());
}
}

View File

@@ -2,7 +2,9 @@ package de.dhbwstuttgart.typeinference.result;
public interface ResultPairVisitor {
void visit(PairTPHsmallerTPH p);
void visit(PairTPHequalRefTypeOrWildcardType p);
void visit(PairTPHEqualTPH p);
//bisher nicht umgesetzt

View File

@@ -1,16 +1,11 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.HashSet;
import java.util.Set;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@SuppressWarnings("rawtypes")
public class ResultSet {
@@ -20,7 +15,11 @@ public class ResultSet {
public ResultSet(Set<ResultPair> set) {
this.results = set;
this.genIns = new HashSet<>();
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} );
results.forEach(x -> {
if (x instanceof PairTPHsmallerTPH) {
this.genIns.add(x);
}
});
}
public boolean contains(ResultPair toCheck) {
@@ -34,11 +33,11 @@ public class ResultSet {
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
if (type instanceof TypePlaceholder)
return new Resolver(this).resolve((TypePlaceholder) type);
if(type instanceof GenericRefType)return new ResolvedType(type, new HashSet<>());
if (type instanceof GenericRefType) return new ResolvedType(type);
if (type instanceof RefType) {
RelatedTypeWalker related = new RelatedTypeWalker(null, this);
type.accept(related);
return new ResolvedType(type, related.relatedTPHs);
return new ResolvedType(type);
} else {
throw new NotImplementedException();
//return new ResolvedType(type,new HashSet<>());
@@ -51,8 +50,7 @@ public class ResultSet {
@Override
public boolean equals(Object o) {
if (o instanceof ResultSet) {
ResultSet other = (ResultSet)o;
if (o instanceof ResultSet other) {
return this.results.equals(other.results);
} else {
return false;
@@ -67,9 +65,9 @@ public class ResultSet {
class Resolver implements ResultSetVisitor {
private final ResultSet result;
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
private TypePlaceholder toResolve;
private RefTypeOrTPHOrWildcardOrGeneric resolved;
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
private ResultPair<?, ?> currentPair;
public Resolver(ResultSet resultPairs) {
@@ -94,7 +92,7 @@ class Resolver implements ResultSetVisitor {
resolved = tph;
}
ResolvedType result = new ResolvedType(resolved, additionalTPHs);//resolved;
ResolvedType result = new ResolvedType(resolved); //resolved;
result.setResultPair(currentPair);
return result;
}
@@ -152,7 +150,6 @@ class Resolver implements ResultSetVisitor {
}
}
/**
@@ -162,8 +159,8 @@ class Resolver implements ResultSetVisitor {
class TPHResolver implements ResultSetVisitor {
private final TypePlaceholder tph;
Set<GenericInsertPair> resolved = new HashSet<>();
private final ResultSet resultSet;
Set<GenericInsertPair> resolved = new HashSet<>();
TPHResolver(TypePlaceholder tph, ResultSet resultSet) {
this.resultSet = resultSet;
@@ -171,7 +168,7 @@ class TPHResolver implements ResultSetVisitor {
for (ResultPair p : resultSet.results) {
p.accept(this);
}
if(resolved.size() == 0){
if (resolved.isEmpty()) {
resolved.add(new GenericInsertPair(tph, null));
}
}
@@ -236,6 +233,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
/**
* Läuft über das resultSet und speichert alle TPHs, welche mit start in Verbindung stehen
*
* @param start - kann null sein, wenn der Walker für einen RefType benutzt wird
* @param resultSet
*/

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
@@ -9,7 +8,7 @@ import java.util.HashMap;
import java.util.List;
/**
* Ein GenericsResolver, welcher Generics mit dem selben Namen den selben TPH zuordnet
* A generics resolver, which assigns generics with the same name to the same TPH
*/
public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
@@ -26,8 +25,7 @@ public class GenericsResolverSameName implements GenericsResolver, TypeVisitor<R
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
params.add(param.acceptTV(this));
}
RefType ret = new RefType(refType.getName(), params, refType.getOffset());
return ret;
return new RefType(refType.getName(), params, refType.getOffset());
}
@Override

View File

@@ -1,17 +1,15 @@
package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.util.BiRelation;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import java.util.*;
import java.util.Collection;
public class TYPE {
@@ -23,8 +21,8 @@ public class TYPE {
this.typeInferenceInformation = new TypeInferenceInformation(allAvailableClasses);
}
public ConstraintSet getConstraints() {
ConstraintSet ret = new ConstraintSet();
public ConstraintSet<Pair> getConstraints() {
ConstraintSet<Pair> ret = new ConstraintSet<>();
for (SourceFile sf : sfs)
for (ClassOrInterface cl : sf.KlassenVektor) {
ret.addAll(getConstraintsClass(cl, typeInferenceInformation));
@@ -32,11 +30,12 @@ public class TYPE {
return ret;
}
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
ConstraintSet methConstrains;
private ConstraintSet<Pair> getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet<Pair> ret = new ConstraintSet<>();
for (Method m : cl.getMethods()) {
ret.addAll(methConstrains = getConstraintsMethod(m,info, cl));
ConstraintSet<Pair> methConstrains = getConstraintsMethod(m, info, cl);
ret.addAll(methConstrains);
m.constraints.addAll(methConstrains);
}
for (Constructor m : cl.getConstructors()) {
@@ -69,19 +68,19 @@ public class TYPE {
}
*/
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
private ConstraintSet<Pair> getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if (m.block == null) return new ConstraintSet<>(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo);
m.block.accept(methodScope);
return methodScope.getConstraints();
}
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
private ConstraintSet<Pair> getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo);
//for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope);
ConstraintSet ret = this.getConstraintsMethod(m, info, currentClass);
ConstraintSet<Pair> ret = this.getConstraintsMethod(m, info, currentClass);
ret.addAll(methodScope.getConstraints());
return ret;
}

View File

@@ -11,41 +11,45 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.FunNClass;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.*;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.BiRelation;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TYPEStmt implements StatementVisitor {
private final TypeInferenceBlockInformation info;
private final ConstraintSet constraintsSet = new ConstraintSet();
private final ConstraintSet<Pair> constraintsSet = new ConstraintSet<>();
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
private final RefType longg = new RefType(ASTFactory.createClass(Long.class).getClassName(), new NullToken());
private final RefType integer = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
private final RefType shortt = new RefType(ASTFactory.createClass(Short.class).getClassName(), new NullToken());
private final RefType bytee = new RefType(ASTFactory.createClass(Byte.class).getClassName(), new NullToken());
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
public TYPEStmt(TypeInferenceBlockInformation info) {
this.info = info;
}
public ConstraintSet getConstraints() {
return constraintsSet;
}
/**
* Erstellt einen neuen GenericResolver
* Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen.
* Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen
* kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
* @return
* Creates a new GenericsResolver
* The idea behind this data-structure is to assign a unique TPH to GTVs.
* On method calls or other accesses where all used GTVs must get a unique TPH, this class can be used.
* It is important to always use a fresh instance for that.
*/
private static GenericsResolver getResolverInstance() {
return new GenericsResolverSameName();
@@ -55,6 +59,69 @@ public class TYPEStmt implements StatementVisitor{
return null;
}
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken)
if (name.equals("apply")) {
List<GenericRefType> funNParams = new ArrayList<>();
for (int i = 0; i < numArgs + 1; i++) {
//funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(),
new NullToken()));
}
funNParams.get(funNParams.size() - 1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size() - 1), funNParams.subList(0, funNParams.size() - 1),
new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
throw new NotImplementedException();
}
}, false));
}
for (ClassOrInterface cl : info.getAvailableClasses()) {
for (Method m : cl.getMethods()) {
if (m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs) {
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(), info),
createTypeScope(cl, m), m.isInherited));
}
}
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info) {
//TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
Beispiel:
auto test = new List<String>();
test.add("hallo");
Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A>
Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (FormalParameter fp : parameterList.getFormalparalist()) {
params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben
}
return params;
}
public ConstraintSet<Pair> getConstraints() {
return constraintsSet;
}
@Override
public void visit(ArgumentList arglist) {
for (int i = 0; i < arglist.getArguments().size(); i++) {
@@ -71,7 +138,6 @@ public class TYPEStmt implements StatementVisitor{
constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getType(),
new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
//new FunN(lambdaParams),
PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getReturnType(),
@@ -111,16 +177,16 @@ public class TYPEStmt implements StatementVisitor{
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>();
Set<Constraint<Pair>> oderConstraints = new HashSet<>();
for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint();
Constraint<Pair> constraint = new Constraint<>();
GenericsResolver resolver = getResolverInstance();
constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT)); //PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten
constraint.add(new Pair(
fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if(oderConstraints.size() == 0)
if (oderConstraints.isEmpty())
throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
}
@@ -155,23 +221,23 @@ public class TYPEStmt implements StatementVisitor{
@Override
public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig
// Constraints are only generated for field variables. Local variables are unambiguous
}
@Override
public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
// Nothing to do here. All local variables get their correct type already while being parsed
}
@Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
// In oder-constraints it is assumed, that the conditions for the argument types are placed left
// and the types of the return values are placed right (see JavaTXCompiler)
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
//Overloading:
Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
for (MethodAssumption m : getMethods(methodCall.name, methodCall.arglist, info)) {
GenericsResolver resolver = getResolverInstance();
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
methodConstraints.addAll(oneMethodConstraints);
@@ -189,7 +255,7 @@ public class TYPEStmt implements StatementVisitor{
methodConstraints.add(extendsOneMethodConstraint);
*/
}
if(methodConstraints.size()<1){
if (methodConstraints.isEmpty()) {
throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
@@ -198,11 +264,11 @@ public class TYPEStmt implements StatementVisitor{
@Override
public void visit(NewClass methodCall) {
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) {
methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance()));
}
if(methodConstraints.size()<1){
if (methodConstraints.isEmpty()) {
throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
@@ -218,15 +284,6 @@ public class TYPEStmt implements StatementVisitor{
receiver.expr.accept(this);
}
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
private final RefType longg = new RefType(ASTFactory.createClass(Long.class).getClassName(), new NullToken());
private final RefType integer = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
private final RefType shortt = new RefType(ASTFactory.createClass(Short.class).getClassName(), new NullToken());
private final RefType bytee = new RefType(ASTFactory.createClass(Byte.class).getClassName(), new NullToken());
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
@Override
public void visit(UnaryExpr unaryExpr) {
if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT ||
@@ -234,7 +291,7 @@ public class TYPEStmt implements StatementVisitor{
unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT ||
unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
//@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben
// Expression must be convertable to Numeric and also inherit from Numeric
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT));
// The type of the postfix increment expression is the type of the variable
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT));
@@ -244,8 +301,8 @@ public class TYPEStmt implements StatementVisitor{
}
@Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
// In oder-constraints it is assumed, that the conditions for the argument types are placed left
// and the types of the return values are placed right (see JavaTXCompiler)
public void visit(BinaryExpr binary) {
binary.lexpr.accept(this);
binary.rexpr.accept(this);
@@ -262,13 +319,12 @@ public class TYPEStmt implements StatementVisitor{
// pruefen, ob Typen richtig bestimmt werden.
//Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer:
//see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben
Constraint<Pair> numeric;
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
@@ -276,7 +332,7 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(numeric);
}
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
@@ -284,7 +340,7 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(numeric);
}
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
@@ -292,7 +348,7 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(numeric);
}
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
@@ -300,7 +356,7 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(numeric);
}
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
@@ -308,7 +364,7 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(numeric);
}
//PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
@@ -328,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{
if (binary.operation.equals(BinaryExpr.Operator.ADD)) {
//Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
if (info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
Constraint<Pair> stringConcat = new Constraint<>();
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT));
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT));
@@ -336,8 +392,8 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(stringConcat);
}
}
if(numericAdditionOrStringConcatenation.size()<1){
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
if (numericAdditionOrStringConcatenation.isEmpty()) {
throw new TypeinferenceException("Kein Typ für " + binary.operation + " vorhanden", binary.getOffset());
}
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
} else if (binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) ||
@@ -406,9 +462,8 @@ public class TYPEStmt implements StatementVisitor{
@Override
public void visit(Literal literal) {
//Nothing to do here. Literale erzeugen keine Constraints
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
//PL 2018-06-23 Literale haben einen Typ. Der muesste hier eingefuegt werden
//wie hier fuer double gezeigt. Im Moment auskommentiert, weil zu wenige Literaltypen
//funktionieren
if (literal.value instanceof Short) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
@@ -431,40 +486,37 @@ public class TYPEStmt implements StatementVisitor{
return;
}
if (literal.value instanceof Integer) {
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT));
// /*
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new));
Set<Constraint> oderConstraints = new HashSet<>();
Constraint constraint = new Constraint();
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(ClassOrInterface::getClassName).collect(Collectors.toCollection(HashSet::new));
Set<Constraint<Pair>> oderConstraints = new HashSet<>();
Constraint<Pair> constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) {
constraint = new Constraint();
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Double"))) {
constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) {
constraint = new Constraint();
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Long"))) {
constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) {
constraint = new Constraint();
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Float"))) {
constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) {
constraint = new Constraint();
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Short"))) {
constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) {
constraint = new Constraint();
if (clNames.stream().anyMatch(x -> x.toString().equals("java.lang.Byte"))) {
constraint = new Constraint<>();
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
constraintsSet.addOderConstraint(oderConstraints);
// */
return;
}
if (literal.value instanceof Short) {
@@ -485,9 +537,7 @@ public class TYPEStmt implements StatementVisitor{
}
if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
return;
}
else {
} else {
throw new NotImplementedException();
}
}
@@ -526,28 +576,14 @@ public class TYPEStmt implements StatementVisitor{
aThis.getType(), thisType, PairOperator.EQUALSDOT));
}
private static TypeScope createNullTypeScope() {
return new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
return new ArrayList<>();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return null;
}
};
}
@Override
public void visit(WhileStmt whileStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
//Expression inferieren:
// Infer expression:
whileStmt.expr.accept(this);
//Expression muss boolean sein:
// Expression must be boolean:
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT));
//LoopBlock inferieren:
// Infer loopBlock:
whileStmt.loopBlock.accept(this);
}
@@ -556,6 +592,10 @@ public class TYPEStmt implements StatementVisitor{
throw new NotImplementedException();
}
/*
METHOD CALL Section:
*/
@Override
public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
@@ -573,27 +613,12 @@ public class TYPEStmt implements StatementVisitor{
//TODO: Für einen super-Call werden keine Constraints erzeugt bisher
}
/*
METHOD CALL Section:
*/
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint<Pair> methodConstraint, extendsMethodConstraint;
methodConstraint = new Constraint<>(assumption.isInherited());
extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall)
ClassOrInterface receiverCl = assumption.getReceiver();
/*
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiverCl.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(gtv.getName()));
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));//PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
@@ -645,7 +670,6 @@ public class TYPEStmt implements StatementVisitor{
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
@@ -655,7 +679,6 @@ public class TYPEStmt implements StatementVisitor{
return ret;
}
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>();
@@ -673,65 +696,6 @@ public class TYPEStmt implements StatementVisitor{
return ret;
}
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken)
if(name.equals("apply")){
List<GenericRefType> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
//funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(),
new NullToken()));
}
funNParams.get(funNParams.size()-1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size()-1), funNParams.subList(0, funNParams.size()-1),
new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
throw new NotImplementedException();
}
}, false));
}
for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){
if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m), m.isInherited));
}
}
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
//TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
BEispiel:
auto test = new List<String>();
test.add("hallo");
Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A>
Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben
}
return params;
}
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList) {
List<MethodAssumption> ret = new ArrayList<>();
for (ClassOrInterface cl : info.getAvailableClasses()) {
@@ -749,7 +713,7 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint methodConstraint = new Constraint();
Constraint<Pair> methodConstraint = new Constraint<>();
//WELCHEN SINN MACHT DIESER CONSTRAINT???
//Ist er nicht immer classname <. classname und damit redundant?
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(),

View File

@@ -0,0 +1,51 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class DistributeVariance extends VisitUnifyTypeVisitor<Integer> {
public static int inverseVariance(int variance) {
// TODO: or should this simply be "return -variance;" ???
return switch (variance) {
case 1 -> -1;
case -1 -> 1;
default -> 0;
};
}
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
//PL 2018-05-17 urspruengliche Variance nicht veraendern
//else if (phty.getVariance() != ht) {
// phty.setVariance(0);
//}
}
return phty;
}
public FunNType visit(FunNType funnty, Integer ht) {
List<UnifyType> param = new ArrayList<>(Arrays.asList(funnty.getTypeParams().get()));
UnifyType resultType = param.removeLast();
Integer htInverse = inverseVariance(ht);
param = param.stream()
.map(x -> x.accept(this, htInverse))
.collect(Collectors.toCollection(ArrayList::new));
param.add(resultType.accept(this, ht));
return FunNType.getFunNType(new TypeParams(param));
}
}

View File

@@ -0,0 +1,15 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import java.util.HashMap;
public class FreshPlaceholder extends VisitUnifyTypeVisitor<HashMap<PlaceholderType, PlaceholderType>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType, PlaceholderType> ht) {
return ht.get(phty);
}
}

View File

@@ -1,16 +1,15 @@
package de.dhbwstuttgart.typeinference.unify;
import com.google.common.collect.Sets;
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Sets;
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
/**
* Implements set operations using google guava.
* @author DH10STF
*
* @author DH10STF
*/
public class GuavaSetOperations implements ISetOperations {

View File

@@ -1,22 +1,14 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
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 implements IUnify {

View File

@@ -11,6 +11,7 @@ import java.util.stream.Collectors;
/**
* Implementation of match derived from unification algorithm.
*
* @author Martin Pluemicke
*/
public class Match implements IMatch {
@@ -73,7 +74,7 @@ public class Match implements IMatch {
// SUBST - Rule
if (lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType);
termsList = termsList.stream().map(mgu::applyleft).collect(Collectors.toCollection(ArrayList::new));
termsList = termsList.stream().map(mgu::applyLeft).collect(Collectors.toCollection(ArrayList::new));
idx = idx + 1 == termsList.size() ? 0 : idx + 1;
continue;
}

View File

@@ -15,8 +15,8 @@ import java.util.stream.Collectors;
/**
* Implementation of the type inference rules.
* @author Florian Steurer
*
* @author Florian Steurer
*/
public class RuleSet implements IRuleSet {
@@ -225,16 +225,13 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
UnifyType c = pair.getLhsType();
if(!(c instanceof ReferenceType))
if (!(c instanceof ReferenceType lhsSType))
return Optional.empty();
UnifyType d = pair.getRhsType();
if(!(d instanceof ReferenceType))
if (!(d instanceof ReferenceType rhsSType))
return Optional.empty();
ReferenceType lhsSType = (ReferenceType) c;
ReferenceType rhsSType = (ReferenceType) d;
//try {
// logFile.write("PAIR Rules: " + pair + "\n");
// logFile.flush();
@@ -310,19 +307,16 @@ public class RuleSet implements IRuleSet{
if ((lhsType instanceof ReferenceType) && (rhsType instanceof ReferenceType)) {
lhsSType = (ReferenceType) lhsType;
rhsSType = (ReferenceType) rhsType;
}
else if (((lhsType instanceof ExtendsType) && (rhsType instanceof ExtendsType))
} 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
} else
return Optional.empty();
}
else
} else
return Optional.empty();
if (lhsSType.getTypeParams().empty())
@@ -348,7 +342,8 @@ public class RuleSet implements IRuleSet{
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 (!(lhsSType.getTypeParams().size() == rhsSType.getTypeParams().size()))
throw new DebugException("Fehler in Unifizierung" + " " + lhsSType + " " + rhsSType);
//if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size())
// return Optional.empty();
@@ -464,9 +459,6 @@ public class RuleSet implements IRuleSet{
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();
@@ -526,7 +518,7 @@ public class RuleSet implements IRuleSet{
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;
typeDgen = opt.map(ExtendsType::new).orElse(null);
}
if (typeDgen == null)
@@ -536,7 +528,7 @@ public class RuleSet implements IRuleSet{
Optional<UnifyType> opt = grArg.stream().filter(x -> x.getName().equals(typeExtDs.getName())).findAny();
if(!opt.isPresent())
if (opt.isEmpty())
return Optional.empty();
UnifyType newLhs = ((ExtendsType) opt.get()).getExtendedType();
@@ -570,7 +562,7 @@ public class RuleSet implements IRuleSet{
Optional<UnifyType> opt = fc.getLeftHandedType(((SuperType) typeSupD).getSuperedType().getName());
if(!opt.isPresent())
if (opt.isEmpty())
return Optional.empty();
UnifyType typeDgen = opt.get();
@@ -581,7 +573,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyType> smArg = fc.smArg(typeSupDgen, new HashSet<>());
opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny();
if(!opt.isPresent())
if (opt.isEmpty())
return Optional.empty();
// New RHS
@@ -605,6 +597,7 @@ public class RuleSet implements IRuleSet{
/**
* 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.
@@ -655,7 +648,7 @@ public class RuleSet implements IRuleSet{
if (t1 instanceof SuperType)
occuringTypes.push(((SuperType) t1).getSuperedType());
else
t1.getTypeParams().forEach(x -> occuringTypes.push(x));
t1.getTypeParams().forEach(occuringTypes::push);
}
Queue<UnifyPair> result1 = new LinkedList<UnifyPair>(pairs);
ArrayList<UnifyPair> result = new ArrayList<UnifyPair>();
@@ -690,15 +683,7 @@ public class RuleSet implements IRuleSet{
: () -> new Constraint<UnifyPair>(b.isInherited())
));
oderConstraints.replaceAll(oc -> oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new)));
/*
oderConstraints = oderConstraints.stream().map(
a -> a.stream().map(applyUni
//b -> b.stream().map(
// x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new) )
).collect(Collectors.toCollection(HashSet::new))
).collect(Collectors.toList(ArrayList::new));
}
*/
applied = true;
}
result.add(pair);
@@ -759,52 +744,6 @@ public class RuleSet implements IRuleSet{
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
}
/* PL 2018-03-06 auskommentiert sind mutmaßlich falsch
* vgl. JAVA_BSP/Wildcard6.java
@Override
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
return Optional.empty();
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof SuperType))
return Optional.empty();
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((SuperType) rhsType).getSuperedType(), PairOperator.EQUALSDOT));
}
@Override
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
return Optional.empty();
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof SuperType) || !(rhsType instanceof ExtendsType))
return Optional.empty();
return Optional.of(new UnifyPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT));
}
@Override
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
return Optional.empty();
UnifyType rhsType = pair.getRhsType();
if(!(rhsType instanceof ReferenceType))
return Optional.empty();
UnifyType lhsType = pair.getLhsType();
if(lhsType instanceof WildcardType)
return Optional.of(new UnifyPair(((WildcardType) lhsType).getWildcardedType(), rhsType, PairOperator.EQUALSDOT));
return Optional.empty();
}
*/
@Override
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) {
if ((pair.getPairOp() != PairOperator.SMALLERDOT)
@@ -816,12 +755,9 @@ public class RuleSet implements IRuleSet{
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof FunNType) || !(rhsType instanceof FunNType))
if (!(lhsType instanceof FunNType funNLhsType) || !(rhsType instanceof FunNType funNRhsType))
return Optional.empty();
FunNType funNLhsType = (FunNType) lhsType;
FunNType funNRhsType = (FunNType) rhsType;
if (funNLhsType.getN() != funNRhsType.getN())
return Optional.empty();
@@ -831,17 +767,21 @@ public class RuleSet implements IRuleSet{
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
} 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(); }
result.stream().forEach(x -> {
UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) {
((PlaceholderType) l).disableWildcardable();
}
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
if (r instanceof PlaceholderType) {
((PlaceholderType) r).disableWildcardable();
}
});
logFile.write("FUNgreater: " + pair + "\n");
logFile.write("FUNred: " + result + "\n");
@@ -857,15 +797,13 @@ public class RuleSet implements IRuleSet{
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof FunNType) || !(rhsType instanceof PlaceholderType))
if (!(lhsType instanceof FunNType funNLhsType) || !(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);
Integer inversVariance = DistributeVariance.inverseVariance(variance);
UnifyType[] freshPlaceholders = new UnifyType[funNLhsType.getTypeParams().size()];
for (int i = 0; i < freshPlaceholders.length - 1; i++) {
@@ -882,10 +820,15 @@ public class RuleSet implements IRuleSet{
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(); }
result.stream().forEach(x -> {
UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) {
((PlaceholderType) l).disableWildcardable();
}
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
if (r instanceof PlaceholderType) {
((PlaceholderType) r).disableWildcardable();
}
});
logFile.write("FUNgreater: " + pair + "\n");
@@ -902,15 +845,13 @@ public class RuleSet implements IRuleSet{
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof FunNType))
if (!(lhsType instanceof PlaceholderType) || !(rhsType instanceof FunNType funNRhsType))
return Optional.empty();
FunNType funNRhsType = (FunNType) rhsType;
Set<UnifyPair> result = new HashSet<UnifyPair>();
Integer variance = ((PlaceholderType)lhsType).getVariance();
Integer inversVariance = distributeVariance.inverseVariance(variance);
int variance = ((PlaceholderType) lhsType).getVariance();
int inversVariance = DistributeVariance.inverseVariance(variance);
UnifyType[] freshPlaceholders = new UnifyType[funNRhsType.getTypeParams().size()];
for (int i = 0; i < freshPlaceholders.length - 1; i++) {
@@ -928,10 +869,15 @@ public class RuleSet implements IRuleSet{
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(); }
result.stream().forEach(x -> {
UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) {
((PlaceholderType) l).disableWildcardable();
}
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
if (r instanceof PlaceholderType) {
((PlaceholderType) r).disableWildcardable();
}
});
logFile.write("FUNgreater: " + pair + "\n");
@@ -1002,7 +948,7 @@ public class RuleSet implements IRuleSet{
else {
UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
Set<UnifyType> fBounded = pair.getfBounded();
Set<UnifyType> fBounded = pair.getFBounded();
fBounded.add(lhsType);
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair(), fBounded));
}

View File

@@ -12,88 +12,78 @@ import java.util.concurrent.ForkJoinPool;
public class TypeUnify {
public static Writer statistics;
/**
* unify parallel ohne result modell
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
* Unify parallel without result model
*/
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
ForkJoinPool pool = new ForkJoinPool(
Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null,
true
);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(
undConstrains,
oderConstraints,
fc,
true,
new WriterActiveObject(logFile, pool),
log,
resultModel,
pool
);
pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join();
return res;
return unifyTask.join();
}
/**
* unify asynchron mit Rückgabe UnifyResultModel, ohne dass alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
* Unify parallel returning UnifyResultModel after gathering all results
*/
public UnifyResultModelParallel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
public void unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(
Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null,
true
);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool);
pool.invoke(unifyTask);
return resultModel;
}
/**
* unify parallel mit Rückgabe UnifyResultModel nachdem alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
*/
public UnifyResultModelParallel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
taskModel.setPool(pool);
resultModel.setPool(pool);
TypeUnifyTask unifyTask = //new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
new TypeUnifyTask(undConstrains, oderConstraints, fc, true, new WriterActiveObject(logFile, pool), log, resultModel, pool, statistics);
TypeUnifyTask unifyTask = new TypeUnifyTask(
undConstrains,
oderConstraints,
fc,
true,
new WriterActiveObject(logFile, pool),
log,
resultModel,
pool,
statistics
);
pool.invoke(unifyTask);
unifyTask.join();
return resultModel;
}
/*
public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile, Boolean log) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log);
Set<Set<UnifyPair>> res = unifyTask.compute();
return res;
}
*/
/**
* unify sequentiell mit oderconstraints
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @return
* Unify sequential with oder-constraints
*/
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel, UnifyTaskModelParallel taskModel) {
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModelParallel resultModel) {
resultModel.setPool(ForkJoinPool.commonPool());
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, new WriterActiveObject(logFile, ForkJoinPool.commonPool()), log, resultModel, ForkJoinPool.commonPool());
unifyTask.statisticsFile = statistics;
Set<Set<UnifyPair>> res = unifyTask.compute();
return res;
TypeUnifyTask unifyTask = new TypeUnifyTask(
undConstrains,
oderConstraints,
fc,
false,
new WriterActiveObject(logFile, ForkJoinPool.commonPool()),
log,
resultModel,
ForkJoinPool.commonPool()
);
TypeUnifyTask.statisticsFile = statistics;
return unifyTask.compute();
}
}

View File

@@ -4,7 +4,6 @@ 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;
import java.util.concurrent.ForkJoinPool;
@@ -14,16 +13,6 @@ public class TypeUnify2Task extends TypeUnifyTask {
Set<Set<UnifyPair>> setToFlatten;
Set<UnifyPair> methodSignatureConstraintUebergabe;
//statistics
TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints,
Set<UnifyPair> nextSetElement,
IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm,
Set<UnifyPair> methodSignatureConstraintUebergabe, ForkJoinPool pool, Writer statistics) {
this(setToFlatten, eq, oderConstraints, nextSetElement, fc, parallel, logFile, log, urm, methodSignatureConstraintUebergabe, pool );
}
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, Set<UnifyPair> methodSignatureConstraintUebergabe, ForkJoinPool pool) {
super(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
this.setToFlatten = setToFlatten;

View File

@@ -32,43 +32,34 @@ import java.util.stream.Collectors;
*/
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
/**
* Element, das aus dem nextSet den Gleichunen dieses Threads hinzugefuegt wurde
*/
Set<UnifyPair> nextSetElement;
/**
* Fuer die Threads
*/
protected UnifyResultModelParallel urm;
private static int totalnoOfThread = 0;
int thNo;
public static final String rootDirectory = System.getProperty("user.dir") + "/test/logFiles/";
static Writer statisticsFile = new NullWriter();
private static int totalNoOfThreads = 0;
/*
* Thread related
*/
protected UnifyResultModelParallel unifyResultModel;
protected WriterActiveObject logFile;
protected ForkJoinPool pool;
/**
* The implementation of the standard unify that will be used during the unification
*/
protected IUnify stdUnify = new MartelliMontanariUnify();
/**
* The implementation of the rules that will be used during the unification.
*/
protected IRuleSet rules;
protected Set<UnifyPair> eq; //und-constraints
protected List<Set<Constraint<UnifyPair>>> oderConstraintsField;
protected IFiniteClosure fc;
protected boolean parallel;
static Writer statisticsFile = new NullWriter();
//gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
Boolean log = true;
/**
* Element that was added to the equations of this thread from the nextSet
*/
Set<UnifyPair> nextSetElement;
int threadNumber;
public TypeUnifyTask() {
rules = new RuleSet();
@@ -77,7 +68,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//statistics
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool, Writer statisticsFile) {
this(eq, oderConstraints, fc, parallel, logFile, log, urm, pool);
this.statisticsFile = statisticsFile;
TypeUnifyTask.statisticsFile = statisticsFile;
}
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Constraint<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, WriterActiveObject logFile, Boolean log, UnifyResultModelParallel urm, ForkJoinPool pool) {
@@ -89,12 +80,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
this.log = log;
this.pool = pool;
totalnoOfThread++;
thNo = totalnoOfThread;
writeLog("thNo2 " + thNo);
totalNoOfThreads++;
threadNumber = totalNoOfThreads;
writeLog("thNo2 " + threadNumber);
try {
if (log) {
this.logFile = new WriterActiveObject(new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "Thread_" + thNo), pool);
this.logFile = new WriterActiveObject(new FileWriter(System.getProperty("user.dir") + "/logFiles/" + "Thread_" + threadNumber), pool);
} else {
this.logFile = new WriterActiveObject(new OutputStreamWriter(new NullOutputStream()), pool);
}
@@ -102,7 +93,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
System.err.println("log-File nicht vorhanden");
}
rules = new RuleSet(logFile);
this.urm = urm;
this.unifyResultModel = urm;
}
protected Set<Set<UnifyPair>> compute() {
@@ -300,7 +291,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
*/
urm.notify(eqPrimePrimeSet);
unifyResultModel.notify(eqPrimePrimeSet);
writeStatistics("Result: " + eqPrimePrimeSet);
}
} else if (eqPrimePrime.isPresent()) {
@@ -457,7 +448,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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, urm, methodSignatureConstraint, this.pool);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, methodSignatureConstraint, this.pool);
forkOrig.fork();
while (!nextSetasList.isEmpty()) {
@@ -471,14 +462,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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, urm, new HashSet<>(methodSignatureConstraint), this.pool);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forks.add(fork);
fork.fork();
}
res = forkOrig.join();
forks.forEach(x -> writeLog("wait: " + x.thNo));
forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join();
add_res.add(fork_res);
@@ -494,7 +485,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forkOrig.fork();
while (!nextSetasList.isEmpty()) {
@@ -507,21 +498,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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, urm, new HashSet<>(methodSignatureConstraint), this.pool);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forks.add(fork);
fork.fork();
}
writeLog("wait " + forkOrig.thNo);
writeLog("wait " + forkOrig.threadNumber);
res = forkOrig.join();
writeLog("JoinOrig " + Integer.valueOf(forkOrig.thNo).toString());
writeLog("JoinOrig " + Integer.valueOf(forkOrig.threadNumber).toString());
forks.forEach(x -> writeLog("wait: " + x.thNo));
forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join();
writeLog("Join " + Integer.valueOf(fork.thNo).toString());
writeLog("Join " + Integer.valueOf(fork.threadNumber).toString());
add_res.add(fork_res);
if (!isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement());
@@ -536,7 +527,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, urm, new HashSet<>(methodSignatureConstraint), this.pool);
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, unifyResultModel, new HashSet<>(methodSignatureConstraint), this.pool);
forkOrig.fork();
while (!nextSetasList.isEmpty()) {
@@ -545,21 +536,21 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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, urm, methodSignatureConstraint, this.pool);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, unifyResultModel, methodSignatureConstraint, this.pool);
forks.add(fork);
fork.fork();
}
writeLog("wait " + forkOrig.thNo);
writeLog("wait " + forkOrig.threadNumber);
res = forkOrig.join();
writeLog("JoinOrig " + Integer.valueOf(forkOrig.thNo).toString());
writeLog("JoinOrig " + Integer.valueOf(forkOrig.threadNumber).toString());
forks.forEach(x -> writeLog("wait: " + x.thNo));
forks.forEach(x -> writeLog("wait: " + x.threadNumber));
for (TypeUnify2Task fork : forks) {
Set<Set<UnifyPair>> fork_res = fork.join();
writeLog("Join " + Integer.valueOf(fork.thNo).toString());
writeLog("Join " + Integer.valueOf(fork.threadNumber).toString());
add_res.add(fork_res);
}
} else {//parallel = false oder MaxNoOfThreads ist erreicht, sequentiell weiterarbeiten
@@ -617,7 +608,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
res.stream()
.map(b ->
b.stream()
.map(x -> x.getThisAndAllBases()) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann.
.map(UnifyPair::getThisAndAllBases) //getAllBases durch getThisAndAllBases ersetzt, weil auch im UnifyPair selbst schon ein Fehler liegen kann.
.reduce((y, z) -> {
y.addAll(z);
return y;
@@ -627,22 +618,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return y;
}).get()
);
Set<UnifyPair> b = a;//effective final a
Set<UnifyPair> b = a;
Set<UnifyPair> durchschnitt = abhSubst.stream()
.filter(x -> b.contains(x))
.collect(Collectors.toCollection(HashSet::new));
int len = nextSetasList.size();
nofstred = nextSetasList.size();
writeLog("res (undef): " + res.toString() + "\n" +
"abhSubst: " + abhSubst.toString() + "\n" +
"Durchschnitt: " + durchschnitt.toString() + "\n" +
"nextSet: " + nextSet.toString() + "\n" +
"nextSetasList: " + nextSetasList.toString() + "\n" +
"Number first erased Elements (undef): " + (len - nofstred) + "\n" +
"Number second erased Elements (undef): " + (nofstred - nextSetasList.size()) + "\n" +
"Number erased Elements (undef): " + (len - nextSetasList.size()));
writeLog(
"res (undef): " + res + "\n" +
"abhSubst: " + abhSubst + "\n" +
"Durchschnitt: " + durchschnitt + "\n" +
"nextSet: " + nextSet + "\n" +
"nextSetasList: " + nextSetasList + "\n"
);
}
}
return result;
@@ -923,10 +910,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}
}
writeLog("eq2s: " + eq2s.toString() + "\n" +
"eq2sAsListFst: " + eq2sAsListFst.toString() + "\n" +
"eq2sAsListSnd: " + eq2sAsListSnd.toString() + "\n" +
"eq2sAsListBack: " + eq2sAsListBack.toString());
writeLog("eq2s: " + eq2s + "\n" +
"eq2sAsListFst: " + eq2sAsListFst + "\n" +
"eq2sAsListSnd: " + eq2sAsListSnd + "\n" +
"eq2sAsListBack: " + eq2sAsListBack);
eq2sAsList.addAll(eq2sAsListFst);
eq2sAsList.addAll(eq2sAsListSnd);
@@ -1213,7 +1200,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
aa.put(b, PlaceholderType.freshPlaceholder());
return aa;
}, combiner);
return x.accept(new freshPlaceholder(), hm);
return x.accept(new FreshPlaceholder(), hm);
}).collect(Collectors.toCollection(HashSet::new));
IMatch match = new Match();
@@ -1228,7 +1215,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if ((match.match(ml)).isEmpty()) {
thetaQs.remove(c);
}
writeLog("thetaQs von " + c + ": " + thetaQs.toString());
writeLog("thetaQs von " + c + ": " + thetaQs);
//Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new));
//thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht
//PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert,
@@ -1252,7 +1239,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for (TypeParams tp : permuteParams(candidateParams))
thetaQPrimes.add(c.setTypeParams(tp));
}
writeLog("thetaQPrimes von " + c + ": " + thetaQPrimes.toString());
writeLog("thetaQPrimes von " + c + ": " + thetaQPrimes);
for (UnifyType tqp : thetaQPrimes) {//PL 2020-03-08 umbauen in der Schleife wird nur unifizierbarer Typ gesucht break am Ende
Collection<PlaceholderType> tphs = tqp.getInvolvedPlaceholderTypes();
Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime);
@@ -1305,13 +1292,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
//TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt
for (UnifyType unifyType : up.getRhsType().getTypeParams())
unifyType.accept(new distributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance());
unifyType.accept(new DistributeVariance(), a.getVariance());//((PlaceholderType)upit.next()).setVariance(a.getVariance());
resultPrime.add(up);
} else {
UnifyPair up = new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
//TODO PL 2019-01-24: upit.next() ist nicht unbedingt ein PlaceholderType -> Visitor erledigt
for (UnifyType unifyType : up.getRhsType().getTypeParams())
unifyType.accept(new distributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance());
unifyType.accept(new DistributeVariance(), a.getVariance()); //((PlaceholderType)upit.next()).setVariance(a.getVariance());
resultPrime.add(up);
}
resultPrime.addAll(substitutionSet);
@@ -1323,7 +1310,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}
}
}
writeLog("result von " + pair + ": " + result.toString());
writeLog("result von " + pair + ": " + result);
return result;
}
@@ -1337,7 +1324,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
aPrime.setVariance(a.getVariance());
aPrime.disableWildcardtable();
aPrime.disableWildcardable();
UnifyType extAPrime = new ExtendsType(aPrime);
UnifyType thetaPrime = extThetaPrime.getExtendedType();
Set<UnifyPair> resultPrime = new HashSet<>();
@@ -1363,11 +1350,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType aPrime = PlaceholderType.freshPlaceholder();
aPrime.setVariance(a.getVariance());
aPrime.disableWildcardtable();
aPrime.disableWildcardable();
UnifyType supAPrime = new SuperType(aPrime);
UnifyType thetaPrime = subThetaPrime.getSuperedType();
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded()));
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getFBounded()));
result.add(resultPrime);
//writeLog(resultPrime.toString());
@@ -1399,7 +1386,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//fc.setLogTrue();
//writeLog("FBOUNDED: " + pair.getfBounded());
//writeLog("Pair: " + pair);
Set<UnifyType> greater = fc.greater(theta, pair.getfBounded());
Set<UnifyType> greater = fc.greater(theta, pair.getFBounded());
//writeLog("GREATER: " + greater + pair + "THETA: " + theta + "FBOUNDED: " + pair.getfBounded() + " ");
if (a.isWildcardable()) {
Set<UnifyType> greater_ext = greater.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType))
@@ -1424,7 +1411,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for (int i = 0; !allGen && i < freshTphs.length; i++) {
freshTphs[i] = PlaceholderType.freshPlaceholder();
((PlaceholderType) freshTphs[i]).setVariance(a.getVariance());
Set<UnifyType> fBounded = new HashSet<>(pair.getfBounded()); //PL 2019-01-09 new HashSet eingefuegt
Set<UnifyType> fBounded = new HashSet<>(pair.getFBounded()); //PL 2019-01-09 new HashSet eingefuegt
int i_ef = i;
BiFunction<Boolean, UnifyType, Boolean> f = (x, y) ->
@@ -1473,10 +1460,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
PlaceholderType freshTph = PlaceholderType.freshPlaceholder();
freshTph.setVariance(a.getVariance());
freshTph.disableWildcardtable();
freshTph.disableWildcardable();
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getfBounded()));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair, pair.getFBounded()));
result.add(resultPrime);
//writeLog("resultPrime: " + resultPrime.toString());
@@ -1528,12 +1515,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
void writeLog(String str) {
if (log) {
if (parallel) {
logFile.write("Thread no.:" + thNo + "\n"
logFile.write("Thread no.:" + threadNumber + "\n"
+ "parallel:" + parallel + "\n"
+ str + "\n\n"
);
} else {
logFile.writeNonThreaded("Thread no.:" + thNo + "\n"
logFile.writeNonThreaded("Thread no.:" + threadNumber + "\n"
+ "parallel:" + parallel + "\n"
+ str + "\n\n"
);
@@ -1543,7 +1530,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
void writeStatistics(String str) {
try {
statisticsFile.write("Thread No. " + thNo + ": " + str + "\n");
statisticsFile.write("Thread No. " + threadNumber + ": " + str + "\n");
statisticsFile.flush();
} catch (IOException e) {

View File

@@ -1,18 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.List;
public class UnifyResultEvent {
private List<ResultSet> newTypeResult;
public UnifyResultEvent(List<ResultSet> newTypeResult) {
this.newTypeResult = newTypeResult;
}
public List<ResultSet> getNewTypeResult() {
return newTypeResult;
}
}

View File

@@ -1,7 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
public interface UnifyResultListener {
void onNewTypeResultFound(UnifyResultEvent evt);
}

View File

@@ -1,21 +0,0 @@
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;
}
}

View File

@@ -1,55 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
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;
import java.util.*;
import java.util.stream.Collectors;
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);
}
}
}

View File

@@ -1,22 +1,25 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.typeinference.TypeInferenceHelper;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
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;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
public class UnifyResultModelParallel {
private final ConstraintSet<Pair> cons;
private final IFiniteClosure fc;
private final List<ResultSet> results = new ArrayList<>();
private ForkJoinPool pool;
private ConstraintSet<Pair> cons;
private IFiniteClosure fc;
private List<UnifyResultListener> listeners = new ArrayList<>();
public UnifyResultModelParallel(ConstraintSet<Pair> cons, IFiniteClosure fc) {
this.cons = cons;
@@ -26,32 +29,26 @@ public class UnifyResultModelParallel {
public void setPool(ForkJoinPool pool) {
this.pool = pool;
}
public void addUnifyResultListener(UnifyResultListener listenerToAdd) {
listeners.add(listenerToAdd);
public synchronized void onNewTypeResultFound(List<ResultSet> result) {
results.addAll(result);
}
public void removeUnifyResultListener(UnifyResultListener listenerToRemove) {
listeners.remove(listenerToRemove);
public List<ResultSet> getResults() {
return results;
}
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
pool.execute(() -> {
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));
Set<Set<UnifyPair>> eqPrimePrimeSetRet =
TypeInferenceHelper.resolveSubstitutions(new HashSet<>(eqPrimePrimeSet), fc);
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);
}
// TODO: this is a synchronized call, can we find a way around this?
this.onNewTypeResultFound(newResult);
});
}
}

View File

@@ -0,0 +1,40 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
public class VisitUnifyTypeVisitor<T> implements UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht) {
return new ReferenceType(refty.getName(),
new TypeParams(
Arrays.stream(refty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new))));
}
public PlaceholderType visit(PlaceholderType phty, T ht) {
return phty;
}
public FunNType visit(FunNType funnty, T ht) {
return FunNType.getFunNType(
new TypeParams(
Arrays.stream(funnty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new)))
);
}
public SuperType visit(SuperType suty, T ht) {
return new SuperType(suty.getWildcardedType().accept(this, ht));
}
public ExtendsType visit(ExtendsType extty, T ht) {
return new ExtendsType(extty.getWildcardedType().accept(this, ht));
}
}

View File

@@ -5,30 +5,23 @@ import java.io.Writer;
import java.util.concurrent.ForkJoinPool;
public class WriterActiveObject {
private Writer writer;
private ForkJoinPool pool;
private final Writer writer;
private final ForkJoinPool pool;
public WriterActiveObject(Writer writer, ForkJoinPool pool) {
this.writer = writer;
this.pool = pool;
}
public void close(){
pool.execute(()->{
try {
writer.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
});
}
public void write(String message) {
pool.execute(() -> {
try {
writer.write(message);
// TODO: do something against this flush(). Writing to disk is slooooooow
writer.flush();
} catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e);
}
});
@@ -37,16 +30,29 @@ public class WriterActiveObject {
public void writeNonThreaded(String message) {
try {
writer.write(message);
// TODO: do something against this flush(). Writing to disk is slooooooow
writer.flush();
} catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e);
}
}
public void close() {
pool.execute(() -> {
try {
writer.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
});
}
public void closeNonThreaded() {
try {
writer.close();
} catch (IOException e) {
// TODO: why is here a random error conversion down to a runtimeException?
throw new RuntimeException(e);
}
}

View File

@@ -1,54 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class distributeVariance extends visitUnifyTypeVisitor<Integer> {
public static int inverseVariance(int variance) {
Integer ret = 0;
if (variance == 1) {
ret = -1;
}
if (variance == -1) {
ret = 1;
}
return ret;
}
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
//PL 2018-05-17 urspruengliche Variance nicht veraendern
//else if (phty.getVariance() != ht) {
// phty.setVariance(0);
//}
}
return phty;
}
public FunNType visit(FunNType funnty, Integer ht) {
List<UnifyType> param = new ArrayList<>(funnty.getTypeParams().get().length);
param.addAll(Arrays.asList(funnty.getTypeParams().get()));
UnifyType resultType = param.remove(param.size()-1);
Integer htInverse = inverseVariance(ht);
param = param.stream()
.map(x -> x.accept(this, htInverse))
.collect(Collectors.toCollection(ArrayList::new));
param.add(resultType.accept(this, ht));
return FunNType.getFunNType(new TypeParams(param));
}
}

View File

@@ -1,15 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import java.util.HashMap;
public class freshPlaceholder extends visitUnifyTypeVisitor<HashMap<PlaceholderType,PlaceholderType>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType,PlaceholderType> ht) {
return ht.get(phty);
}
}

View File

@@ -6,58 +6,71 @@ import java.util.Optional;
import java.util.Set;
/**
*
* @author Florian Steurer
*/
public interface IFiniteClosure {
public void setLogTrue();
void setLogTrue();
/**
* Returns all types of the finite closure that are subtypes of the argument.
*
* @return The set of subtypes of the argument.
*/
public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
/**
* Returns all types of the finite closure that are supertypes of the argument.
*
* @return The set of supertypes of the argument.
*/
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
/**
* Wo passt Type rein?
*
* @param type
* @return
*/
public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
/**
* Was passt in Type rein?
*
* @param type
* @return
*/
public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyPair> getPairs();
public Optional<UnifyType> getLeftHandedType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName);
Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop);
Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
Set<UnifyPair> getPairs();
Optional<UnifyType> getLeftHandedType(String typeName);
Set<UnifyType> getAncestors(UnifyType t);
Set<UnifyType> getChildren(UnifyType t);
Set<UnifyType> getAllTypesByName(String typeName);
int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairOp);
}

View File

@@ -8,6 +8,7 @@ import java.util.Optional;
/**
* Match
*
* @author Martin Pluemicke
* abgeleitet aus IUnify.java
*/
@@ -16,10 +17,11 @@ public interface IMatch {
/**
* Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = t1' , ... sigma(tn) = tn'.
* @param terms The set of terms to be matched
*
* @param termsList The set of terms to be matched
* @return An optional of the most general matcher if it exists or an empty optional if there is no matcher.
*/
public Optional<Unifier> match(ArrayList<UnifyPair> termsList);
Optional<Unifier> match(ArrayList<UnifyPair> termsList);
}

View File

@@ -9,32 +9,43 @@ import java.util.Set;
/**
* Contains the inference rules that are applied to the set Eq.
*
* @author Florian Steurer
*/
public interface IRuleSet {
public Optional<UnifyPair> reduceUp(UnifyPair pair);
public Optional<UnifyPair> reduceLow(UnifyPair pair);
public Optional<UnifyPair> reduceUpLow(UnifyPair pair);
public Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
public Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc);
public Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
Optional<UnifyPair> reduceUp(UnifyPair pair);
Optional<UnifyPair> reduceLow(UnifyPair pair);
Optional<UnifyPair> reduceUpLow(UnifyPair pair);
Optional<Set<UnifyPair>> reduceExt(UnifyPair pair, IFiniteClosure fc);
Optional<Set<UnifyPair>> reduceSup(UnifyPair pair, IFiniteClosure fc);
Optional<Set<UnifyPair>> reduceEq(UnifyPair pair);
Optional<Set<UnifyPair>> reduce1(UnifyPair pair, IFiniteClosure fc);
Optional<Set<UnifyPair>> reduce2(UnifyPair pair);
/*
* Missing Reduce-Rules for Wildcards
*/
public Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
Optional<UnifyPair> reduceWildcardLow(UnifyPair pair);
Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
/*
* vgl. JAVA_BSP/Wildcard6.java
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
*/
/*
@@ -44,60 +55,69 @@ public interface IRuleSet {
/**
* Rule that replaces the fourth case of the cartesian product where (a <.? Theta)
*/
public Optional<UnifyPair> reduceTph(UnifyPair pair);
Optional<UnifyPair> reduceTph(UnifyPair pair);
/**
* Rule that replaces the sixth case of the cartesian product where (? ext Theta <.? a)
*/
public Optional<Set<UnifyPair>> reduceTphExt(UnifyPair pair);
Optional<Set<UnifyPair>> reduceTphExt(UnifyPair pair);
/**
* Rule that replaces the fourth case of the cartesian product where (? sup Theta <.? a)
*/
public Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair);
Optional<Set<UnifyPair>> reduceTphSup(UnifyPair pair);
/*
* FunN Rules
*/
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair);
Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
/**
* Checks whether the erase1-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise.
*/
public boolean erase1(UnifyPair pair, IFiniteClosure fc);
boolean erase1(UnifyPair pair, IFiniteClosure fc);
/**
* Checks whether the erase2-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise.
*/
public boolean erase2(UnifyPair pair, IFiniteClosure fc);
boolean erase2(UnifyPair pair, IFiniteClosure fc);
/**
* Checks whether the erase3-Rule applies to the pair.
*
* @return True if the pair is erasable, false otherwise.
*/
public boolean erase3(UnifyPair pair);
boolean erase3(UnifyPair pair);
public Optional<UnifyPair> swap(UnifyPair pair);
Optional<UnifyPair> swap(UnifyPair pair);
public Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
Optional<UnifyPair> adapt(UnifyPair pair, IFiniteClosure fc);
Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
/**
* Applies the subst-Rule to a set of pairs (usually Eq').
*
* @param pairs The set of pairs where the subst rule should apply.
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
*/
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints);
Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints);
/**
* Applies the subst-Rule to a set of pairs (usually Eq').
*
* @param pairs The set of pairs where the subst rule should apply.
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
*/
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs);
}

View File

@@ -5,11 +5,13 @@ import java.util.Set;
/**
* Contains operations on sets.
*
* @author Florian Steurer
*/
public interface ISetOperations {
/**
* Calculates the cartesian product of the sets.
*
* @return The cartesian product
*/
<B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets);

View File

@@ -10,6 +10,7 @@ import java.util.stream.Collectors;
/**
* Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari)
*
* @author Florian Steurer
*/
public interface IUnify {
@@ -17,18 +18,20 @@ public interface IUnify {
/**
* 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 Optional<Unifier> unify(Set<UnifyType> terms);
Optional<Unifier> unify(Set<UnifyType> terms);
/**
* 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.
*/
default public Optional<Unifier> unify(UnifyType... terms) {
default Optional<Unifier> unify(UnifyType... terms) {
return unify(Arrays.stream(terms).collect(Collectors.toSet()));
}

View File

@@ -4,14 +4,14 @@ import de.dhbwstuttgart.typeinference.unify.model.*;
public interface UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht);
ReferenceType visit(ReferenceType refty, T ht);
public PlaceholderType visit(PlaceholderType phty, T ht);
PlaceholderType visit(PlaceholderType phty, T ht);
public FunNType visit(FunNType funnty, T ht);
FunNType visit(FunNType funnty, T ht);
public SuperType visit(SuperType suty, T ht);
SuperType visit(SuperType suty, T ht);
public ExtendsType visit(ExtendsType extty, T ht);
ExtendsType visit(ExtendsType extty, T ht);
}

View File

@@ -10,12 +10,9 @@ import java.util.Set;
*/
public final class ExtendsType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a new extends wildcard type.
*
* @param extendedType The extended type e.g. Integer in "? extends Integer"
*/
public ExtendsType(UnifyType extendedType) {
@@ -25,6 +22,10 @@ public final class ExtendsType extends WildcardType {
}
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* The extended type e.g. Integer in "? extends Integer"
*/
@@ -54,8 +55,8 @@ public final class ExtendsType extends WildcardType {
}
@Override
UnifyType apply(Unifier unif) {
UnifyType newType = wildcardedType.apply(unif);
UnifyType apply(Unifier unifier) {
UnifyType newType = wildcardedType.apply(unifier);
if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
return this; // Reduced the amount of objects created
return new ExtendsType(newType);
@@ -72,15 +73,12 @@ public final class ExtendsType extends WildcardType {
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ExtendsType))
if (!(obj instanceof ExtendsType other))
return false;
if (obj.hashCode() != this.hashCode())
return false;
ExtendsType other = (ExtendsType) obj;
return other.getWildcardedType().equals(wildcardedType);
}

View File

@@ -14,39 +14,31 @@ import java.util.stream.Collectors;
/**
* The finite closure for the type unification
*
* @author Florian Steurer
*/
public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11
implements IFiniteClosure {
public class FiniteClosure implements IFiniteClosure {
Writer logFile;
static Boolean log = false;
public void setLogTrue() {
log = true;
}
/**
* A map that maps every type to the node in the inheritance graph that contains that type.
*/
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
private final HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
/**
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
*/
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
private final HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/**
* The initial pairs of that define the inheritance tree
*/
private Set<UnifyPair> pairs;
private final Set<UnifyPair> pairs;
Writer logFile;
/**
* Hastable fuer die greater-Werte, damit sie nicht doppelt berechnet werden muessen
* Hashtable for greater-values to prevent them from being calculated twice
*/
Hashtable<hashKeyType, Set<UnifyType>> greaterHash = new Hashtable<>();
/**
* Hastable fuer die smaller-Werte, damit sie nicht doppelt berechnet werden muessen
* Hashtable for smaller-values to prevent them from being calculated twice
*/
Hashtable<hashKeyType, Set<UnifyType>> smallerHash = new Hashtable<>();
@@ -56,23 +48,12 @@ implements IFiniteClosure {
public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) {
this.logFile = logFile;
this.pairs = new HashSet<>(pairs);
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
inheritanceGraph = new HashMap<>();
// Build the transitive closure of the inheritance tree
for (UnifyPair pair : pairs) {
/*
try {
logFile.write("Pair: " + pair + "\n");
logFile.flush();
}
catch (IOException e) {
System.err.println("no LogFile");
}
*/
if(pair.getPairOp() != PairOperator.SMALLER)
continue;
if (pair.getPairOp() != PairOperator.SMALLER) continue;
//VERSUCH PL 18-02-06
//koennte ggf. die FC reduzieren
@@ -80,12 +61,12 @@ implements IFiniteClosure {
//if (!pair.getLhsType().getTypeParams().arePlaceholders()
// && !pair.getRhsType().getTypeParams().arePlaceholders())
// continue;
;
// Add nodes if not already in the graph
if (!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType()));
inheritanceGraph.put(pair.getLhsType(), new Node<>(pair.getLhsType()));
if (!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType()));
inheritanceGraph.put(pair.getRhsType(), new Node<>(pair.getRhsType()));
Node<UnifyType> childNode = inheritanceGraph.get(pair.getLhsType());
Node<UnifyType> parentNode = inheritanceGraph.get(pair.getRhsType());
@@ -94,38 +75,40 @@ implements IFiniteClosure {
parentNode.addDescendant(childNode);
// Add edges to build the transitive closure
parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode));
childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode));
parentNode.getPredecessors().forEach(x -> x.addDescendant(childNode));
childNode.getDescendants().forEach(x -> x.addPredecessor(parentNode));
//PL eingefuegt 2020-05-07 File UnitTest InheritTest.java
this.inheritanceGraph.forEach((x,y) -> { if (y.getDescendants().contains(parentNode)) { y.addDescendant(childNode); y.addAllDescendant(childNode.getDescendants());};
if (y.getPredecessors().contains(childNode)) { y.addPredecessor(parentNode); y.addAllPredecessor(parentNode.getPredecessors());};} );
this.inheritanceGraph.forEach((x, y) -> {
if (y.getDescendants().contains(parentNode)) {
y.addDescendant(childNode);
y.addAllDescendant(childNode.getDescendants());
}
if (y.getPredecessors().contains(childNode)) {
y.addPredecessor(parentNode);
y.addAllPredecessor(parentNode.getPredecessors());
}
});
}
// Build the alternative representation with strings as keys
strInheritanceGraph = new HashMap<>();
for (UnifyType key : inheritanceGraph.keySet()) {
if(!strInheritanceGraph.containsKey(key.getName()))
if (!strInheritanceGraph.containsKey(key.getName())) {
strInheritanceGraph.put(key.getName(), new HashSet<>());
}
strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key));
}
}
void testSmaller() {
UnifyType tq1, tq2, tq3;
tq1 = new ExtendsType(PlaceholderType.freshPlaceholder());
List<UnifyType> l1 = new ArrayList<>();
List<UnifyType> l2 = new ArrayList<>();
l1.add(tq1);
tq2 = new ReferenceType("java.util.Vector", new TypeParams(l1));
l2.add(tq2);
tq3 = new ReferenceType("java.util.Vector", new TypeParams(l2));
Set<UnifyType> smaller = smaller(tq3, new HashSet<>());
public void setLogTrue() {
log = true;
}
/**
* Returns all types of the finite closure that are subtypes of the argument.
*
* @return The set of subtypes of the argument.
*/
@Override
@@ -133,12 +116,10 @@ implements IFiniteClosure {
Set<UnifyType> ret;
if ((ret = smallerHash.get(new hashKeyType(type))) != null) {
//System.out.println(greaterHash);
return new HashSet<>(ret);
}
if(type instanceof FunNType)
return computeSmallerFunN((FunNType) type, fBounded);
if (type instanceof FunNType) return computeSmallerFunN((FunNType) type, fBounded);
Set<Pair<UnifyType, Set<UnifyType>>> ts = new HashSet<>();
ts.add(new Pair<>(type, fBounded));
@@ -170,12 +151,7 @@ implements IFiniteClosure {
Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <* T'
try {
result.add(new Pair<>(t, fBounded));
}
catch (StackOverflowError e) {
System.out.println("");
}
// if C<...> <* C<...> then ... (third case in definition of <*)
if (t.getTypeParams().size() > 0) {
@@ -185,13 +161,15 @@ implements IFiniteClosure {
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), fBounded)));
}
if(!strInheritanceGraph.containsKey(t.getName()))
continue;
if (!strInheritanceGraph.containsKey(t.getName())) continue;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName()); //cadidates= [???Node(java.util.Vector<java.util.Vector<java.lang.Integer>>)???
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
// candidates = [
// ???Node(java.util.Vector<java.util.Vector<java.lang.Integer>>)???
// , Node(java.util.Vector<gen_hv>)
// ]
for (Node<UnifyType> candidate : candidates) {
UnifyType theta2 = candidate.getContent();
//PL 18-02-05 Unifier durch Matcher ersetzt ANFANG
@@ -199,8 +177,7 @@ implements IFiniteClosure {
termList.add(new UnifyPair(theta2, t, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-02-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent())
continue;
if (optSigma.isEmpty()) continue;
Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutions(t.getTypeParams());
@@ -212,9 +189,11 @@ implements IFiniteClosure {
}
}
HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut;
HashSet<UnifyType> resultKeys = result.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new));
if (resultKeys.equals(types.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new)))) {
return resultKeys;
}
return computeSmaller(result);
}
@@ -231,8 +210,9 @@ implements IFiniteClosure {
// it is enough to permute the params with the values of greater / smaller.
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
paramCandidates.add(smaller(type.getTypeParams().get(0), fBounded));
for (int i = 1; i < type.getTypeParams().size(); i++)
for (int i = 1; i < type.getTypeParams().size(); i++) {
paramCandidates.add(greater(type.getTypeParams().get(i), new HashSet<>()));
}
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
return result;
@@ -240,6 +220,7 @@ implements IFiniteClosure {
/**
* Returns all types of the finite closure that are supertypes of the argument.
*
* @return The set of supertypes of the argument.
*/
@Override
@@ -248,11 +229,9 @@ implements IFiniteClosure {
Set<UnifyType> ret;
if ((ret = greaterHash.get(new hashKeyType(type))) != null) {
//System.out.println(greaterHash);
return new HashSet<>(ret);
}
if (type instanceof FunNType) {
return computeGreaterFunN((FunNType) type, fBounded);
}
@@ -262,11 +241,9 @@ implements IFiniteClosure {
Match match = new Match();
// if T = T' then T <=* T'
result.add(type);
if(!strInheritanceGraph.containsKey(type.getName()))
return result;
if (!strInheritanceGraph.containsKey(type.getName())) return result;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(type.getName());
@@ -289,7 +266,7 @@ implements IFiniteClosure {
termList.add(new UnifyPair(theta1, type, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent()) {
if (optSigma.isEmpty()) {
continue;
}
Unifier sigma = optSigma.get();
@@ -325,8 +302,7 @@ implements IFiniteClosure {
for (int i = 0; i < t.getTypeParams().size(); i++) {
//UnifyType parai = t.getTypeParams().get(i);
int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{
BiFunction<Boolean, UnifyType, Boolean> f = (x, y) -> {
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y, t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x);
@@ -339,8 +315,7 @@ implements IFiniteClosure {
//F-Bounded Endlosrekursion
HashSet<UnifyType> res = new HashSet<UnifyType>();
paramCandidates.add(res);
}
else {
} else {
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded)));
}
}
@@ -361,96 +336,6 @@ implements IFiniteClosure {
return result;
}
/* auskommentiert PL 2018-05-24
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*
//@Override
public Set<UnifyType> oldgreater(UnifyType type, Set<UnifyType> fBounded) {
if(type instanceof FunNType)
return computeGreaterFunN((FunNType) type, fBounded);
Set<Pair<UnifyType,Set<UnifyType>>> ts = new HashSet<>();
ts.add(new Pair<>(type, fBounded));
return computeGreater(ts);
}
/**
* Computes the greater function for all types except function types.
*
protected Set<UnifyType> computeGreater(Set<Pair<UnifyType,Set<UnifyType>>> types) {
Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>();
//PL 18-04-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify();
Match match = new Match();
for(Pair<UnifyType,Set<UnifyType>> pt : types) {
UnifyType t = pt.getKey();
Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <=* T'
result.add(pt);
// if C<...> <* C<...> then ... (third case in definition of <*)
if(t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) {
UnifyType parai = t.getTypeParams().get(i);
int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x);
};
if (parai.getName().equals("java.lang.Integer")) {
System.out.println("");
}
BinaryOperator<Boolean> bo = (a,b) -> (a || b);
if (fBounded.stream().reduce(false,f,bo)) continue; //F-Bounded Endlosrekursion
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
}
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), new HashSet<>(fBounded))));
}
if(!strInheritanceGraph.containsKey(t.getName()))
continue;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent();
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,t, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent())
continue;
Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams());
Set<UnifyType> fBoundedNew = new HashSet<>(fBounded);
fBoundedNew.add(theta1);
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
for(UnifyType theta2 : theta2Set)
result.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
}
}
HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
System.out.println(resut);
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut;
return computeGreater(result);
}
*/
/**
* Computes the greater function for FunN-Types
*/
@@ -558,7 +443,7 @@ implements IFiniteClosure {
result.add(type);
UnifyType t = type.getSuperedType();
result.add(t);
//*** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen
// TODO: *** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen
greater(t, fBounded).forEach(x -> {
result.add(new SuperType(x));
result.add(x);
@@ -575,15 +460,13 @@ implements IFiniteClosure {
@Override
public Set<UnifyType> getAllTypesByName(String typeName) {
if(!strInheritanceGraph.containsKey(typeName))
return new HashSet<>();
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
if (!strInheritanceGraph.containsKey(typeName)) return new HashSet<>();
return strInheritanceGraph.get(typeName).stream().map(Node::getContent).collect(Collectors.toCollection(HashSet::new));
}
@Override
public Optional<UnifyType> getLeftHandedType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName))
return Optional.empty();
if (!strInheritanceGraph.containsKey(typeName)) return Optional.empty();
for (UnifyPair pair : pairs)
if (pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
@@ -594,8 +477,7 @@ implements IFiniteClosure {
@Override
public Set<UnifyType> getAncestors(UnifyType t) {
if(!inheritanceGraph.containsKey(t))
return new HashSet<>();
if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfPredecessors();
result.add(t);
return result;
@@ -603,8 +485,7 @@ implements IFiniteClosure {
@Override
public Set<UnifyType> getChildren(UnifyType t) {
if(!inheritanceGraph.containsKey(t))
return new HashSet<>();
if (!inheritanceGraph.containsKey(t)) return new HashSet<>();
Set<UnifyType> result = inheritanceGraph.get(t).getContentOfDescendants();
result.add(t);
return result;
@@ -612,6 +493,7 @@ implements IFiniteClosure {
/**
* 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.
*/
@@ -623,6 +505,7 @@ implements IFiniteClosure {
/**
* 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.
@@ -648,66 +531,26 @@ implements IFiniteClosure {
return this.inheritanceGraph.toString();
}
/* entfernt PL 2018-12-11
public int compare (UnifyType left, UnifyType right) {
return compare(left, right, PairOperator.SMALLERDOT);
}
*/
public int compare(UnifyType left, UnifyType right, PairOperator pairOp) {
public int compare (UnifyType left, UnifyType right, PairOperator pairop) {
//try {logFile.write("left: "+ left + " right: " + right + " pairop: " + pairop);} catch (IOException ie) {}
if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
System.out.println("");
/*
pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
al.add(xx);
left = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
right = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
*/
/*
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
al.add(xx);
left = new ExtendsType(xx);
right = xx;
*/
/*
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx");
PlaceholderType yy =new PlaceholderType("yy");
al.add(xx);
left = yy;
right = new ExtendsType(xx);
*/
//Die Faelle abfangen, bei den Variablen verglichen werden PL 2018-12-11
UnifyType ex;
if (left instanceof PlaceholderType) {
if ((right instanceof WildcardType)
&& ((ex = ((WildcardType)right).wildcardedType) instanceof PlaceholderType)
&& ((PlaceholderType)left).getName().equals(((PlaceholderType)ex).getName())) {// a <.? ? extends a oder a <.? ? super a
if ((right instanceof WildcardType) && ((ex = ((WildcardType) right).wildcardedType) instanceof PlaceholderType) && left.getName().equals(ex.getName())) {// a <.? ? extends a oder a <.? ? super a
return -1;
}
else {
} else {
return 0;
}
}
if (right instanceof PlaceholderType) {//&& (left instanceof WildcardType)) {PL geloescht 2019-01-15 analog zu oben
if ((left instanceof WildcardType) //PL eingefuegt 2019-01-15 analog zu oben
&& ((ex = ((WildcardType)left).wildcardedType) instanceof PlaceholderType)
&& ((PlaceholderType)right).getName().equals(((PlaceholderType)ex).getName())) {// ? extends a <. a oder ? super a <. a
&& ((ex = ((WildcardType) left).wildcardedType) instanceof PlaceholderType) && right.getName().equals(ex.getName())) {// ? extends a <. a oder ? super a <. a
return 1;
}
else {
} else {
return 0;
}
}
UnifyPair up = new UnifyPair(left, right, pairop);
UnifyPair up = new UnifyPair(left, right, pairOp);
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
@@ -722,15 +565,12 @@ implements IFiniteClosure {
System.err.println("no LogFile");}}
*/
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType ||
x.getRhsType() instanceof PlaceholderType)
&& !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
((WildcardType)x.getLhsType()).getWildcardedType().equals(x.getRhsType()))
);
Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType) && !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
((WildcardType) x.getLhsType()).getWildcardedType().equals(x.getRhsType())));
long smallerLen = smallerRes.stream().filter(delFun).count();
if (smallerLen == 0) return -1;
else {
up = new UnifyPair(right, left, pairop);
up = new UnifyPair(right, left, pairOp);
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
@@ -744,6 +584,7 @@ implements IFiniteClosure {
catch (IOException e) {
System.err.println("no LogFile");}}
*/
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long greaterLen = greaterRes.stream().filter(delFun).count();
if (greaterLen == 0) return 1;

View File

@@ -5,18 +5,16 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* A real function type in java.
*
* @author Florian Steurer
*/
public class FunNType extends UnifyType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a FunN-Type with the specified TypeParameters.
*/
@@ -26,6 +24,7 @@ public class FunNType extends UnifyType {
/**
* Creates a new FunNType.
*
* @param tp The parameters of the type.
* @return A FunNType.
* @throws IllegalArgumentException is thrown when there are to few type parameters or there are wildcard-types.
@@ -39,6 +38,10 @@ public class FunNType extends UnifyType {
return new FunNType(tp);
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Returns the degree of the function type, e.g. 2 for FunN<Integer, Integer, Integer>.
*/
@@ -64,10 +67,10 @@ public class FunNType extends UnifyType {
}
@Override
UnifyType apply(Unifier unif) {
UnifyType apply(Unifier unifier) {
// TODO this bypasses the validation of the type parameters.
// Wildcard types can be unified into FunNTypes.
TypeParams newParams = typeParams.apply(unif);
TypeParams newParams = typeParams.apply(unifier);
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this;
@@ -76,8 +79,8 @@ public class FunNType extends UnifyType {
@Override
public Boolean wrongWildcard() {
return (new ArrayList<UnifyType>(Arrays.asList(getTypeParams()
.get())).stream().filter(x -> (x instanceof WildcardType)).findFirst().isPresent());
List<UnifyType> typeParamList = new ArrayList<>(Arrays.asList(getTypeParams().get()));
return typeParamList.stream().anyMatch(x -> (x instanceof WildcardType));
}
@Override
@@ -88,14 +91,12 @@ public class FunNType extends UnifyType {
@Override
public boolean equals(Object obj) {
if(!(obj instanceof FunNType))
if (!(obj instanceof FunNType other))
return false;
if (obj.hashCode() != this.hashCode())
return false;
FunNType other = (FunNType) obj;
return other.getTypeParams().equals(typeParams);
}

View File

@@ -6,26 +6,26 @@ import java.util.stream.Collectors;
/**
* A node of a directed graph.
* @author Florian Steurer
*
* @param <T> The type of the content of the node.
* @author Florian Steurer
*/
class Node<T> {
/**
* The content of the node.
*/
private T content;
private final T content;
/**
* The set of predecessors
*/
private HashSet<Node<T>> predecessors = new HashSet<>();
private final HashSet<Node<T>> predecessors = new HashSet<>();
/**
* The set of descendants
*/
private HashSet<Node<T>> descendants = new HashSet<>();
private final HashSet<Node<T>> descendants = new HashSet<>();
/**
* Creates a node containing the specified content.
@@ -75,44 +75,45 @@ class Node<T> {
}
/**
* The content of this node.
* @return The content of this node.
*/
public T getContent() {
return content;
}
/**
* Returns all predecessors (nodes that have a directed edge to this node)
* @return All predecessors (nodes that have a directed edge to this node)
*/
public Set<Node<T>> getPredecessors() {
return predecessors;
}
/**
* Returns all descendants. All nodes M, where there is a edge from this node to the node M.
* @return
* @return All nodes M, where there is an edge from this node to the node M.
*/
public Set<Node<T>> getDescendants() {
return descendants;
}
/**
* Retrieves the content of all descendants.
* @return The content of all descendants.
*/
public Set<T> getContentOfDescendants() {
return descendants.stream().map(x -> x.getContent()).collect(Collectors.toSet());
return descendants.stream().map(Node::getContent).collect(Collectors.toSet());
}
/**
* Retrieves the content of all predecessors.
* @return The content of all predecessors.
*/
public Set<T> getContentOfPredecessors() {
return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet());
return predecessors.stream().map(Node::getContent).collect(Collectors.toSet());
}
@Override
public String toString() {
return "Elem: Node(" + content.toString() + ")\nPrec: " + getContentOfPredecessors().toString()
+ "\nDesc: " + getContentOfDescendants().toString() + "\n\n";
return
"Elem: Node(" + content.toString() + ")\n" +
"Prec: " + getContentOfPredecessors().toString() + "\n" +
"Desc: " + getContentOfDescendants().toString() + "\n\n";
}
}

View File

@@ -1,85 +0,0 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.*;
public abstract class OrderingExtend<T> extends com.google.common.collect.Ordering<T> {
public List<T> maxElements(Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
while (iterable.iterator().hasNext()) {
Set<T> believe = new HashSet<>();
T max = max(iterable);
ret.add(max);
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T elem = it.next();
if (!(compare(max, elem) == 1) && !max.equals(elem)) {
believe.add(elem);
}
}
iterable = believe;
}
return ret;
}
public List<T> minElements(Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
while (iterable.iterator().hasNext()) {
Set<T> believe = new HashSet<>();
T min = min(iterable);
ret.add(min);
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T elem = it.next();
if (!(compare(min, elem) == -1) && !min.equals(elem)) {
believe.add(elem);
}
}
iterable = believe;
}
return ret;
}
public List<T> smallerEqThan(T elem, Iterable<T> iterable) {
List<T> ret = smallerThan(elem, iterable);
ret.add(elem);
return ret;
}
public List<T> smallerThan(T elem, Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T itElem = it.next();
if (!itElem.equals(elem) && compare(elem, itElem) == 1) {
ret.add(itElem);
}
}
return ret;
}
public List<T> greaterEqThan(T elem, Iterable<T> iterable) {
List<T> ret = greaterThan(elem, iterable);
ret.add(elem);
return ret;
}
public List<T> greaterThan(T elem, Iterable<T> iterable) {
ArrayList<T> ret = new ArrayList<>();
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T itElem = it.next();
if (!itElem.equals(elem) && (compare(elem, itElem) == -1)) {
ret.add(itElem);
}
}
return ret;
}
}

View File

@@ -1,446 +0,0 @@
package de.dhbwstuttgart.typeinference.unify.model;
import de.dhbwstuttgart.typeinference.unify.Match;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.util.Pair;
import java.io.IOException;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
protected IFiniteClosure fc;
public OrderingUnifyPair(IFiniteClosure fc) {
this.fc = fc;
}
/*
* vergleicht Paare (a =. Theta) und (a =. Theta')
* in dem compare(Theta, Theta') aufgerufen wird.
*/
public int compareEq (UnifyPair left, UnifyPair right) {
try {
//if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {//PL 2019-01-12 ausgetauscht
if (((PlaceholderType)left.getLhsType()).isInnerType() && ((PlaceholderType)right.getLhsType()).isInnerType()) {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC);
}
else {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT);
}}
catch (ClassCastException e) {
try {
((FiniteClosure)fc).logFile.write("ClassCastException: " + left.toString() + " " + left.getGroundBasePair() + "\n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
return -99;
}
}
/*
public int compareEq (UnifyPair left, UnifyPair right) {
if (left == null || right == null)
System.out.println("Fehler");
if (left.getLhsType() instanceof PlaceholderType) {
return fc.compare(left.getRhsType(), right.getRhsType(), left.getPairOp());
}
else {
return fc.compare(left.getLhsType(), right.getLhsType(), left.getPairOp());
}
}
*/
public Pair<Integer,Set<UnifyPair>> compare (UnifyType left, UnifyType right) {
UnifyPair up;
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(left, right, PairOperator.SMALLERDOTWC);
if (((left instanceof ExtendsType)
&& (((ExtendsType)left).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)left).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)) ||
((right instanceof ExtendsType)
&& (((ExtendsType)right).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)right).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)))
{
System.out.println("");
}
if (((right instanceof SuperType) && (((SuperType)right).getSuperedType().getName().equals("java.lang.Object")))
||((left instanceof SuperType) && (((SuperType)left).getSuperedType().getName().equals("java.lang.Object"))))
{
System.out.println("");
}
}
else {
up = new UnifyPair(left, right, PairOperator.SMALLERDOT);
}
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, fc);
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (smallerLen == 0) return new Pair<>(-1, smallerRes);
else {
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(right, left, PairOperator.SMALLERDOTWC);
if (((left instanceof ExtendsType)
&& (((ExtendsType)left).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)left).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)) ||
((right instanceof ExtendsType)
&& (((ExtendsType)right).getExtendedType().getName().equals("java.util.Vector"))
&& (((ReferenceType)((ExtendsType)right).getExtendedType()).getTypeParams().iterator().next() instanceof ExtendsType)))
{
System.out.println("");
}
if (right instanceof SuperType)
{
System.out.println("");
}
}
else {
up = new UnifyPair(right, left, PairOperator.SMALLERDOT);
}
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, fc);
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (greaterLen == 0) return new Pair<>(1, greaterRes);
else return new Pair<>(0, new HashSet<>());
}
}
/* TODO muss noch verifiziert werden PL 2018-03-21
* (non-Javadoc)
* fuehrt zu Fehlern bei Arrays.sort (contract nicht erfuellt)
* @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object)
*/
public int compare (Set<UnifyPair> leftpara, Set<UnifyPair> rightpara) {
Set<UnifyPair> left = new HashSet<>(leftpara);
Set<UnifyPair> right = new HashSet<>(rightpara);
/*
//pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx = PlaceholderType.freshPlaceholder();
al.add(xx);
UnifyType t1 = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
//PlaceholderType yy =new PlaceholderType("yy");
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
UnifyType t2 = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
PlaceholderType a = PlaceholderType.freshPlaceholder();
a.setInnerType(true);
UnifyPair p1 = new UnifyPair(a, t1, PairOperator.SMALLERDOTWC);
PlaceholderType b = PlaceholderType.freshPlaceholder();
b.setInnerType(true);
UnifyPair p2 = new UnifyPair(b, t2, PairOperator.SMALLERDOTWC);
List<UnifyType> al3 = new ArrayList<>();
al3.add(a);
List<UnifyType> al4 = new ArrayList<>();
al4.add(b);
UnifyPair p3 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al3)), PairOperator.EQUALSDOT);
UnifyPair p4 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al4)), PairOperator.EQUALSDOT);
right = new HashSet<>();
right.add(p1);
right.add(p3);
left = new HashSet<>();
left.add(p2);
left.add(p4);
*/
Set<UnifyPair> lefteq = left.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> righteq = right.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftle = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightle = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftlewc = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightlewc = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
//System.out.println(left.toString());
//Fall 2
//if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) {
// System.out.print("");
//}
//ODER-CONSTRAINT
Set<UnifyPair> leftBase = left.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightBase = right.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> lefteqOder = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
/*try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y: " + y.toString() +"\n");
((FiniteClosure)fc).logFile.write("y.getLhsType() : " + y.getLhsType() .toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y.getRhsType(): " + y.getRhsType().toString() +"\n");
((FiniteClosure)fc).logFile.write("x.getPairOp(): " + x.getPairOp().toString() +"\n\n");
}
catch (IOException ie) {
} */
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqOder);
Set<UnifyPair> righteqOder = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqOder);
Set<UnifyPair> lefteqRet = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqRet);
Set<UnifyPair> righteqRet = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqRet);
Set<UnifyPair> leftleOder = left.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightleOder = right.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
/*
synchronized(this) {
try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqOder: " + lefteqOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqOder: " + righteqOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqRet: " + lefteqRet.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqRet: " + righteqRet.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("leftleOder: " + leftleOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
}
*/
Integer compareEq;
if (lefteqOder.size() == 1 && righteqOder.size() == 1 && lefteqRet.size() == 1 && righteqRet.size() == 1) {
Match m = new Match();
if ((compareEq = compareEq(lefteqOder.iterator().next().getGroundBasePair(), righteqOder.iterator().next().getGroundBasePair())) == -1) {
ArrayList<UnifyPair> matchList =
rightleOder.stream().map(x -> {
UnifyPair leftElem = leftleOder.stream()
.filter(y -> y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
.findAny().get();
return new UnifyPair(x.getRhsType(), leftElem.getRhsType(), PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(ArrayList::new));
if (m.match(matchList).isPresent()) {
//try { ((FiniteClosure)fc).logFile.write("result1: -1 \n\n"); } catch (IOException ie) {}
return -1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result1: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else if (compareEq == 1) {
ArrayList<UnifyPair> matchList =
leftleOder.stream().map(x -> {
UnifyPair rightElem = rightleOder.stream()
.filter(y ->
y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
.findAny().get();
return new UnifyPair(x.getRhsType(), rightElem.getRhsType(), PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(ArrayList::new));
if (m.match(matchList).isPresent()) {
//try { ((FiniteClosure)fc).logFile.write("result2: 1 \n\n"); } catch (IOException ie) {}
return 1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result2: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else {
/*
synchronized(this) {
try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqOder: " + lefteqOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqOder: " + righteqOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("lefteqRet: " + lefteqRet.toString() +"\n");
((FiniteClosure)fc).logFile.write("righteqRet: " + righteqRet.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("leftleOder: " + leftleOder.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("result3: 0 \n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
}
*/
return 0;
}
}
if (lefteq.size() == 1 && lefteq.iterator().next().getRhsType() instanceof ExtendsType && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return 1;
}
//Fall 2
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && righteq.iterator().next().getRhsType() instanceof ExtendsType && rightle.size() == 1) {
return -1;
}
//Fall 3
if (lefteq.size() == 1 && lefteq.iterator().next().getRhsType() instanceof SuperType && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return -1;
}
//Fall 3
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && righteq.iterator().next().getRhsType() instanceof SuperType && rightle.size() == 1) {
return 1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 0 && righteq.size() == 1 && rightle.size() == 1) {
return -1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 0) {
return 1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 1) {
return 0;
}
// Nur Paare a =. Theta
if (leftle.size() == 0 && rightle.size() == 0 && leftlewc.size() == 0 && rightlewc.size() ==0) {
Stream<UnifyPair> lseq = lefteq.stream(); //left.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
Stream<UnifyPair> rseq = righteq.stream(); //right.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm = rseq.reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
lseq = lseq.filter(x -> !(hm.get(x.getLhsType()) == null));//NOCHMALS UEBERPRUEFEN!!!!
lseq = lseq.filter(x -> !x.equals(hm.get(x.getLhsType()))); //Elemente die gleich sind muessen nicht verglichen werden
Optional<Integer> si = lseq.map(x -> compareEq(x, hm.get(x.getLhsType()))).reduce((x,y)-> { if (x == y) return x; else return 0; } );
if (!si.isPresent()) return 0;
else return si.get();
}
//Fall 1 und 4
if (lefteq.size() >= 1 && righteq.size() >= 1 && (leftlewc.size() > 0 || rightlewc.size() > 0)) {
if (lefteq.iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
//Set<PlaceholderType> varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//Set<PlaceholderType> varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) andere Substitutioen werden rausgefiltert
lefteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType()));
righteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//.removeIf(x -> !varsleft.contains(x.getLhsType()));
UnifyPair lseq = lefteq.iterator().next();
UnifyPair rseq = righteq.iterator().next();
if (lseq.getRhsType().getName().equals("Object")) {
if (rseq.getRhsType().getName().equals("Object")) return 0;
else return 1;
}
else {
if (rseq.getRhsType().getName().equals("Object")) return -1;
}
if (leftlewc.size() == rightlewc.size()) {
//TODO: Hier wird bei Wildcards nicht das richtige compare aufgerufen PL 18-04-20
Pair<Integer, Set<UnifyPair>> int_Unifier = compare(lseq.getRhsType(), rseq.getRhsType());
Unifier uni = new Unifier();
int_Unifier.getValue().get().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
if (!lseq.getRhsType().getName().equals(rseq.getRhsType().getName())
|| leftlewc.size() == 0 || rightlewc.size() == 0) return int_Unifier.getKey();
else {
Set <UnifyPair> lsleuni = leftlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
Set <UnifyPair> rsleuni = rightlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm;
Optional<Integer> si;
//1. Fall
if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getLhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
//4. Fall
else {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getRhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getRhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getLhsType(), hm.get(x.getRhsType()).getLhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
if (!si.isPresent()) return 0;
else return si.get();
}
} else {
if (leftlewc.size() > 0) {
Set<UnifyPair> subst;
subst = leftlewc.stream().map(x -> {
if (x.getLhsType() instanceof PlaceholderType) {
return new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT);
}
else {
return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT);
}}).collect(Collectors.toCollection(HashSet::new));
Unifier uni = new Unifier();
lseq = uni.apply(lseq);
}
else {
Set<UnifyPair> subst;
subst = rightlewc.stream().map(x -> {
if (x.getLhsType() instanceof PlaceholderType) {
return new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT);
}
else {
return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT);
}}).collect(Collectors.toCollection(HashSet::new));
Unifier uni = new Unifier();
subst.stream().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
rseq = uni.apply(rseq);
}
return compareEq(lseq, rseq);
}
}
return 0;
}
}

View File

@@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model;
/**
* Operators of pairs of the unification.
*
* @author Florian Steurer
*/
public enum PairOperator {
@@ -38,12 +39,12 @@ public enum PairOperator {
@Override
public String toString() {
switch (this) {
case SMALLER: return "<";
case SMALLERDOT: return "<.";
case SMALLERNEQDOT: return "<!=.";
case SMALLERDOTWC: return "<.?";
default: return "=."; // EQUALSDOT
}
return switch (this) {
case SMALLER -> "<";
case SMALLERDOT -> "<.";
case SMALLERNEQDOT -> "<!=.";
case SMALLERDOTWC -> "<.?";
default -> "=."; // EQUALSDOT
};
}
}

View File

@@ -10,6 +10,7 @@ import java.util.Set;
/**
* An unbounded placeholder type.
*
* @author Florian Steurer
*/
public final class PlaceholderType extends UnifyType {
@@ -20,15 +21,10 @@ public final class PlaceholderType extends UnifyType{
*/
public static final ArrayList<String> EXISTING_PLACEHOLDERS = new ArrayList<String>();
/**
* Prefix of auto-generated placeholder names.
*/
protected static String nextName = "gen_";
/**
* Random number generator used to generate fresh placeholder name.
*/
protected static Random rnd = new Random(43558747548978L);
private static final Random rnd = new Random(43558747548978L);
/**
* True if this object was auto-generated, false if this object was user-generated.
@@ -37,12 +33,12 @@ public final class PlaceholderType extends UnifyType{
/**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
* Defines, if a WildcardType can be assigned to this PlaceholderType
*/
private boolean wildcardable = true;
private boolean canBeWildcard = true;
/**
* is innerType gibt an, ob der Type des PlaceholderType innerhalb eines Typkonstruktorsverwendet wird
* Defines, if this type is used inside a type constructor
*/
private boolean innerType = false;
@@ -56,7 +52,7 @@ public final class PlaceholderType extends UnifyType{
private int variance = 0;
/*
* Fuer Oder-Constraints:
* For Oder-Constraints:
* orCons = 1: Receiver
* orCons = 0: Argument oder kein Oder-Constraint
* orCons = -1: RetType
@@ -74,6 +70,7 @@ public final class PlaceholderType extends UnifyType{
/**
* Creates a new placeholdertype
*
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
*/
public PlaceholderType(String name, boolean isGenerated) {
@@ -82,17 +79,14 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = isGenerated;
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a fresh placeholder type with a name that does so far not exist.
* A user could later instantiate a type using the same name that is equivalent to this type.
*
* @return A fresh placeholder type.
*/
public synchronized static PlaceholderType freshPlaceholder() {
String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
String name = "gen_" + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
// Add random chars while the name is in use.
while (EXISTING_PLACEHOLDERS.contains(name)) {
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
@@ -100,6 +94,9 @@ public final class PlaceholderType extends UnifyType{
return new PlaceholderType(name, true);
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* True if this placeholder is auto-generated, false if it is user-generated.
@@ -108,44 +105,42 @@ public final class PlaceholderType extends UnifyType{
return IsGenerated;
}
public void setVariance(int v) {
variance = v;
}
public int getVariance() {
return variance;
}
public void setVariance(int v) {
variance = v;
}
public void reversVariance() {
if (variance == 1) {
setVariance(-1);
} else {
if (variance == -1) {
setVariance(1);
}}
}
public void setOrCons(byte i) {
orCons = i;
}
}
public byte getOrCons() {
return orCons;
}
public void setOrCons(byte i) {
orCons = i;
}
public Boolean isWildcardable() {
return wildcardable;
}
public void disableWildcardtable() {
wildcardable = false;
return canBeWildcard;
}
public void enableWildcardtable() {
wildcardable = true;
public void disableWildcardable() {
canBeWildcard = false;
}
public void setWildcardtable(Boolean wildcardable) {
this.wildcardable = wildcardable;
public void enableWildcardable() {
canBeWildcard = true;
}
public Boolean isInnerType() {
@@ -168,7 +163,7 @@ public final class PlaceholderType extends UnifyType{
@Override
public UnifyType setTypeParams(TypeParams newTp) {
return this; // Placeholders never have params.
throw new RuntimeException("Placeholders never have params");
}
@Override
@@ -177,23 +172,23 @@ public final class PlaceholderType extends UnifyType{
}
@Override
UnifyType apply(Unifier unif) {
if(unif.hasSubstitute(this)) {
UnifyType ret = unif.getSubstitute(this);
UnifyType apply(Unifier unifier) {
if (unifier.hasSubstitute(this)) {
//PL 2018-05-17 Auskommentierung muesste korrekt sein,
//bereits in JavaTXComplier Variancen gesetzt werden.
//ret.accept(new distributeVariance(), this.getVariance());
return ret;
return unifier.getSubstitute(this);
}
return this;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof PlaceholderType))
return false;
if (obj instanceof PlaceholderType placeholderObj) {
return placeholderObj.getName().equals(typeName);
}
return ((PlaceholderType) obj).getName().equals(typeName);
return false;
}

View File

@@ -7,8 +7,8 @@ import java.util.Set;
/**
* A reference type e.q. Integer or List<T>.
* @author Florian Steurer
*
* @author Florian Steurer
*/
public class ReferenceType extends UnifyType {
@@ -18,15 +18,10 @@ public class ReferenceType extends UnifyType {
private final int hashCode;
/**
* gibt an, ob der ReferenceType eine generische Typvariable ist
* Defines, if the reference type is a generic type variable
*/
private final boolean genericTypeVar;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public ReferenceType(String name, Boolean genericTypeVar) {
super(name, new TypeParams());
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
@@ -45,6 +40,10 @@ public class ReferenceType extends UnifyType {
genericTypeVar = false;
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public boolean isGenTypeVar() {
return genericTypeVar;
}
@@ -60,8 +59,8 @@ public class ReferenceType extends UnifyType {
}
@Override
UnifyType apply(Unifier unif) {
TypeParams newParams = typeParams.apply(unif);
UnifyType apply(Unifier unifier) {
TypeParams newParams = typeParams.apply(unifier);
if (newParams.hashCode() == typeParams.hashCode() && newParams.equals(typeParams))
return this;
@@ -71,8 +70,10 @@ public class ReferenceType extends UnifyType {
@Override
public UnifyType setTypeParams(TypeParams newTp) {
if(newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams))
return this; // reduced the amount of objects created
if (newTp.hashCode() == typeParams.hashCode() && newTp.equals(typeParams)) {
// reduced the amount of objects created by reusing this instance
return this;
}
return new ReferenceType(typeName, newTp);
}
@@ -83,17 +84,15 @@ public class ReferenceType extends UnifyType {
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ReferenceType))
if (!(obj instanceof ReferenceType referenceObj))
return false;
if (obj.hashCode() != this.hashCode())
return false;
ReferenceType other = (ReferenceType) obj;
if(!other.getName().equals(typeName))
if (!referenceObj.getName().equals(typeName))
return false;
return other.getTypeParams().equals(typeParams);
return referenceObj.getTypeParams().equals(typeParams);
}
}

View File

@@ -7,22 +7,24 @@ import java.util.Set;
/**
* A super wildcard type e.g. ? super Integer.
*
* @author Florian Steurer
*/
public final class SuperType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* Creates a new instance "? extends superedType"
*
* @param superedType The type that is supered e.g. Integer in "? super Integer"
*/
public SuperType(UnifyType superedType) {
super("? super " + superedType.getName(), superedType);
}
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/**
* The type that is supered e.g. Integer in "? super Integer"
*/
@@ -41,8 +43,10 @@ public final class SuperType extends WildcardType {
@Override
public UnifyType setTypeParams(TypeParams newTp) {
UnifyType newType = wildcardedType.setTypeParams(newTp);
if(newType == wildcardedType)
return this; // Reduced the amount of objects created
if (newType == wildcardedType) {
// Reduced the amount of objects created by reusing this instance
return this;
}
return new SuperType(wildcardedType.setTypeParams(newTp));
}
@@ -57,10 +61,12 @@ public final class SuperType extends WildcardType {
}
@Override
UnifyType apply(Unifier unif) {
UnifyType newType = wildcardedType.apply(unif);
if(newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType))
return this; // Reduced the amount of objects created
UnifyType apply(Unifier unifier) {
UnifyType newType = wildcardedType.apply(unifier);
if (newType.hashCode() == wildcardedType.hashCode() && newType.equals(wildcardedType)) {
// Reduced the amount of objects created by reusing this instance
return this;
}
return new SuperType(newType);
}
@@ -75,13 +81,12 @@ public final class SuperType extends WildcardType {
@Override
public boolean equals(Object obj) {
if(!(obj instanceof SuperType))
if (!(obj instanceof SuperType superObj))
return false;
if (obj.hashCode() != this.hashCode())
return false;
SuperType other = (SuperType) obj;
return other.getSuperedType().equals(wildcardedType);
return superObj.getSuperedType().equals(wildcardedType);
}
}

View File

@@ -5,6 +5,7 @@ import java.util.*;
/**
* The generic or non-generic parameters of a type e.g. <T> for List<T>
*
* @author Florian Steurer
*/
public final class TypeParams implements Iterable<UnifyType> {
@@ -20,6 +21,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/**
* Creates a new set of type parameters.
*
* @param types The type parameters.
*/
public TypeParams(List<UnifyType> types) {
@@ -35,6 +37,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/**
* Creates a new set of type parameters.
*
* @param types The type parameters.
*/
public TypeParams(UnifyType... types) {
@@ -45,7 +48,7 @@ public final class TypeParams implements Iterable<UnifyType>{
}
/**
* True if every parameter in this object is a placeholder type, false otherwise.
* @return True if every parameter in this object is a placeholder type, false otherwise.
*/
public boolean arePlaceholders() {
return Arrays.stream(typeParams).allMatch(x -> x instanceof PlaceholderType);
@@ -53,6 +56,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/**
* Returns the number of the type parameters in this object.
*
* @return number of type parameters, always positive (including 0).
*/
public int size() {
@@ -60,7 +64,7 @@ public final class TypeParams implements Iterable<UnifyType>{
}
/**
* Returns true if this object has size() of zero, false otherwise.
* @return true if this object has size() of zero, false otherwise.
*/
public boolean empty() {
return typeParams.length == 0;
@@ -68,6 +72,7 @@ public final class TypeParams implements Iterable<UnifyType>{
/**
* Applies a unifier to every parameter in this object.
*
* @param unif The applied unifier.
* @return A new type parameter object, where the unifier was applied to every parameter.
*/
@@ -101,10 +106,10 @@ public final class TypeParams implements Iterable<UnifyType>{
if (p instanceof PlaceholderType) {//PL 2018-01-31 dangeling else Problem { ... } eingefuegt.
if (p.equals(t))
return true;
}
else {
} else {
if (p.getTypeParams().occurs(t))
return true; }
return true;
}
return false;
}
@@ -150,21 +155,15 @@ public final class TypeParams implements Iterable<UnifyType>{
@Override
public boolean equals(Object obj) {
if(!(obj instanceof TypeParams))
if (!(obj instanceof TypeParams other))
return false;
if (obj.hashCode() != this.hashCode())
return false;
TypeParams other = (TypeParams) obj;
if (other.size() != this.size())
return false;
for(int i = 0; i < this.size(); i++){
//if(this.get(i) == null)
//System.out.print("s");
}
for (int i = 0; i < this.size(); i++)
if (!(this.get(i).equals(other.get(i))))
return false;
@@ -174,9 +173,9 @@ public final class TypeParams implements Iterable<UnifyType>{
@Override
public String toString() {
String res = "";
StringBuilder res = new StringBuilder();
for (UnifyType t : typeParams)
res += t + ",";
res.append(t).append(",");
return "<" + res.substring(0, res.length() - 1) + ">";
}

View File

@@ -9,6 +9,7 @@ import java.util.function.Function;
/**
* A set of substitutions (s -> t) that is an applicable function to types and pairs.
*
* @author Florian Steurer
*/
public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<PlaceholderType, UnifyType>> {
@@ -16,26 +17,27 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/**
* The set of substitutions that unify a type-term
*/
private HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>();
private final HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>();
/**
* Creates a new instance with a single substitution (source -> target).
* @param The type that is replaced
* @param The type that replaces
*
* @param source The type that is replaced
* @param target The type that replaces
*/
public Unifier(PlaceholderType source, UnifyType target) {
substitutions.put(source, target);
}
/**
* Identity function as an "unifier".
* Identity function as a "unifier".
*/
protected Unifier() {
}
/**
* Creates an unifier that is the identity function (thus has no substitutions).
* Creates a unifier that is the identity function (thus has no substitutions).
*/
public static Unifier identity() {
return new Unifier();
@@ -43,15 +45,15 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/**
* Adds a substitution to the unifier from (source -> target)
* @param The type that is replaced
* @param The type that replaces
*
* @param source The type that is replaced
* @param target The type that replaces
*/
public void add(PlaceholderType source, UnifyType target) {
Unifier tempU = new Unifier(source, target);
// Every new substitution must be applied to previously added substitutions
// otherwise the unifier needs to be applied multiple times to unify two terms
for(PlaceholderType pt : substitutions.keySet())
substitutions.put(pt, substitutions.get(pt).apply(tempU));
substitutions.replaceAll((p, _) -> substitutions.get(p).apply(tempU));
substitutions.put(source, target);
}
@@ -62,6 +64,7 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/**
* Applies the unifier to the two terms of the pair.
*
* @return A new pair where the left and right-hand side are applied
*/
public UnifyPair apply(UnifyPair p) {
@@ -72,72 +75,61 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
/**
* Applies the unifier to the two terms of the pair.
* works only for single subsitution
* works only for single substitution
*
* @return A new pair where the left and right-hand side are applied
*/
public UnifyPair apply(UnifyPair thisAsPair, UnifyPair p) {
UnifyType newLhs = this.apply(p.getLhsType());
UnifyType newRhs = this.apply(p.getRhsType());
//Varianceweitergabe wird nicht benoetigt.
//PlaceholderType lhsph = (PlaceholderType)thisAsPair.getLhsType();
//if (lhsph.getVariance() != 0) {
// if (p.getLhsType().equals(lhsph)) {
// if (p.getRhsType() instanceof PlaceholderType) {
// ((PlaceholderType)p.getRhsType()).setVariance(lhsph.getVariance());
// }
// }
// if (p.getRhsType().equals(lhsph)) {
// if (p.getLhsType() instanceof PlaceholderType) {
// ((PlaceholderType)p.getLhsType()).setVariance(lhsph.getVariance());
// }
// }
//}
if (!(p.getLhsType().equals(newLhs)) || !(p.getRhsType().equals(newRhs))) {//Die Anwendung von this hat was veraendert PL 2018-04-01
Set<UnifyPair> suniUnifyPair = new HashSet<>();
suniUnifyPair.addAll(thisAsPair.getAllSubstitutions());
suniUnifyPair.add(thisAsPair);
if (p.getLhsType() instanceof PlaceholderType //&& newLhs instanceof PlaceholderType entfernt PL 2018-04-13
&& p.getPairOp() == PairOperator.EQUALSDOT) {
suniUnifyPair.add(p); //p koennte auch subsitution sein
if (!(p.getLhsType().equals(newLhs)) || !(p.getRhsType().equals(newRhs))) {
//Die Anwendung von this hat was veraendert PL 2018-04-01
Set<UnifyPair> sUniUnifyPair = new HashSet<>(thisAsPair.getAllSubstitutions());
sUniUnifyPair.add(thisAsPair);
if (p.getLhsType() instanceof PlaceholderType
&& p.getPairOp() == PairOperator.EQUALSDOT
) {
sUniUnifyPair.add(p); //p could also be substitution
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p);
return new UnifyPair(newLhs, newRhs, p.getPairOp(), sUniUnifyPair, p);
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getfBounded());
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair(), p.getFBounded());
}
/**
* Applies the unifier to the left terms of the pair.
*
* @return A new pair where the left and right-hand side are applied
*/
public UnifyPair applyleft(UnifyPair p) {
public UnifyPair applyLeft(UnifyPair p) {
return new UnifyPair(this.apply(p.getLhsType()), p.getRhsType(), p.getPairOp());
}
/**
* True if the typevariable t will be substituted if the unifier is applied.
* false otherwise.
* @return True if the type variable t will be substituted if the unifier is applied. False otherwise.
*/
public boolean hasSubstitute(PlaceholderType t) {
return substitutions.containsKey(t);
}
/**
* Returns the type that will replace the typevariable t if the unifier is applied.
* @return The type that will replace the type variable t if the unifier is applied.
*/
public UnifyType getSubstitute(PlaceholderType t) {
return substitutions.get(t);
}
/**
* The number of substitutions in the unifier. If zero, this is the identity function.
* @return The number of substitutions in the unifier. If zero, this is the identity function.
*/
public int size() {
return substitutions.size();
}
/**
* Garantuees that if there is a substitutions (a -> b) in this unifier,
* a is not an element of the targetParams. Substitutions that do not
* Guarantees that if there is a substitutions (a -> b) in this unifier,
* then a is not an element of the targetParams. Substitutions that do not
* satisfy this condition, are swapped.
*/
public void swapPlaceholderSubstitutions(Iterable<UnifyType> targetParams) {
@@ -146,8 +138,7 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
continue;
// Swap a substitutions (a -> b) if a is an element of the target params.
if (substitutions.containsKey(tph)) {
if((substitutions.get(tph) instanceof PlaceholderType)) {
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
if ((substitutions.get(tph) instanceof PlaceholderType newLhs)) {
substitutions.remove(tph);
substitutions.put(newLhs, tph);
}

View File

@@ -7,6 +7,7 @@ import java.util.Set;
/**
* A pair which contains two types and an operator, e.q. (Integer <. a).
*
* @author Florian Steurer
*/
public class UnifyPair {
@@ -20,37 +21,32 @@ public class UnifyPair {
* The type on the right hand side of the pair.
*/
private final UnifyType rhs;
/**
* The operator that determines the relation between the left and right hand side type.
*/
private PairOperator pairOp;
private boolean undefinedPair = false;
/**
* Unifier/substitute that generated this pair
* PL 2018-03-15
*/
private Set<UnifyPair> substitution;
private final Set<UnifyPair> substitution;
private final int hashCode;
/**
* Base on which the the unifier is applied
* The operator that determines the relation between the left and right hand side type.
*/
private PairOperator pairOp;
private boolean undefinedPair = false;
/**
* Base on which the unifier is applied
* PL 2018-03-15
*/
private UnifyPair basePair;
/**
* For pairs a <. Theta generated in the rule reduceTphSup
* to store the f-Bouned Elements to avoid endless recursion
* to store the f-Bounded Elements to avoid endless recursion
* PL 2018-03-15
*/
private Set<UnifyType> fBounded = new HashSet<>();
private final int hashCode;
/**
* Creates a new instance of the pair.
*
* @param lhs The type on the left hand side of the pair.
* @param rhs The type on the right hand side of the pair.
* @param op The operator that determines the relation between the left and right hand side type.
@@ -72,33 +68,31 @@ public class UnifyPair {
substitution = uni;
basePair = base;
// Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
}
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base, Set<UnifyType> fBounded) {
this(lhs, rhs, op, uni, base);
this.fBounded = fBounded;
}
/**
* Returns the type on the left hand side of the pair.
* @return The type on the left hand side of the pair.
*/
public UnifyType getLhsType() {
return lhs;
}
/**
* Returns the type on the right hand side of the pair.
* @return The type on the right hand side of the pair.
*/
public UnifyType getRhsType() {
return rhs;
}
/**
* Returns the operator that determines the relation between the left and right hand side type.
* @return The operator that determines the relation between the left and right hand side type.
*/
public PairOperator getPairOp() {
return pairOp;
@@ -115,6 +109,7 @@ public class UnifyPair {
public void setUndefinedPair() {
undefinedPair = true;
}
public Set<UnifyPair> getSubstitution() {
return new HashSet<>(substitution);
}
@@ -122,13 +117,13 @@ 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()));
Set<UnifyPair> ret = new HashSet<>(new ArrayList<>(getSubstitution()));
if (basePair != null) {
ret.addAll(new ArrayList<>(basePair.getAllSubstitutions()));
}
@@ -140,6 +135,7 @@ public class UnifyPair {
ret.add(this);
return ret;
}
public Set<UnifyPair> getAllBases() {
Set<UnifyPair> ret = new HashSet<>();
if (basePair != null) {
@@ -156,58 +152,55 @@ public class UnifyPair {
if (basePair.getBasePair() == null) {
return basePair;
}
else {
return basePair.getGroundBasePair();
}
}
/**
* wenn in einem Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist,
* so beide auf nicht wildcardtable setzen
* if a pair of two type variables contains one that can not be replaced by a wildcard, then both
* of them cannot be replaced by a wildcard
*/
public void disableCondWildcards() {
if (lhs instanceof PlaceholderType && rhs instanceof PlaceholderType
&& (!((PlaceholderType)lhs).isWildcardable() || !((PlaceholderType)rhs).isWildcardable()))
{
((PlaceholderType)lhs).disableWildcardtable();
((PlaceholderType)rhs).disableWildcardtable();
if (!(lhs instanceof PlaceholderType lhsPlaceholder) || !(rhs instanceof PlaceholderType rhsPlaceholder)) {
return;
}
if (!lhsPlaceholder.isWildcardable() || !rhsPlaceholder.isWildcardable()) {
lhsPlaceholder.disableWildcardable();
rhsPlaceholder.disableWildcardable();
}
}
public Boolean wrongWildcard() {
return lhs.wrongWildcard() || rhs.wrongWildcard();
}
public Set<UnifyType> getfBounded() {
public Set<UnifyType> getFBounded() {
return this.fBounded;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair))
if (!(obj instanceof UnifyPair unifyPairObj))
return false;
if (obj.hashCode() != this.hashCode())
return false;
UnifyPair other = (UnifyPair) obj;
if (isUndefinedPair()) {
if (other.getBasePair() != basePair || (other.getBasePair() == null && basePair == null)) {
if (unifyPairObj.getBasePair() != basePair || (unifyPairObj.getBasePair() == null && basePair == null)) {
return false;
}
if (!other.getBasePair().equals(basePair) ||
!other.getAllSubstitutions().equals(getAllSubstitutions())) {
if (!unifyPairObj.getBasePair().equals(basePair) ||
!unifyPairObj.getAllSubstitutions().equals(getAllSubstitutions())) {
return false;
}
}
return other.getPairOp() == pairOp
&& other.getLhsType().equals(lhs)
&& other.getRhsType().equals(rhs);
return unifyPairObj.getPairOp() == pairOp
&& unifyPairObj.getLhsType().equals(lhs)
&& unifyPairObj.getRhsType().equals(rhs);
}
@Override
@@ -218,25 +211,17 @@ public class UnifyPair {
@Override
public String toString() {
String ret = "";
if (lhs instanceof PlaceholderType) {
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString() + " "
+ "WC: " + ((PlaceholderType)lhs).isWildcardable()
+ ", IT: " + ((PlaceholderType)lhs).isInnerType();
if (lhs instanceof PlaceholderType lhsPlaceholder) {
ret = lhsPlaceholder.getVariance() + " "
+ "WC: " + lhsPlaceholder.isWildcardable() + ", "
+ "IT: " + lhsPlaceholder.isInnerType();
}
if (rhs instanceof PlaceholderType) {
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString() + " "
+ "WC: " + ((PlaceholderType)rhs).isWildcardable()
+ ", IT: " + ((PlaceholderType)rhs).isInnerType();
if (rhs instanceof PlaceholderType rhsPlaceholder) {
ret = ret + ", " + rhsPlaceholder.getVariance() + " "
+ "WC: " + rhsPlaceholder.isWildcardable() + ", "
+ "IT: " + rhsPlaceholder.isInnerType();
}
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])";
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")";
}
/*
public List<? extends PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.addAll(lhs.getInvolvedPlaceholderTypes());
ret.addAll(rhs.getInvolvedPlaceholderTypes());
return ret;
}
*/
}

View File

@@ -9,6 +9,7 @@ import java.util.Set;
/**
* Represents a java type.
*
* @author Florian Steurer
*/
public abstract class UnifyType {
@@ -25,12 +26,13 @@ public abstract class UnifyType {
/**
* Creates a new instance
*
* @param name Name of the type (e.q. List for List<T>, Integer or ? extends Integer)
* @param typeParams Parameters of the type (e.q. <T> for List<T>)
* @param params Parameters of the type (e.q. <T> for List<T>)
*/
protected UnifyType(String name, TypeParams p) {
protected UnifyType(String name, TypeParams params) {
typeName = name;
typeParams = p;
typeParams = params;
}
@@ -38,6 +40,7 @@ public abstract class UnifyType {
/**
* Returns the name of the type.
*
* @return The name e.q. List for List<T>, Integer or ? extends Integer
*/
public String getName() {
@@ -46,6 +49,7 @@ public abstract class UnifyType {
/**
* The parameters of the type.
*
* @return Parameters of the type, e.q. <T> for List<T>.
*/
public TypeParams getTypeParams() {
@@ -54,6 +58,7 @@ public abstract class UnifyType {
/**
* Returns a new type that equals this type except for the type parameters.
*
* @param newTp The type params of the new type.
* @return A new type object.
*/
@@ -62,6 +67,7 @@ public abstract class UnifyType {
/**
* Implementation of the visitor-pattern. Returns the set of smArg
* by calling the most specific overload in the FC.
*
* @param fc The FC that is called.
* @return The set that is smArg(this)
*/
@@ -70,6 +76,7 @@ public abstract class UnifyType {
/**
* Implementation of the visitor-pattern. Returns the set of grArg
* by calling the most specific overload in the FC.
*
* @param fc The FC that is called.
* @return The set that is grArg(this)
*/
@@ -77,10 +84,11 @@ public abstract class UnifyType {
/**
* Applies a unifier to this object.
* @param unif The unifier
*
* @param unifier The unifier
* @return A UnifyType, that may or may not be a new object, that has its subtypes substituted.
*/
abstract UnifyType apply(Unifier unif);
abstract UnifyType apply(Unifier unifier);
@Override
public String toString() {
@@ -95,9 +103,7 @@ public abstract class UnifyType {
}
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.addAll(typeParams.getInvolvedPlaceholderTypes());
return ret;
return new ArrayList<>(typeParams.getInvolvedPlaceholderTypes());
}
public Boolean wrongWildcard() {//default
@@ -111,7 +117,9 @@ public abstract class UnifyType {
@Override
public boolean equals(Object obj) {
if(obj == null)return false;
if (!(obj instanceof UnifyType)) {
return false;
}
return this.toString().equals(obj.toString());
}
}

View File

@@ -5,6 +5,7 @@ import java.util.Collection;
/**
* A wildcard type that is either a ExtendsType or a SuperType.
*
* @author Florian Steurer
*/
public abstract class WildcardType extends UnifyType {
@@ -16,6 +17,7 @@ public abstract class WildcardType extends UnifyType {
/**
* Creates a new instance.
*
* @param name The name of the type, e.q. ? extends Integer
* @param wildcardedType The wildcarded type, e.q. Integer for ? extends Integer. Never a wildcard type itself.
*/
@@ -26,6 +28,7 @@ public abstract class WildcardType extends UnifyType {
/**
* Returns the wildcarded type, e.q. Integer for ? extends Integer.
*
* @return The wildcarded type. Never a wildcard type itself.
*/
public UnifyType getWildcardedType() {
@@ -33,7 +36,7 @@ public abstract class WildcardType extends UnifyType {
}
/**
* Returns the type parameters of the WILDCARDED TYPE.
* Returns the type parameters of the wildcarded type.
*/
@Override
public TypeParams getTypeParams() {
@@ -52,21 +55,18 @@ public abstract class WildcardType extends UnifyType {
@Override
public boolean equals(Object obj) {
if(!(obj instanceof WildcardType))
if (!(obj instanceof WildcardType wildcardObj))
return false;
if (obj.hashCode() != this.hashCode())
return false;
WildcardType other = (WildcardType) obj;
return other.getWildcardedType().equals(wildcardedType);
return wildcardObj.getWildcardedType().equals(wildcardedType);
}
@Override
public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.addAll(wildcardedType.getInvolvedPlaceholderTypes());
return ret;
return new ArrayList<>(wildcardedType.getInvolvedPlaceholderTypes());
}
}

View File

@@ -11,9 +11,7 @@ public class hashKeyType {
public boolean equals(Object obj) {
if (obj instanceof hashKeyType) {
return realType.equals(((hashKeyType) obj).realType);
}
else
{
} else {
return false;
}
}

View File

@@ -1,47 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
public class visitUnifyTypeVisitor<T> implements UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht) {
return new ReferenceType(refty.getName(),
new TypeParams(
Arrays.stream(refty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new))));
}
public PlaceholderType visit(PlaceholderType phty, T ht) {
return phty;
}
public FunNType visit(FunNType funnty, T ht) {
return FunNType.getFunNType(
new TypeParams(
Arrays.stream(funnty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new)))
);
}
public SuperType visit(SuperType suty, T ht) {
return new SuperType(suty.getWildcardedType().accept(this, ht));
}
public ExtendsType visit(ExtendsType extty, T ht) {
return new ExtendsType(extty.getWildcardedType().accept(this, ht));
}
}

View File

@@ -12,8 +12,4 @@ public class BiRelation<X,Y> extends ArrayList<Pair<X,Y>>{
this.add(p);
}
public void putAll(BiRelation<X,Y> br) {
this.addAll(br);
}
}