Merge mit bytecode

This commit is contained in:
JanUlrich 2018-04-25 16:13:23 +02:00
commit 41774b3faf
37 changed files with 1693 additions and 233 deletions

View File

@ -4,31 +4,38 @@ package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
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.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.inheritVariance;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JavaTXCompiler {
@ -97,20 +104,73 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify();
Set<Set<UnifyPair>> results = new HashSet<>();
for (List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()) {
Set<UnifyPair> xConsSet = new HashSet<>();
for (Constraint<UnifyPair> constraint : xCons) {
xConsSet.addAll(constraint);
}
System.out.println(xConsSet);
Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
System.out.println("RESULT: " + result.size());
results.addAll(result);
try {
FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/test/logFiles/"+"log"));
logFile.write("FC:\\" + finiteClosure.toString()+"\n");
for(SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
}
logFile.flush();
for (List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()) {
Set<UnifyPair> xConsSet = new HashSet<>();
for (Constraint<UnifyPair> constraint : xCons) {
xConsSet.addAll(constraint);
}
//.collect(Collectors.toCollection(ArrayList::new))))
System.out.println(xConsSet);
Set<String> paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist()
.stream().filter(z -> z.getType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get())
.reduce((a,b) -> { a.addAll(b); return a;} ).get();
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
xConsSet = xConsSet.stream().map(x -> {
//Hier muss ueberlegt werden, ob
//1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
//2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
//in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
//PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType)x.getLhsType()).setVariance((byte)1);
((PlaceholderType)x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
((PlaceholderType)x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType)x.getRhsType()).setVariance((byte)1);
((PlaceholderType)x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
((PlaceholderType)x.getRhsType()).disableWildcardtable();
}
}
return x;
}).collect(Collectors.toCollection(HashSet::new));
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, logFile);
//Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString()+"\n");
logFile.flush();
results.addAll(result);
}
}
catch (IOException e) { }
return results.stream().map((unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
}
return results.stream().map((unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
}
private Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>();
@ -156,4 +216,4 @@ public class JavaTXCompiler {
System.out.println(name+".class file generated");
}
}
}
}

View File

@ -57,48 +57,55 @@ public class FCGenerator {
params.add(gtvs.get(gtv.getName()));
}
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception
{
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString()));
}else{
superClass = hasSuperclass.get();
}
/*
Die Parameter der superklasse müssen jetzt nach den Angaben in der Subklasse
modifiziert werden
Beispie: Matrix<A> extends Vector<Vector<A>>
Den ersten Parameter mit Vector<A> austauschen und dort alle Generics zu den Typplaceholdern in gtvs austauschen
*/
//Hier vermerken, welche Typen im der Superklasse ausgetauscht werden müssen
Iterator<GenericTypeVar> itGenParams = superClass.getGenerics().iterator();
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itSetParams = forType.getSuperClass().getParaList().iterator();
while(itGenParams.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next();
//In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen:
RefTypeOrTPHOrWildcardOrGeneric setSetType = setType.acceptTV(new TypeExchanger(gtvs));
newGTVs.put(itGenParams.next().getName(), setSetType);
}
RefTypeOrTPHOrWildcardOrGeneric superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs));
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken());
RefTypeOrTPHOrWildcardOrGeneric t2 = superType;
Pair ret = new Pair(t1, t2, PairOperator.SMALLER);
List<Pair> superTypes;
//Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse:
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs);
}
List<RefType> superClasses = new ArrayList<>();
superClasses.add(forType.getSuperClass());
superClasses.addAll(forType.getSuperInterfaces());
List<Pair> retList = new ArrayList<>();
retList.add(ret);
retList.addAll(superTypes);
for(RefType superType : superClasses){
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> superType.getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception
{
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(superType.getName().toString()));
}else{
superClass = hasSuperclass.get();
}
/*
Die Parameter der superklasse müssen jetzt nach den Angaben in der Subklasse
modifiziert werden
Beispie: Matrix<A> extends Vector<Vector<A>>
Den ersten Parameter mit Vector<A> austauschen und dort alle Generics zu den Typplaceholdern in gtvs austauschen
*/
//Hier vermerken, welche Typen im der Superklasse ausgetauscht werden müssen
Iterator<GenericTypeVar> itGenParams = superClass.getGenerics().iterator();
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itSetParams = superType.getParaList().iterator();
while(itSetParams.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next();
//In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen:
RefTypeOrTPHOrWildcardOrGeneric setSetType = setType.acceptTV(new TypeExchanger(gtvs));
newGTVs.put(itGenParams.next().getName(), setSetType);
}
RefTypeOrTPHOrWildcardOrGeneric superRefType = superType.acceptTV(new TypeExchanger(newGTVs));
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken());
RefTypeOrTPHOrWildcardOrGeneric t2 = superRefType;
Pair ret = new Pair(t1, t2, PairOperator.SMALLER);
List<Pair> superTypes;
//Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse:
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs);
}
retList.add(ret);
retList.addAll(superTypes);
}
return retList;
}

View File

@ -203,20 +203,20 @@ public class SyntaxTreeGenerator{
}
Boolean isInterface = false;
List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = convert(ctx.superinterfaces(), generics);
List<RefType> implementedInterfaces = convert(ctx.superinterfaces(), generics);
return new ClassOrInterface(modifiers, name, fielddecl, methods, konstruktoren, genericClassParameters, superClass,
isInterface, implementedInterfaces, offset);
}
private List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.SuperinterfacesContext ctx, GenericsRegistry generics) {
private List<RefType> convert(Java8Parser.SuperinterfacesContext ctx, GenericsRegistry generics) {
if(ctx == null)return new ArrayList<>();
return convert(ctx.interfaceTypeList(), generics);
}
private List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.InterfaceTypeListContext ctx, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
private List<RefType> convert(Java8Parser.InterfaceTypeListContext ctx, GenericsRegistry generics) {
List<RefType> ret = new ArrayList<>();
for(Java8Parser.InterfaceTypeContext interfaceType : ctx.interfaceType()){
ret.add(TypeGenerator.convert(interfaceType.classType(), reg, generics));
ret.add((RefType) TypeGenerator.convert(interfaceType.classType(), reg, generics));
}
return ret;
}
@ -400,7 +400,7 @@ public class SyntaxTreeGenerator{
List<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);
List<RefTypeOrTPHOrWildcardOrGeneric> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);
List<RefType> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);
return new ClassOrInterface(modifiers, name, fields, methods, new ArrayList<>(),
genericParams, superClass, true, extendedInterfaces, ctx.getStart());
@ -423,7 +423,7 @@ public class SyntaxTreeGenerator{
return ret;
}
private List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.ExtendsInterfacesContext extendsInterfacesContext, GenericsRegistry generics) {
private List<RefType> convert(Java8Parser.ExtendsInterfacesContext extendsInterfacesContext, GenericsRegistry generics) {
if(extendsInterfacesContext == null)return new ArrayList<>();
return convert(extendsInterfacesContext.interfaceTypeList(), generics);
}

View File

@ -113,9 +113,7 @@ public class TypeGenerator {
if(referenceTypeContext.classOrInterfaceType() != null){
if(referenceTypeContext.classOrInterfaceType().classType_lfno_classOrInterfaceType()!= null){
Java8Parser.ClassType_lfno_classOrInterfaceTypeContext ctx = referenceTypeContext.classOrInterfaceType().classType_lfno_classOrInterfaceType();
//return convertTypeName(ctx.Identifier().toString(), ctx.typeArguments(),referenceTypeContext.getStart(), reg, generics);
if(ctx.typeArguments() != null)throw new NotImplementedException();
return convertTypeName(referenceTypeContext.getText(), null,referenceTypeContext.getStart(), reg, generics);
return convertTypeName(ctx.Identifier().toString(), ctx.typeArguments(),referenceTypeContext.getStart(), reg, generics);
}else{
throw new NotImplementedException();
}

View File

@ -13,6 +13,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@ -26,11 +27,11 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
private GenericDeclarationList genericClassParameters;
private RefType superClass;
protected boolean isInterface;
private List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces;
private List<RefType> implementedInterfaces;
private List<Constructor> constructors;
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
RefType superClass, Boolean isInterface, List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces, Token offset){
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
super(offset);
this.modifiers = modifiers;
this.name = name;
@ -101,4 +102,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public Collection<RefType> getSuperInterfaces() {
return implementedInterfaces;
}
}

View File

@ -11,6 +11,7 @@ public class Pair implements Serializable
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
private PairOperator eOperator = PairOperator.SMALLER;
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
{

View File

@ -94,7 +94,8 @@ public class MartelliMontanariUnify implements IUnify {
// SUBST - Rule
if(lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType);
termsList = termsList.stream().map(mgu::apply).collect(Collectors.toCollection(ArrayList::new));
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1;
continue;
}

View File

@ -25,12 +25,25 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
import java.io.FileWriter;
import java.io.IOException;
/**
* Implementation of the type inference rules.
* @author Florian Steurer
*
*/
public class RuleSet implements IRuleSet{
public class RuleSet implements IRuleSet{
FileWriter logFile;
RuleSet() {
super();
}
RuleSet(FileWriter logFile) {
this.logFile = logFile;
}
@Override
public Optional<UnifyPair> reduceUp(UnifyPair pair) {
@ -47,7 +60,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
// Rule is applicable, unpack the SuperType
return Optional.of(new UnifyPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -65,7 +78,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
// Rule is applicable, unpack the ExtendsType
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -83,7 +96,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
// Rule is applicable, unpack both sides
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -133,7 +146,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++)
result.add(new UnifyPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC));
result.add(new UnifyPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -184,7 +197,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++)
result.add(new UnifyPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC));
result.add(new UnifyPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -215,7 +228,7 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsType.getTypeParams();
for(int i = 0; i < lhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -236,19 +249,53 @@ public class RuleSet implements IRuleSet{
ReferenceType lhsSType = (ReferenceType) c;
ReferenceType rhsSType = (ReferenceType) d;
//try {
// logFile.write("PAIR Rules: " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size())
return Optional.empty();
UnifyType cFromFc = fc.getLeftHandedType(c.getName()).orElse(null);
//2018-02-23: liefert Vector<Vector<Integer>>: Das kann nicht sein.
//NOCHMAL UEBERPRUEFEN
//PL 18-02-09 Eingfuegt Anfang
//C und D koennen auch gleich sein.
if (c.getName().equals(d.getName())) {
Set<UnifyPair> result = new HashSet<>();
TypeParams rhsTypeParams = d.getTypeParams();
TypeParams lhsTypeParams = c.getTypeParams();
for(int rhsIdx = 0; rhsIdx < c.getTypeParams().size(); rhsIdx++)
result.add(new UnifyPair(lhsTypeParams.get(rhsIdx), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
//PL 18-02-09 Eingfuegt ENDE
//try {
// logFile.write("cFromFc: " + cFromFc);
// logFile.flush();
//}
//catch (IOException e) { }
if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders())
return Optional.empty();
UnifyType dFromFc = fc.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null);
//try {
// logFile.write("cFromFc: " + cFromFc);
// logFile.flush();
//}
//catch (IOException e) { }
if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size())
return Optional.empty();
//System.out.println("cFromFc: " + cFromFc);
//System.out.println("dFromFc: " + dFromFc);
int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams());
if(pi.length == 0)
@ -259,7 +306,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
result.add(new UnifyPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC));
result.add(new UnifyPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -314,7 +361,7 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsSType.getTypeParams();
TypeParams lhsTypeParams = lhsSType.getTypeParams();
for(int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT));
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -365,7 +412,7 @@ public class RuleSet implements IRuleSet{
if(!(pair.getRhsType() instanceof PlaceholderType))
return Optional.empty();
return Optional.of(new UnifyPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT));
return Optional.of(new UnifyPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -407,11 +454,19 @@ public class RuleSet implements IRuleSet{
TypeParams typeDParams = typeD.getTypeParams();
TypeParams typeDgenParams = typeDgen.getTypeParams();
//System.out.println("Pair: " +pair);
//System.out.println("typeD: " +typeD);
//System.out.println("typeDParams: " +typeDParams);
//System.out.println("typeDgen: " +typeD);
//System.out.println("typeDgenParams: " +typeDgenParams);
Unifier unif = Unifier.identity();
for(int i = 0; i < typeDParams.size(); i++)
for(int i = 0; i < typeDParams.size(); i++) {
//System.out.println("ADAPT" +typeDgenParams);
if (typeDgenParams.get(i) instanceof PlaceholderType)
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT));
else System.out.println("ERROR");
}
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -457,7 +512,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC));
return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -509,7 +564,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i));
return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC));
return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
}
/**
@ -581,8 +636,8 @@ public class RuleSet implements IRuleSet{
&& typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
&& !rhsType.getTypeParams().occurs(lhsType)) {
Unifier uni = new Unifier(lhsType, rhsType);
result = result.stream().map(uni::apply).collect(Collectors.toCollection(ArrayList::new));
result1 = result1.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new));
result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
applied = true;
}
@ -602,7 +657,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType))
return Optional.empty();
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -615,7 +670,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType))
return Optional.empty();
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -628,7 +683,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType))
return Optional.empty();
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT));
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -641,9 +696,11 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType))
return Optional.empty();
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC));
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)
@ -670,6 +727,7 @@ public class RuleSet implements IRuleSet{
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)
@ -686,7 +744,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty();
}
*/
@Override
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) {
if((pair.getPairOp() != PairOperator.SMALLERDOT)
@ -709,9 +767,9 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<UnifyPair>();
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT));
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
for(int i = 1; i < funNLhsType.getTypeParams().size(); i++)
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT));
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -735,10 +793,10 @@ public class RuleSet implements IRuleSet{
for(int i = 0; i < freshPlaceholders.length; i++)
freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), freshPlaceholders[0], PairOperator.SMALLERDOT));
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), freshPlaceholders[0], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
for(int i = 1; i < funNLhsType.getTypeParams().size(); i++)
result.add(new UnifyPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT));
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT));
result.add(new UnifyPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -762,10 +820,10 @@ public class RuleSet implements IRuleSet{
for(int i = 0; i < freshPlaceholders.length; i++)
freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(freshPlaceholders[0], funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT));
result.add(new UnifyPair(freshPlaceholders[0], funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
for(int i = 1; i < funNRhsType.getTypeParams().size(); i++)
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT));
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT));
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
@ -780,7 +838,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType))
return Optional.empty();
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT));
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
}
@Override
@ -799,11 +857,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>();
if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else {
UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT));
result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT));
result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
return Optional.of(result);
@ -825,11 +883,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>();
if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT));
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else {
UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT));
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT));
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
return Optional.of(result);

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
@ -7,16 +8,16 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class TypeUnify {
public Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, true);
public Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, true, logFile);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join();
return res;
}
public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false);
public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile);
Set<Set<UnifyPair>> res = unifyTask.compute();
return res;
}

View File

@ -3,7 +3,9 @@ package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
@ -11,7 +13,9 @@ import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.RecursiveTask;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
@ -25,16 +29,27 @@ 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.OrderingUnifyPair;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.google.common.collect.Ordering;
/**
* Implementation of the type unification algorithm
* @author Florian Steurer
*/
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
private static final long serialVersionUID = 1L;
private static int i = 0;
private boolean printtag = false;
public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/";
FileWriter logFile;
/**
* The implementation of setOps that will be used during the unification
@ -49,23 +64,80 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/**
* The implementation of the rules that will be used during the unification.
*/
protected IRuleSet rules = new RuleSet();
protected IRuleSet rules;
protected Set<UnifyPair> eq;
protected IFiniteClosure fc;
protected Ordering<Set<UnifyPair>> oup;
protected boolean parallel;
public TypeUnifyTask(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
public TypeUnifyTask() {
rules = new RuleSet();
}
public TypeUnifyTask(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel, FileWriter logFile) {
this.eq = eq;
this.fc = fc;
this.oup = new OrderingUnifyPair(fc);
this.parallel = parallel;
this.logFile = logFile;
rules = new RuleSet(logFile);
}
/**
* Vererbt alle Variancen
* @param eq The set of constraints
*/
private void varianceInheritance(Set<UnifyPair> eq) {
Set<PlaceholderType> phSet = eq.stream().map(x -> {
Set<PlaceholderType> pair = new HashSet<>();
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType());
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType());
return pair;
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;});
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0));
while(!phSetVariance.isEmpty()) {
PlaceholderType a = phSetVariance.remove(0);
HashMap<PlaceholderType,Integer> ht = new HashMap<>();
ht.put(a, a.getVariance());
eq.stream().forEach(x -> {
x.getLhsType().accept(new inheritVariance(), ht);
if (x.getLhsType() instanceof PlaceholderType
&& ((PlaceholderType)x.getLhsType()).equals(a)//) {
//((PlaceholderType)x.getLhsType()).setVariance(a.getVariance());
//if
&& x.getRhsType() instanceof PlaceholderType
&& ((PlaceholderType)x.getRhsType()).getVariance() == 0) {
((PlaceholderType)x.getRhsType()).setVariance(a.getVariance());
phSetVariance.add((PlaceholderType)x.getRhsType());
//}
};
});
eq.stream().forEach(x -> {
x.getRhsType().accept(new inheritVariance(), ht);
if (x.getRhsType() instanceof PlaceholderType
&& ((PlaceholderType)x.getRhsType()).equals(a)//) {
//((PlaceholderType)x.getRhsType()).setVariance(a.getVariance());
//if
&& x.getLhsType() instanceof PlaceholderType
&& ((PlaceholderType)x.getLhsType()).getVariance() == 0) {
((PlaceholderType)x.getLhsType()).setVariance(a.getVariance());
phSetVariance.add((PlaceholderType)x.getLhsType());
//}
};
});
}
}
@Override
protected Set<Set<UnifyPair>> compute() {
return unify(eq, fc, parallel);
Set<Set<UnifyPair>> res = unify(eq, fc, parallel);
if (isUndefinedPairSetSet(res)) { return new HashSet<>(); }
else return res;
}
/**
@ -74,11 +146,30 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* @param fc The finite closure
* @return The set of all principal type unifiers
*/
protected Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
protected Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
/*
* Step 1: Repeated application of reduce, adapt, erase, swap
*/
//System.out.println("Unifikation: " + eq);
writeLog("Unifikation: " + eq.toString());
//eq = eq.stream().map(x -> {x.setVariance((byte)-1); return x;}).collect(Collectors.toCollection(HashSet::new));
/*
* Variancen auf alle Gleichungen vererben
*/
varianceInheritance(eq);
/*
* ? extends ? extends Theta rausfiltern
*/
Set<UnifyPair> doubleExt = eq.stream().filter(x -> (x.doubleExtended())).map(x -> { x.setUndefinedPair(); return x;})
.collect(Collectors.toCollection(HashSet::new));
if (doubleExt.size() > 0) {
Set<Set<UnifyPair>> ret = new HashSet<>();
ret.add(doubleExt);
return ret;
}
Set<UnifyPair> eq0 = applyTypeUnificationRules(eq, fc);
/*
@ -99,7 +190,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// cartesian product of the sets created by pattern matching.
List<Set<Set<UnifyPair>>> topLevelSets = new ArrayList<>();
System.out.println(eq2s);
//System.out.println(eq2s);
if(eq1s.size() != 0) { // Do not add empty sets or the cartesian product will always be empty.
Set<Set<UnifyPair>> wrap = new HashSet<>();
@ -122,22 +213,33 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Sets that originate from pair pattern matching
// Sets of the "second level"
Set<UnifyPair> undefinedPairs = new HashSet<>();
if (printtag) System.out.println("eq2s " + eq2s);
//writeLog("BufferSet: " + bufferSet.toString()+"\n");
Set<Set<Set<Set<UnifyPair>>>> secondLevelSets = calculatePairSets(eq2s, fc, undefinedPairs);
//PL 2017-09-20: Im calculatePairSets wird möglicherweise O .< java.lang.Integer
//nicht ausgewertet Faculty Beispiel im 1. Schritt
//PL 2017-10-03 geloest, muesste noch mit FCs mit kleineren
//Typen getestet werden.
if (printtag) System.out.println("secondLevelSets:" +secondLevelSets);
// If pairs occured that did not match one of the cartesian product cases,
// those pairs are contradictory and the unification is impossible.
if(!undefinedPairs.isEmpty())
return new HashSet<>();
if(!undefinedPairs.isEmpty()) {
for (UnifyPair up : undefinedPairs) {
writeLog("UndefinedPairs; " + up);
writeLog("BasePair; " + up.getBasePair());
}
Set<Set<UnifyPair>> error = new HashSet<>();
undefinedPairs = undefinedPairs.stream().map(x -> { x.setUndefinedPair(); return x;}).collect(Collectors.toCollection(HashSet::new));
error.add(undefinedPairs);
return error;
}
/* Up to here, no cartesian products are calculated.
* filters for pairs and sets can be applied here */
// Sub cartesian products of the second level (pattern matched) sets
// Alternative: Sub cartesian products of the second level (pattern matched) sets
// "the big (x)"
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
/* for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
//System.out.println("secondLevelSet "+secondLevelSet.size());
List<Set<Set<UnifyPair>>> secondLevelSetList = new ArrayList<>(secondLevelSet);
Set<List<Set<UnifyPair>>> cartResult = setOps.cartesianProduct(secondLevelSetList);
@ -153,62 +255,108 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
flat1.addAll(s1);
flat.add(flat1);
}
topLevelSets.add(flat);
//topLevelSets.add(flat);
}
*/
//Alternative KEIN KARTESISCHES PRODUKT der secondlevel Ebene bilden
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
for (Set<Set<UnifyPair>> secondlevelelem : secondLevelSet) {
topLevelSets.add(secondlevelelem);
}
}
//System.out.println(topLevelSets);
//System.out.println();
//Aufruf von computeCartesianRecursive ANFANG
return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, fc, parallel);
}
Set<Set<UnifyPair>> unify2(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
//Aufruf von computeCartesianRecursive ENDE
//keine Ahnung woher das kommt
//Set<Set<UnifyPair>> setToFlatten = topLevelSets.stream().map(x -> x.iterator().next()).collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
// Cartesian product over all (up to 10) top level sets
Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets)
.stream().map(x -> new HashSet<>(x))
.collect(Collectors.toCollection(HashSet::new));
//Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets)
// .stream().map(x -> new HashSet<>(x))
// .collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
Set<TypeUnifyTask> forks = new HashSet<>();
for(Set<Set<UnifyPair>> setToFlatten : eqPrimeSet) {
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
//for(Set<Set<UnifyPair>> setToFlatten : eqPrimeSet) {
// Flatten the cartesian product
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<UnifyPair> eqPrime = new HashSet<>();
setToFlatten.stream().forEach(x -> eqPrime.addAll(x));
/*
* Step 5: Substitution
*/
System.out.println("vor Subst: " + eqPrime);
//System.out.println("vor Subst: " + eqPrime);
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
/*
* Step 6 a) Restart (fork) for pairs where subst was applied
*/
if(parallel) {
if //(eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch
(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
if (eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch
//(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
//Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt.
eqPrimePrimeSet.add(eqPrime);
else if(eqPrimePrime.isPresent()) {
System.out.println("nextStep: " + eqPrimePrime.get());
TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true);
//System.out.println("nextStep: " + eqPrimePrime.get());
TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true, logFile);
forks.add(fork);
fork.fork();
}
else {
System.out.println("nextStep: " + eqPrime);
TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true);
//System.out.println("nextStep: " + eqPrime);
TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true, logFile);
forks.add(fork);
fork.fork();
}
}
else { // sequentiell (Step 6b is included)
if //(eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch
(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
if (printtag) System.out.println("nextStep: " + eqPrimePrime);
if (eqPrime.equals(eq)) { //PL 2017-09-29 auskommentiert und durch
//(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
//Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt.
try {
if (isSolvedForm(eqPrime)) {
logFile.write(eqPrime.toString()+"\n");
logFile.flush();
}
}
catch (IOException e) { }
eqPrimePrimeSet.add(eqPrime);
else if(eqPrimePrime.isPresent())
eqPrimePrimeSet.addAll(unify(eqPrimePrime.get(), fc, false));
else
eqPrimePrimeSet.addAll(unify(eqPrime, fc, false));
}
else if(eqPrimePrime.isPresent()) {
Set<Set<UnifyPair>> unifyres = unify(eqPrimePrime.get(), fc, false);
eqPrimePrimeSet.addAll(unifyres);
}
else {
Set<Set<UnifyPair>> unifyres = unify(eqPrime, fc, false);
eqPrimePrimeSet.addAll(unifyres);
}
}
}
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
//}
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
/*
* Step 6 b) Build the union over everything.
@ -221,10 +369,227 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/*
* Step 7: Filter empty sets;
*/
return eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x)).collect(Collectors.toCollection(HashSet::new));
eqPrimePrimeSet = eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x) || this.isUndefinedPairSet(x)).collect(Collectors.toCollection(HashSet::new));
if (!eqPrimePrimeSet.isEmpty() && !isUndefinedPairSetSet(eqPrimePrimeSet))
writeLog("Result1 " + eqPrimePrimeSet.toString());
return eqPrimePrimeSet;
}
Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
//ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets);
fstElems.addAll(topLevelSets.stream()
.filter(x -> x.size()==1)
.map(y -> y.stream().findFirst().get())
.collect(Collectors.toCollection(HashSet::new)));
ArrayList<Set<Set<UnifyPair>>> remainingSets = topLevelSets.stream()
.filter(x -> x.size()>1)
.collect(Collectors.toCollection(ArrayList::new));
if (remainingSets.isEmpty()) {//Alle Elemente sind 1-elementig
Set<Set<UnifyPair>> result = unify2(fstElems, eq, fc, parallel);
return result;
}
Set<Set<UnifyPair>> nextSet = remainingSets.remove(0);
writeLog("nextSet: " + nextSet.toString());
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
try {
//List<Set<UnifyPair>>
//nextSetasList = oup.sortedCopy(nextSet);//new ArrayList<>(nextSet);
}
catch (java.lang.IllegalArgumentException e) {
System.out.print("");
}
Set<Set<UnifyPair>> result = new HashSet<>();
int variance = 0;
Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> y.getLhsType() instanceof PlaceholderType)
.filter(z -> ((PlaceholderType)z.getLhsType()).getVariance() != 0)
.map(c -> ((PlaceholderType)c.getLhsType()).getVariance())
.reduce((a,b)-> {if (a==b) return a; else return 0; }))
.filter(d -> d.isPresent())
.map(e -> e.get())
.findAny();
if (xi.isPresent()) {
variance = xi.get();
}
if (variance == 1 && nextSetasList.size() > 1) {
List<Set<UnifyPair>> al = new ArrayList<>(nextSetasList.size());
for (int ii = 0; ii < nextSetasList.size();ii++) {
al.add(0,nextSetasList.get(ii));
}
nextSetasList = al;
}
//Set<UnifyPair> a = nextSetasListIt.next();
/*if (nextSetasList.size()>1) {zu loeschen
if (nextSetasList.iterator().next().iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
if (variance == 1) {
a_next = oup.max(nextSetasList.iterator());
}
else if (variance == -1) {
a_next = oup.min(nextSetasList.iterator());
}
else if (variance == 0) {
a_next = nextSetasList.iterator().next();
}
}
else {
a_next = nextSetasList.iterator().next();
}
*/
if (!nextSetasList.iterator().hasNext())
System.out.print("");
if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
System.out.print("");
while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) {
Set<UnifyPair> a = null;
if (variance == 1) {
a = oup.max(nextSetasList.iterator());
nextSetasList.remove(a);
}
else if (variance == -1) {
a = oup.min(nextSetasList.iterator());
nextSetasList.remove(a);
}
else if (variance == 0) {
a = nextSetasList.remove(0);
}
//writeLog("nextSet: " + nextSetasList.toString()+ "\n");
//nextSetasList.remove(a);
/* zu loeschen
if (nextSetasList.size() > 0) {
if (nextSetasList.size()>1) {
if (variance == 1) {
a_next = oup.max(nextSetasList.iterator());
}
else if (variance == -1) {
a_next = oup.min(nextSetasList.iterator());
}
else {
a_next = nextSetasList.iterator().next();
}
}
else {
a_next = nextSetasList.iterator().next();
}
}
*/
//PL 2018-03-01
//TODO: 1. Maximum und Minimum unterscheiden
//TODO: 2. compare noch für alle Elmemente die nicht X =. ty sind erweitern
//for(Set<UnifyPair> a : newSet) {
i++;
Set<Set<UnifyPair>> elems = new HashSet<Set<UnifyPair>>(fstElems);
elems.add(a);
//if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt
Set<Set<UnifyPair>> res = unify2(elems, eq, fc, parallel);
if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
result = res;
}
else {
if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result))
|| (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result))
|| result.isEmpty()) {
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
result.addAll(res);
}
//else {
//wenn Korrekte Ergebnisse da und Feherfälle dazukommen Fehlerfälle ignorieren
// if (isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) {
// result = result;
// }
//}
}
//}
//else {//duerfte gar nicht mehr vorkommen PL 2018-04-03
//result.addAll(computeCartesianRecursive(elems, remainingSets, eq, fc, parallel));
//}
if (!result.isEmpty() && !isUndefinedPairSetSet(res)) {
if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
System.out.print("");
Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<Set<UnifyPair>>(nextSetasList).iterator();
if (variance == 1) {
System.out.println("");
while (nextSetasListIt.hasNext()) {
Set<UnifyPair> a_next = nextSetasListIt.next();
if (a.equals(a_next) ||
(oup.compare(a, a_next) == 1)) {
nextSetasList.remove(a_next);
}
}
}
else { if (variance == -1) {
System.out.println("");
while (nextSetasListIt.hasNext()) {
Set<UnifyPair> a_next = nextSetasListIt.next();
if (a.equals(a_next) ||
(oup.compare(a, a_next) == -1)) {
nextSetasList.remove(0);
}
}
}
else if (variance == 0) {
break;
}
}
}
if (isUndefinedPairSetSet(res)) {
Set<UnifyPair> abhSubst = res.stream()
.map(b ->
b.stream()
.map(x -> x.getAllSubstitutions())
.reduce((y,z) -> { y.addAll(z); return y;}).get())
.reduce((y,z) -> { y.addAll(z); return y;}).get();
Set<UnifyPair> b = a;//effective final a
Set<UnifyPair> durchschnitt = abhSubst.stream()
.filter(x -> b.contains(x))
//.filter(y -> abhSubst.contains(y))
.collect(Collectors.toCollection(HashSet::new));
Set<PlaceholderType> vars = durchschnitt.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
int len = nextSetasList.size();
nextSetasList = nextSetasList.stream().filter(x -> {
//Boolean ret = false;
//for (PlaceholderType var : vars) {
// ret = ret || x.stream().map(b -> b.getLhsType().equals(var)).reduce((c,d) -> c || d).get();
//}
return (!x.containsAll(durchschnitt));
}).collect(Collectors.toCollection(ArrayList::new));
writeLog("abhSubst: " + abhSubst.toString());
writeLog("a: " + a.toString());
writeLog("Durchschnitt: " + durchschnitt.toString());
writeLog("nextSet: " + nextSet.toString());
writeLog("nextSetasList: " + nextSetasList.toString());
writeLog("Number erased Elements (undef): " + (len - nextSetasList.size()));
System.out.println("");
}
//if (nextSetasList.size() == 0 && isUndefinedPairSetSet(result) && nextSet.size() > 1) {
// return result;
//}
//else {
// result.removeIf(y -> isUndefinedPairSet(y));
//}
//else result.stream().filter(y -> !isUndefinedPairSet(y));
}
return result;
}
protected boolean isUndefinedPairSet(Set<UnifyPair> s) {
Boolean ret = s.stream().map(x -> x.isUndefinedPair()).reduce(true, (x,y)-> (x && y));
return ret;
}
protected boolean isUndefinedPairSetSet(Set<Set<UnifyPair>> s) {
if (s.size() >= 1) {
Boolean ret = s.stream(). map(x -> isUndefinedPairSet(x)).reduce(true, (x,y)-> (x && y));
return ret;
}
return false;
}
/**
* Checks whether a set of pairs is in solved form.
* @param eqPrimePrime The set of pair
@ -250,7 +615,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* This is step one of the unification algorithm.
* @return The set of pairs that results from repeated application of the inference rules.
*/
protected Set<UnifyPair> applyTypeUnificationRules(Set<UnifyPair> eq, IFiniteClosure fc) {
public Set<UnifyPair> applyTypeUnificationRules(Set<UnifyPair> eq, IFiniteClosure fc) {
/*
* Rule Application Strategy:
@ -287,9 +652,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
opt = opt.isPresent() ? opt : rules.reduceWildcardLowRight(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair);
//PL 2018-03-06 auskommentiert muesste falsch sein vgl. JAVA_BSP/Wildcard6.java
//opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair);
//opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair);
//opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair);
// Reduce TPH
opt = opt.isPresent() ? opt : rules.reduceTph(pair);
@ -301,6 +667,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}
// Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq
//try {
// logFile.write("PAIR1 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
Optional<Set<UnifyPair>> optSet = rules.reduce1(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.reduce2(pair);
optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair, fc);
@ -324,6 +696,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}
// Adapt, AdaptExt, AdaptSup
//try {
// logFile.write("PAIR2 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
opt = rules.adapt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptExt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptSup(pair, fc);
@ -385,26 +762,66 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Init all 8 cases
for(int i = 0; i < 8; i++)
result.add(new HashSet<>());
for(UnifyPair pair : eq2s) {
ArrayList<UnifyPair> eq2sprime = new ArrayList<>(eq2s);
Iterator<UnifyPair> eq2sprimeit = eq2sprime.iterator();
ArrayList<UnifyPair> eq2sAsList = new ArrayList<>();
while(eq2sprimeit.hasNext()) {// alle mit Variance != 0 nach vorne schieben
UnifyPair up = eq2sprimeit.next();
if ((up.getLhsType() instanceof PlaceholderType && ((PlaceholderType)up.getLhsType()).getVariance() != 0)
|| (up.getRhsType() instanceof PlaceholderType && ((PlaceholderType)up.getRhsType()).getVariance() != 0)) {
eq2sAsList.add(up);
eq2s.remove(up);
}
}
eq2sAsList.addAll(eq2s);
Boolean first = true;
for(UnifyPair pair : eq2sAsList) {
PairOperator pairOp = pair.getPairOp();
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
// Case 1: (a <. Theta')
if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) {
System.out.println(pair);
Set<Set<UnifyPair>> x1 = unifyCase1((PlaceholderType) pair.getLhsType(), pair.getRhsType(), fc);
System.out.println(x1);
result.get(0).add(x1);
//System.out.println(pair);
if (first) { //writeLog(pair.toString()+"\n");
Set<Set<UnifyPair>> x1 = unifyCase1(pair, fc);
//System.out.println(x1);
result.get(0).add(x1);
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(0).add(s2);
}
}
// Case 2: (a <.? ? ext Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType)
result.get(1).add(unifyCase2((PlaceholderType) pair.getLhsType(), (ExtendsType) pair.getRhsType(), fc));
if (first) { //writeLog(pair.toString()+"\n");
result.get(1).add(unifyCase2(pair, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(1).add(s2);
}
// Case 3: (a <.? ? sup Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType)
result.get(2).add(unifyCase3((PlaceholderType) lhsType, (SuperType) rhsType, fc));
if (first) { //writeLog(pair.toString()+"\n");
result.get(2).add(unifyCase3(pair, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(2).add(s2);
}
// Case 4 was replaced by an inference rule
// Case 4: (a <.? Theta')
@ -413,7 +830,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Case 5: (Theta <. a)
else if(pairOp == PairOperator.SMALLERDOT && rhsType instanceof PlaceholderType)
result.get(4).add(unifyCase5(lhsType, (PlaceholderType) rhsType, fc));
if (first) { //writeLog(pair.toString()+"\n");
if (rhsType.getName().equals("A"))
System.out.println();
result.get(4).add(unifyCase5(pair, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(4).add(s2);
}
// Case 6 was replaced by an inference rule.
// Case 6: (? ext Theta <.? a)
@ -427,7 +855,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Case 8: (Theta <.? a)
else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType)
result.get(7).add(unifyCase8(lhsType, (PlaceholderType) rhsType, fc));
if (first) { //writeLog(pair.toString()+"\n");
result.get(7).add(
unifyCase8(pair, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(7).add(s2);
}
// Case unknown: If a pair fits no other case, then the type unification has failed.
// Through application of the rules, every pair should have one of the above forms.
// Pairs that do not have one of the aboves form are contradictory.
@ -436,6 +874,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
undefined.add(pair);
break;
}
first = false;
}
// Filter empty sets or sets that only contain an empty set.
@ -443,10 +882,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
.filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new));
}
//TODO: Wenn Theta' nicht im FC muss ein Fehler produziert werden PL 18-04-20
/**
* Cartesian product Case 1: (a <. Theta')
*/
protected Set<Set<UnifyPair>> unifyCase1(PlaceholderType a, UnifyType thetaPrime, IFiniteClosure fc) {
protected Set<Set<UnifyPair>> unifyCase1(UnifyPair pair, IFiniteClosure fc) {
PlaceholderType a = (PlaceholderType)pair.getLhsType();
UnifyType thetaPrime = pair.getRhsType();
byte variance = pair.getVariance();
if (a.getName().equals("D")) {
System.out.print("");
}
Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = thetaPrime.getTypeParams().size() > 0;
@ -462,7 +908,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//cs.add(thetaPrime);
//PL 18-02-06 entfernt
for(UnifyType c : cs) {
//cs muessen fresh Typvars gesetzt werden PL 2018-03-18
Set<UnifyType> csPHRenamed = cs.stream().map(x -> {
BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;};
HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream()
.reduce(new HashMap<PlaceholderType,PlaceholderType>(),
(aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner);
return x.accept(new freshPlaceholder(), hm);
}).collect(Collectors.toCollection(HashSet::new));
for(UnifyType c : csPHRenamed) {
//PL 18-02-05 getChildren durch smaller ersetzt in getChildren werden die Varianlen nicht ersetzt.
Set<UnifyType> thetaQs = fc.smaller(c).stream().collect(Collectors.toCollection(HashSet::new));
//Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new));
@ -489,24 +945,36 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}
for(UnifyType tqp : thetaQPrimes) {
//System.out.println(tqp.toString());
//i++;
//System.out.println(i);
//if (i == 62)
// System.out.println(tqp.toString());
Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime);
if (!opt.isPresent())
if (!opt.isPresent()) {
continue;
}
Unifier unifier = opt.get();
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams());
Set<UnifyPair> substitutionSet = new HashSet<>();
for (Entry<PlaceholderType, UnifyType> sigma : unifier)
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
for (Entry<PlaceholderType, UnifyType> sigma : unifier) {
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT,
//TODO: nochmals ueberlegen ob hier pair.getSubstitution() korrekt ist, oder ob leere Menge hin müsste
//alle folgenden New UnifyPair ebenfalls ueberpruefen PL 2018-04-19
pair.getSubstitution(), pair));
}
//List<UnifyType> freshTphs = new ArrayList<>(); PL 18-02-06 in die For-Schleife verschoben
for (UnifyType tq : thetaQs) {
Set<UnifyType> smaller = fc.smaller(unifier.apply(tq));
//eingefuegt PL 2018-03-29 Anfang ? ext. theta hinzufuegen
if (a.isWildcardable()) {
Set<UnifyType> smaller_ext = smaller.stream().filter(x -> !(x instanceof ExtendsType) && !(x instanceof SuperType))
.map(x -> {
//BinaryOperator<HashMap<PlaceholderType,PlaceholderType>> combiner = (aa,b) -> { aa.putAll(b); return aa;}; //Variablenumbenennung rausgenommen
//HashMap<PlaceholderType,PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream() //Variablen muessen wahrscheinlich erhalten bleiben
// .reduce(new HashMap<PlaceholderType,PlaceholderType>(),
// (aa, b)-> { aa.put(b,PlaceholderType.freshPlaceholder()); return aa; }, combiner);
return new ExtendsType (x);})//.accept(new freshPlaceholder(), hm));}
.collect(Collectors.toCollection(HashSet::new));
smaller.addAll(smaller_ext);
}
//eingefuegt PL 2018-03-29 Ende ? ext. theta hinzufuegen
for(UnifyType theta : smaller) {
List<UnifyType> freshTphs = new ArrayList<>();
Set<UnifyPair> resultPrime = new HashSet<>();
@ -514,15 +982,27 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
for(int i = 0; !allGen && i < theta.getTypeParams().size(); i++) {
if(freshTphs.size()-1 < i)
freshTphs.add(PlaceholderType.freshPlaceholder());
resultPrime.add(new UnifyPair(freshTphs.get(i), theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC));
resultPrime.add(new UnifyPair(freshTphs.get(i), theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair));
}
if(allGen)
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
else
resultPrime.add(new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT));
if(allGen) {
UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
Iterator<UnifyType> upit = up.getRhsType().getTypeParams().iterator();
while (upit.hasNext()) ((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);
Iterator<UnifyType> upit = up.getRhsType().getTypeParams().iterator();
while (upit.hasNext()) ((PlaceholderType)upit.next()).setVariance(a.getVariance());
resultPrime.add(up);
}
resultPrime.addAll(substitutionSet);
//writeLog("Substitution: " + substitutionSet.toString());
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog("Result: " + resultPrime.toString());
//writeLog("MAX: " + oup.max(resultPrime.iterator()).toString());
}
}
@ -535,40 +1015,51 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/**
* Cartesian Product Case 2: (a <.? ? ext Theta')
*/
private Set<Set<UnifyPair>> unifyCase2(PlaceholderType a, ExtendsType extThetaPrime, IFiniteClosure fc) {
private Set<Set<UnifyPair>> unifyCase2(UnifyPair pair, IFiniteClosure fc) {
PlaceholderType a = (PlaceholderType) pair.getLhsType();
ExtendsType extThetaPrime = (ExtendsType) pair.getRhsType();
byte variance = pair.getVariance();
Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType extAPrime = new ExtendsType(aPrime);
UnifyType thetaPrime = extThetaPrime.getExtendedType();
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, thetaPrime, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(a, thetaPrime, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
result.add(resultPrime);
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(aPrime, thetaPrime, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(aPrime, thetaPrime, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog("Result: " + resultPrime.toString());
return result;
}
/**
* Cartesian Product Case 3: (a <.? ? sup Theta')
*/
private Set<Set<UnifyPair>> unifyCase3(PlaceholderType a, SuperType subThetaPrime, IFiniteClosure fc) {
private Set<Set<UnifyPair>> unifyCase3(UnifyPair pair, IFiniteClosure fc) {
PlaceholderType a = (PlaceholderType) pair.getLhsType();
SuperType subThetaPrime = (SuperType) pair.getRhsType();
byte variance = pair.getVariance();
Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType supAPrime = new SuperType(aPrime);
UnifyType thetaPrime = subThetaPrime.getSuperedType();
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(thetaPrime, aPrime, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(thetaPrime, aPrime, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
return result;
}
@ -576,7 +1067,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/**
* Cartesian Product Case 5: (Theta <. a)
*/
private Set<Set<UnifyPair>> unifyCase5(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
private Set<Set<UnifyPair>> unifyCase5(UnifyPair pair, IFiniteClosure fc) {
UnifyType theta = pair.getLhsType();
PlaceholderType a = (PlaceholderType) pair.getRhsType();
byte variance = pair.getVariance();
Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = theta.getTypeParams().size() > 0;
@ -592,14 +1086,16 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
UnifyType[] freshTphs = new UnifyType[thetaS.getTypeParams().size()];
for(int i = 0; !allGen && i < freshTphs.length; i++) {
freshTphs[i] = PlaceholderType.freshPlaceholder();
resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC));
resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair));
}
if(allGen)
resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
else
resultPrime.add(new UnifyPair(a, thetaS.setTypeParams(new TypeParams(freshTphs)), PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(a, thetaS.setTypeParams(new TypeParams(freshTphs)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
}
return result;
@ -608,23 +1104,30 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/**
* Cartesian Product Case 8: (Theta <.? a)
*/
private Set<Set<UnifyPair>> unifyCase8(UnifyType theta, PlaceholderType a, IFiniteClosure fc) {
private Set<Set<UnifyPair>> unifyCase8(UnifyPair pair, IFiniteClosure fc) {
UnifyType theta = pair.getLhsType();
PlaceholderType a = (PlaceholderType) pair.getRhsType();
byte variance = pair.getVariance();
Set<Set<UnifyPair>> result = new HashSet<>();
//for(UnifyType thetaS : fc.grArg(theta)) {
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
result.add(resultPrime);
//writeLog(resultPrime.toString());
UnifyType freshTph = PlaceholderType.freshPlaceholder();
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(freshTph, theta, PairOperator.SMALLERDOT));
resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(freshTph, theta, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
//}
return result;
@ -662,4 +1165,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
permuteParams(candidates, idx+1, result, current);
}
}
void writeLog(String str) {
try {
logFile.write(str+"\n");
logFile.flush();
}
catch (IOException e) { }
}
}

View File

@ -0,0 +1,19 @@
package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
public class distributeVariance extends visitUnifyTypeVisitor<Integer> {
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
else if (phty.getVariance() != ht) {
phty.setVariance(0);
}
}
return phty;
}
}

View File

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

View File

@ -0,0 +1,18 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.HashMap;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
public class inheritVariance extends visitUnifyTypeVisitor<HashMap<PlaceholderType,Integer>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType,Integer> ht) {
if (ht.containsKey(phty)) {
if (phty.getVariance() == 0) {
phty.setVariance(ht.get(phty));
}
}
return phty;
}
}

View File

@ -5,6 +5,7 @@ import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
@ -60,5 +61,7 @@ public interface IFiniteClosure {
public Optional<UnifyType> getLeftHandedType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName);
public Set<UnifyType> getAllTypesByName(String typeName);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop);
}

View File

@ -13,23 +13,17 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
/**
* Match
* @author Martin Pluemicke
* abgeleitet aus IUnify.java
*/
public interface IMatch {
/**
* Finds the most general unifier sigma of the set {t1,...,tn} so that
* sigma(t1) = sigma(t2) = ... = 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.
* 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
* @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);
/**
* Finds the most general unifier sigma of the set {t1,...,tn} so that
* sigma(t1) = sigma(t2) = ... = 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.
*/
}

View File

@ -27,9 +27,13 @@ public interface IRuleSet {
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
public 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);
*/
/*
* Additional Rules which replace cases of the cartesian product

View File

@ -15,16 +15,16 @@ import de.dhbwstuttgart.typeinference.unify.model.Unifier;
public interface IUnify {
/**
* Finds the most general unifier sigma of the set {t1,...,tn} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn).
* 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);
/**
* Finds the most general unifier sigma of the set {t1,...,tn} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn).
* 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.
*/

View File

@ -0,0 +1,23 @@
package de.dhbwstuttgart.typeinference.unify.interfaces;
import java.util.HashMap;
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;
public interface UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht);
public PlaceholderType visit(PlaceholderType phty, T ht);
public FunNType visit(FunNType funnty, T ht);
public SuperType visit(SuperType suty, T ht);
public ExtendsType visit(ExtendsType extty, T ht);
}

View File

@ -2,21 +2,30 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* An extends wildcard type "? extends T".
*/
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) {
super("? extends " + extendedType.getName(), extendedType);
super("? extends " + extendedType.getName(), extendedType);
if (extendedType instanceof ExtendsType) {
System.out.print("");
}
}
/**

View File

@ -8,11 +8,14 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
//PL 18-02-05 Unifier durch Matcher ersetzt
//mus greater noch erstezt werden
import com.google.common.collect.Ordering;
//PL 18-02-05/18-04-05 Unifier durch Matcher ersetzt
//muss greater noch ersetzt werden ja erledigt 18--04-05
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
import de.dhbwstuttgart.typeinference.unify.Match;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
@ -20,7 +23,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
* The finite closure for the type unification
* @author Florian Steurer
*/
public class FiniteClosure implements IFiniteClosure {
public class FiniteClosure extends Ordering<UnifyType> implements IFiniteClosure {
/**
* A map that maps every type to the node in the inheritance graph that contains that type.
@ -193,7 +196,9 @@ public class FiniteClosure implements IFiniteClosure {
protected Set<UnifyType> computeGreater(Set<UnifyType> types) {
HashSet<UnifyType> result = new HashSet<>();
IUnify unify = new MartelliMontanariUnify();
//PL 18-04-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify();
Match match = new Match();
for(UnifyType t : types) {
@ -215,7 +220,11 @@ public class FiniteClosure implements IFiniteClosure {
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent();
Optional<Unifier> optSigma = unify.unify(theta1, t);
//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;
@ -369,7 +378,7 @@ public class FiniteClosure implements IFiniteClosure {
return Optional.empty();
for(UnifyPair pair : pairs)
if(pair.getLhsType().getName().equals(typeName))
if(pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
return Optional.of(pair.getLhsType());
return Optional.empty();
@ -430,4 +439,33 @@ public class FiniteClosure implements IFiniteClosure {
public String toString(){
return this.inheritanceGraph.toString();
}
public int compare (UnifyType left, UnifyType right) {
return compare(left, right, PairOperator.SMALLERDOT);
}
public int compare (UnifyType left, UnifyType right, PairOperator pairop) {
if ((left instanceof ExtendsType && right instanceof ReferenceType)
|| (right instanceof ExtendsType && left instanceof ReferenceType))
System.out.println("");
UnifyPair up = new UnifyPair(left, right, pairop);
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, this);
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
if (smallerLen == 0) return -1;
else {
up = new UnifyPair(right, left, pairop);
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, this);
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
if (greaterLen == 0) return 1;
else return 0;
}
}
}

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* A real function type in java.
@ -10,6 +12,10 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
*/
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.
*/

View File

@ -0,0 +1,228 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Optional;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Ordering;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
public class OrderingUnifyPair extends Ordering<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) {
if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC);
}
else {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT);
}
}
/*
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);
}
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);
}
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> left, Set<UnifyPair> right) {
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 und 3
//if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) {
// System.out.print("");
//}
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return 1;
}
//Fall 2 und 3
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && 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)
lefteq.removeIf(x -> !(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.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;
if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
subst = leftlewc.stream().map(x -> new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
else {
subst = leftlewc.stream().map(x -> 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()));
lseq = uni.apply(lseq);
}
else {
Set<UnifyPair> subst;
if (rightlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
subst = rightlewc.stream().map(x -> new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
else {
subst = rightlewc.stream().map(x -> 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

@ -0,0 +1,21 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.Optional;
public class Pair<T, T1> {
private final T key;
private final T1 value;
public Pair(T a, T1 b) {
this.value = b;
this.key = a;
}
public Optional<T1> getValue() {
return Optional.of(value);
}
public T getKey() {
return key;
}
}

View File

@ -2,11 +2,14 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* An unbounded placeholder type.
@ -35,6 +38,21 @@ public final class PlaceholderType extends UnifyType{
*/
private final boolean IsGenerated;
/**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
*/
private boolean wildcardable = true;
/**
* variance shows the variance of the pair
* -1: contravariant
* 1 covariant
* 0 invariant
* PL 2018-03-21
*/
private int variance = 0;
/**
* Creates a new placeholder type with the specified name.
*/
@ -54,6 +72,10 @@ 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.
@ -74,6 +96,21 @@ public final class PlaceholderType extends UnifyType{
return IsGenerated;
}
public void setVariance(int v) {
variance = v;
}
public int getVariance() {
return variance;
}
public Boolean isWildcardable() {
return wildcardable;
}
public void disableWildcardtable() {
wildcardable = false;
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc) {
return fc.smArg(this);
@ -96,8 +133,11 @@ public final class PlaceholderType extends UnifyType{
@Override
UnifyType apply(Unifier unif) {
if(unif.hasSubstitute(this))
return unif.getSubstitute(this);
if(unif.hasSubstitute(this)) {
UnifyType ret = unif.getSubstitute(this);
ret.accept(new distributeVariance(), this.getVariance());
return ret;
}
return this;
}

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* A reference type e.q. Integer or List<T>.
@ -16,6 +18,11 @@ public final class ReferenceType extends UnifyType {
*/
private final int hashCode;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public ReferenceType(String name, UnifyType... params) {
super(name, new TypeParams(params));
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* A super wildcard type e.g. ? super Integer.
@ -10,6 +12,10 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
*/
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"

View File

@ -115,6 +115,14 @@ public final class TypeParams implements Iterable<UnifyType>{
return typeParams[i];
}
/**
* Returns the parameters of this object.
* PL 2018-03-17
*/
public UnifyType[] get() {
return typeParams;
}
/**
* Sets the the type t as the i-th parameter and returns a new object
* that equals this object, except for the i-th type.

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
/**
@ -63,7 +65,44 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
* @return A new pair where the left and right-hand side are applied
*/
public UnifyPair apply(UnifyPair p) {
return new UnifyPair(this.apply(p.getLhsType()), this.apply(p.getRhsType()), p.getPairOp());
UnifyType newLhs = this.apply(p.getLhsType());
UnifyType newRhs = this.apply(p.getRhsType());
return new UnifyPair(newLhs, newRhs, p.getPairOp());
}
/**
* Applies the unifier to the two terms of the pair.
* works only for single subsitution
* @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
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p);
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair());
}
/**

View File

@ -2,7 +2,10 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A pair which contains two types and an operator, e.q. (Integer <. a).
@ -25,6 +28,29 @@ public class UnifyPair {
*/
private PairOperator pairOp;
/** wieder loesecn wird nicht mehr benoetigt PL 2018-03-31
* variance shows the variance of the pair
* -1: contravariant
* 1 covariant
* 0 invariant
* PL 2018-03-21
*/
private byte variance = 0;
private boolean undefinedPair = false;
/**
* Unifier/substitute that generated this pair
* PL 2018-03-15
*/
private Set<UnifyPair> substitution;
/**
* Base on which the the unifier is applied
* PL 2018-03-15
*/
private UnifyPair basePair;
private final int hashCode;
/**
@ -37,6 +63,20 @@ public class UnifyPair {
this.lhs = lhs;
this.rhs = rhs;
pairOp = op;
substitution = new HashSet<>();
// 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) {
this.lhs = lhs;
this.rhs = rhs;
pairOp = op;
substitution = uni;
basePair = base;
this.variance = variance;
// Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
@ -63,6 +103,41 @@ public class UnifyPair {
return pairOp;
}
public byte getVariance() {
return variance;
}
public void setVariance(byte v) {
variance = v;
}
public void setUndefinedPair() {
undefinedPair = true;
}
public Set<UnifyPair> getSubstitution() {
return substitution;
}
public UnifyPair getBasePair() {
return basePair;
}
public boolean isUndefinedPair() {
return undefinedPair;
}
public Set<UnifyPair> getAllSubstitutions () {
Set<UnifyPair> ret = new HashSet<>();
ret.addAll(getSubstitution());
if (basePair != null) {
ret.addAll(basePair.getAllSubstitutions());
}
return ret;
}
public Boolean doubleExtended() {
return lhs.doubleExtended() || rhs.doubleExtended();
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair))
@ -73,6 +148,13 @@ public class UnifyPair {
UnifyPair other = (UnifyPair) obj;
if (isUndefinedPair()) {
if (!other.getBasePair().equals(basePair) ||
!other.getAllSubstitutions().equals(getAllSubstitutions())) {
return false;
}
}
return other.getPairOp() == pairOp
&& other.getLhsType().equals(lhs)
&& other.getRhsType().equals(rhs);
@ -85,7 +167,14 @@ public class UnifyPair {
@Override
public String toString() {
return "(" + lhs + " " + pairOp + " " + rhs + ")";
String ret = "";
if (lhs instanceof PlaceholderType) {
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString();
}
if (rhs instanceof PlaceholderType) {
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString();
}
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")";
}
/*

View File

@ -2,10 +2,13 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/**
* Represents a java type.
@ -33,6 +36,9 @@ public abstract class UnifyType {
typeParams = p;
}
abstract public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht);
/**
* Returns the name of the type.
* @return The name e.q. List for List<T>, Integer or ? extends Integer
@ -96,6 +102,10 @@ public abstract class UnifyType {
ret.addAll(typeParams.getInvolvedPlaceholderTypes());
return ret;
}
public Boolean doubleExtended() {//default
return false;
}
@Override
public int hashCode() {

View File

@ -40,6 +40,11 @@ public abstract class WildcardType extends UnifyType {
return wildcardedType.getTypeParams();
}
@Override
public Boolean doubleExtended () {//This is an error
return (wildcardedType instanceof WildcardType);
}
@Override
public int hashCode() {
return wildcardedType.hashCode() + getName().hashCode() + 17;

View File

@ -0,0 +1,47 @@
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

@ -0,0 +1,31 @@
package finiteClosure;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class SuperInterfacesTest {
@Test
public void test() throws ClassNotFoundException {
Collection<ClassOrInterface> classes = new ArrayList<>();
classes.add(ASTFactory.createClass(TestClass.class));
System.out.println(FCGenerator.toFC(classes));
}
}
class TestClass implements Test2, Test3{
}
interface Test2 {
}
interface Test3{
}

View File

@ -0,0 +1,10 @@
import java.util.Vector;
class Matrix extends Vector<Vector<Integer>> {
methode(m) {
m.add(1);
Matrix i;
methode(i);
}
}

View File

@ -1,26 +1,30 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;
import java.lang.String;
class Matrix extends Vector<Vector<Integer>> {
Integer mul1(Integer x, Integer y) { return x;}
Integer add1(Integer x, Integer y) { return x;}
mul(m) {
var ret = new Matrix();
var i = 0;
//while(i < size()) {
while(i < size()) {
var v1 = this.elementAt(i);
//var v2 = new Vector<Integer>();
//var j = 0;
//while(j < v1.size()) {
//var erg = 0;
//var k = 0;
//while(k < v1.size()) {
//erg = erg + v1.elementAt(k)
// * m.elementAt(k).elementAt(j);
//k++; }
//v2.addElement(new Integer(erg));
//j++; }
//ret.addElement(v2);
//i++; }
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
var erg = 0;
var k = 0;
while(k < v1.size()) {
//erg = erg + v1.elementAt(k) * m.elementAt(k).elementAt(j);
erg = add1(erg, mul1(v1.elementAt(k),
m.elementAt(k).elementAt(j)));
k++; }
v2.addElement(new Integer(erg));
j++; }
ret.addElement(v2);
i++; }
return ret;
}
}

View File

@ -99,7 +99,11 @@ public class JavaTXCompilerTest {
// //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
// //filesToTest.add(new File(rootDirectory+"test.jav"));
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
for(File f : compiler.sourceFiles.keySet()){
SourceFile sf = compiler.sourceFiles.get(f);
System.out.println(ASTTypePrinter.print(sf));
System.out.println(ASTPrinter.print(sf));
}
List<ResultSet> results = compiler.typeInference();
for(File f : compiler.sourceFiles.keySet()){

View File

@ -0,0 +1,139 @@
package typeinference;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class UnifyTest {
public static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/";
/*
@Test
public void finiteClosure() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"fc.jav"));
}
@Test
public void lambda() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Lambda.jav"));
}
@Test
public void lambda2() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Lambda2.jav"));
}
@Test
public void lambda3() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Lambda3.jav"));
}
@Test
public void mathStruc() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"mathStruc.jav"));
}
@Test
public void generics() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Generics.jav"));
}
@Test
public void faculty() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Faculty.jav"));
}
@Test
public void facultyTyped() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"FacultyTyped.jav"));
}
*/
@Test
public void matrix() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Matrix.jav"));
}
/*
@Test
public void vector() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Vector.jav"));
}
@Test
public void lambdaRunnable() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"LambdaRunnable.jav"));
}
@Test
public void expressions() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"Expressions.jav"));
}
@Test
public void matrixFC() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory+"FC_Matrix.jav"));
}
*/
private static class TestResultSet{
}
public TestResultSet execute(File fileToTest) throws IOException, ClassNotFoundException {
//filesToTest.add(new File(rootDirectory+"fc.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
//filesToTest.add(new File(rootDirectory+"Lambda3.jav"));
//filesToTest.add(new File(rootDirectory+"Vector.jav"));
//filesToTest.add(new File(rootDirectory+"Generics.jav"));
//filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
//filesToTest.add(new File(rootDirectory+"Matrix.jav"));
//filesToTest.add(new File(rootDirectory+"Import.jav"));
// //filesToTest.add(new File(rootDirectory+"Faculty.jav"));
// //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
// //filesToTest.add(new File(rootDirectory+"test.jav"));
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
for(File f : compiler.sourceFiles.keySet()){
SourceFile sf = compiler.sourceFiles.get(f);
System.out.println(ASTTypePrinter.print(sf));
System.out.println(ASTPrinter.print(sf));
}
List<ResultSet> results = compiler.typeInference();
for(File f : compiler.sourceFiles.keySet()){
SourceFile sf = compiler.sourceFiles.get(f);
System.out.println(ASTTypePrinter.print(sf));
System.out.println(ASTPrinter.print(sf));
//List<ResultSet> results = compiler.typeInference(); PL 2017-10-03 vor die For-Schleife gezogen
assert results.size()>0;
Set<String> insertedTypes = new HashSet<>();
for(ResultSet resultSet : results){
Set<TypeInsert> result = TypeInsertFactory.createTypeInsertPoints(sf, resultSet);
assert result.size()>0;
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
for(TypeInsert tip : result){
insertedTypes.add(tip.insert(content));
}
}
for(String s : insertedTypes){
System.out.println(s);
}
}
return new TestResultSet();
}
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}