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.bytecode.BytecodeGen;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext; import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; 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.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JavaTXCompiler { public class JavaTXCompiler {
@ -97,20 +104,73 @@ public class JavaTXCompiler {
TypeUnify unify = new TypeUnify(); TypeUnify unify = new TypeUnify();
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
for (List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()) { try {
Set<UnifyPair> xConsSet = new HashSet<>(); FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/test/logFiles/"+"log"));
for (Constraint<UnifyPair> constraint : xCons) { logFile.write("FC:\\" + finiteClosure.toString()+"\n");
xConsSet.addAll(constraint); for(SourceFile sf : this.sourceFiles.values()) {
} logFile.write(ASTTypePrinter.print(sf));
}
System.out.println(xConsSet); logFile.flush();
Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); for (List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()) {
System.out.println("RESULT: " + result.size()); Set<UnifyPair> xConsSet = new HashSet<>();
results.addAll(result); 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) { private Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>(); HashMap<String, TypePlaceholder> ret = new HashMap<>();
@ -156,4 +216,4 @@ public class JavaTXCompiler {
System.out.println(name+".class file generated"); System.out.println(name+".class file generated");
} }
} }
} }

View File

@ -57,48 +57,55 @@ public class FCGenerator {
params.add(gtvs.get(gtv.getName())); 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)); List<RefType> superClasses = new ArrayList<>();
superClasses.add(forType.getSuperClass());
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken()); superClasses.addAll(forType.getSuperInterfaces());
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<Pair> retList = new ArrayList<>(); List<Pair> retList = new ArrayList<>();
retList.add(ret); for(RefType superType : superClasses){
retList.addAll(superTypes); 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; return retList;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -94,7 +94,8 @@ public class MartelliMontanariUnify implements IUnify {
// SUBST - Rule // SUBST - Rule
if(lhsType instanceof PlaceholderType) { if(lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); 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; idx = idx+1 == termsList.size() ? 0 : idx+1;
continue; 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.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.WildcardType; import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
import java.io.FileWriter;
import java.io.IOException;
/** /**
* Implementation of the type inference rules. * Implementation of the type inference rules.
* @author Florian Steurer * @author Florian Steurer
* *
*/ */
public class RuleSet implements IRuleSet{ public class RuleSet implements IRuleSet{
FileWriter logFile;
RuleSet() {
super();
}
RuleSet(FileWriter logFile) {
this.logFile = logFile;
}
@Override @Override
public Optional<UnifyPair> reduceUp(UnifyPair pair) { public Optional<UnifyPair> reduceUp(UnifyPair pair) {
@ -47,7 +60,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack the SuperType // 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 @Override
@ -65,7 +78,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack the ExtendsType // 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 @Override
@ -83,7 +96,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack both sides // 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 @Override
@ -133,7 +146,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++) 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); return Optional.of(result);
} }
@ -184,7 +197,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++) 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); return Optional.of(result);
} }
@ -215,7 +228,7 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsType.getTypeParams(); TypeParams rhsTypeParams = rhsType.getTypeParams();
for(int i = 0; i < lhsTypeParams.size(); i++) 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); return Optional.of(result);
} }
@ -236,19 +249,53 @@ public class RuleSet implements IRuleSet{
ReferenceType lhsSType = (ReferenceType) c; ReferenceType lhsSType = (ReferenceType) c;
ReferenceType rhsSType = (ReferenceType) d; 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()) if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size())
return Optional.empty(); return Optional.empty();
UnifyType cFromFc = fc.getLeftHandedType(c.getName()).orElse(null); 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()) if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders())
return Optional.empty(); return Optional.empty();
UnifyType dFromFc = fc.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null); 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()) if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size())
return Optional.empty(); return Optional.empty();
//System.out.println("cFromFc: " + cFromFc);
//System.out.println("dFromFc: " + dFromFc);
int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams()); int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams());
if(pi.length == 0) if(pi.length == 0)
@ -259,7 +306,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) 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); return Optional.of(result);
} }
@ -314,7 +361,7 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsSType.getTypeParams(); TypeParams rhsTypeParams = rhsSType.getTypeParams();
TypeParams lhsTypeParams = lhsSType.getTypeParams(); TypeParams lhsTypeParams = lhsSType.getTypeParams();
for(int i = 0; i < rhsTypeParams.size(); i++) 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); return Optional.of(result);
} }
@ -365,7 +412,7 @@ public class RuleSet implements IRuleSet{
if(!(pair.getRhsType() instanceof PlaceholderType)) if(!(pair.getRhsType() instanceof PlaceholderType))
return Optional.empty(); 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 @Override
@ -407,11 +454,19 @@ public class RuleSet implements IRuleSet{
TypeParams typeDParams = typeD.getTypeParams(); TypeParams typeDParams = typeD.getTypeParams();
TypeParams typeDgenParams = typeDgen.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(); 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)); unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
else System.out.println("ERROR");
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); }
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -457,7 +512,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++) for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(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 @Override
@ -509,7 +564,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++) for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(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. && typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
&& !rhsType.getTypeParams().occurs(lhsType)) { && !rhsType.getTypeParams().occurs(lhsType)) {
Unifier uni = new Unifier(lhsType, rhsType); Unifier uni = new Unifier(lhsType, rhsType);
result = result.stream().map(uni::apply).collect(Collectors.toCollection(ArrayList::new)); result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
result1 = result1.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new)); result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
applied = true; applied = true;
} }
@ -602,7 +657,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType))
return Optional.empty(); 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 @Override
@ -615,7 +670,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType)) if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType))
return Optional.empty(); 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 @Override
@ -628,7 +683,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType))
return Optional.empty(); 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 @Override
@ -641,9 +696,11 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType)) if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType))
return Optional.empty(); 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 @Override
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair) { public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC) 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)); return Optional.of(new UnifyPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT));
} }
@Override @Override
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair) { public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC) if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
@ -686,7 +744,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
} }
*/
@Override @Override
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) { public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) {
if((pair.getPairOp() != PairOperator.SMALLERDOT) if((pair.getPairOp() != PairOperator.SMALLERDOT)
@ -709,9 +767,9 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<UnifyPair>(); 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++) 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); return Optional.of(result);
} }
@ -735,10 +793,10 @@ public class RuleSet implements IRuleSet{
for(int i = 0; i < freshPlaceholders.length; i++) for(int i = 0; i < freshPlaceholders.length; i++)
freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); 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++) 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(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -762,10 +820,10 @@ public class RuleSet implements IRuleSet{
for(int i = 0; i < freshPlaceholders.length; i++) for(int i = 0; i < freshPlaceholders.length; i++)
freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); 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++) 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(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -780,7 +838,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType)) if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType))
return Optional.empty(); 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 @Override
@ -799,11 +857,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
if(isGen) if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else { else {
UnifyType freshTph = PlaceholderType.freshPlaceholder(); UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT)); result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
return Optional.of(result); return Optional.of(result);
@ -825,11 +883,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
if(isGen) if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else { else {
UnifyType freshTph = PlaceholderType.freshPlaceholder(); UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT)); result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
return Optional.of(result); return Optional.of(result);

View File

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

View File

@ -3,7 +3,9 @@ package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -11,7 +13,9 @@ import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.RecursiveTask; import java.util.concurrent.RecursiveTask;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; 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.Unifier;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; 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 * Implementation of the type unification algorithm
* @author Florian Steurer * @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 final long serialVersionUID = 1L;
private static int i = 0; 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 * 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. * 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 Set<UnifyPair> eq;
protected IFiniteClosure fc; protected IFiniteClosure fc;
protected Ordering<Set<UnifyPair>> oup;
protected boolean parallel; 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.eq = eq;
this.fc = fc; this.fc = fc;
this.oup = new OrderingUnifyPair(fc);
this.parallel = parallel; 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 @Override
protected Set<Set<UnifyPair>> compute() { 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 * @param fc The finite closure
* @return The set of all principal type unifiers * @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 * 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); 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. // cartesian product of the sets created by pattern matching.
List<Set<Set<UnifyPair>>> topLevelSets = new ArrayList<>(); 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. if(eq1s.size() != 0) { // Do not add empty sets or the cartesian product will always be empty.
Set<Set<UnifyPair>> wrap = new HashSet<>(); 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 that originate from pair pattern matching
// Sets of the "second level" // Sets of the "second level"
Set<UnifyPair> undefinedPairs = new HashSet<>(); 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); Set<Set<Set<Set<UnifyPair>>>> secondLevelSets = calculatePairSets(eq2s, fc, undefinedPairs);
//PL 2017-09-20: Im calculatePairSets wird möglicherweise O .< java.lang.Integer //PL 2017-09-20: Im calculatePairSets wird möglicherweise O .< java.lang.Integer
//nicht ausgewertet Faculty Beispiel im 1. Schritt //nicht ausgewertet Faculty Beispiel im 1. Schritt
//PL 2017-10-03 geloest, muesste noch mit FCs mit kleineren //PL 2017-10-03 geloest, muesste noch mit FCs mit kleineren
//Typen getestet werden. //Typen getestet werden.
if (printtag) System.out.println("secondLevelSets:" +secondLevelSets);
// If pairs occured that did not match one of the cartesian product cases, // If pairs occured that did not match one of the cartesian product cases,
// those pairs are contradictory and the unification is impossible. // those pairs are contradictory and the unification is impossible.
if(!undefinedPairs.isEmpty()) if(!undefinedPairs.isEmpty()) {
return new HashSet<>(); 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. /* Up to here, no cartesian products are calculated.
* filters for pairs and sets can be applied here */ * 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)" // "the big (x)"
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) { /* for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
//System.out.println("secondLevelSet "+secondLevelSet.size()); //System.out.println("secondLevelSet "+secondLevelSet.size());
List<Set<Set<UnifyPair>>> secondLevelSetList = new ArrayList<>(secondLevelSet); List<Set<Set<UnifyPair>>> secondLevelSetList = new ArrayList<>(secondLevelSet);
Set<List<Set<UnifyPair>>> cartResult = setOps.cartesianProduct(secondLevelSetList); Set<List<Set<UnifyPair>>> cartResult = setOps.cartesianProduct(secondLevelSetList);
@ -153,62 +255,108 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
flat1.addAll(s1); flat1.addAll(s1);
flat.add(flat1); 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 // Cartesian product over all (up to 10) top level sets
Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets) //Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets)
.stream().map(x -> new HashSet<>(x)) // .stream().map(x -> new HashSet<>(x))
.collect(Collectors.toCollection(HashSet::new)); // .collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>(); Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
Set<TypeUnifyTask> forks = 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 // Flatten the cartesian product
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<UnifyPair> eqPrime = new HashSet<>(); Set<UnifyPair> eqPrime = new HashSet<>();
setToFlatten.stream().forEach(x -> eqPrime.addAll(x)); setToFlatten.stream().forEach(x -> eqPrime.addAll(x));
/* /*
* Step 5: Substitution * Step 5: Substitution
*/ */
System.out.println("vor Subst: " + eqPrime); //System.out.println("vor Subst: " + eqPrime);
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime); Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
/* /*
* Step 6 a) Restart (fork) for pairs where subst was applied * Step 6 a) Restart (fork) for pairs where subst was applied
*/ */
if(parallel) { if(parallel) {
if //(eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch if (eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch
(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt //(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
//Begruendung: Wenn in der Substitution keine Veraenderung //Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt. //(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt.
eqPrimePrimeSet.add(eqPrime); eqPrimePrimeSet.add(eqPrime);
else if(eqPrimePrime.isPresent()) { else if(eqPrimePrime.isPresent()) {
System.out.println("nextStep: " + eqPrimePrime.get()); //System.out.println("nextStep: " + eqPrimePrime.get());
TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true); TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true, logFile);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
else { else {
System.out.println("nextStep: " + eqPrime); //System.out.println("nextStep: " + eqPrime);
TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true); TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true, logFile);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
} }
else { // sequentiell (Step 6b is included) else { // sequentiell (Step 6b is included)
if //(eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch if (printtag) System.out.println("nextStep: " + eqPrimePrime);
(!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 //Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt. //(!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); eqPrimePrimeSet.add(eqPrime);
else if(eqPrimePrime.isPresent()) }
eqPrimePrimeSet.addAll(unify(eqPrimePrime.get(), fc, false)); else if(eqPrimePrime.isPresent()) {
else Set<Set<UnifyPair>> unifyres = unify(eqPrimePrime.get(), fc, false);
eqPrimePrimeSet.addAll(unify(eqPrime, 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. * 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; * 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. * Checks whether a set of pairs is in solved form.
* @param eqPrimePrime The set of pair * @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. * This is step one of the unification algorithm.
* @return The set of pairs that results from repeated application of the inference rules. * @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: * 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.reduceWildcardLowRight(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair); opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair); opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair); //PL 2018-03-06 auskommentiert muesste falsch sein vgl. JAVA_BSP/Wildcard6.java
opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair); //opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair); //opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair);
//opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair);
// Reduce TPH // Reduce TPH
opt = opt.isPresent() ? opt : rules.reduceTph(pair); opt = opt.isPresent() ? opt : rules.reduceTph(pair);
@ -301,6 +667,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
// Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq // Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq
//try {
// logFile.write("PAIR1 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
Optional<Set<UnifyPair>> optSet = rules.reduce1(pair, fc); Optional<Set<UnifyPair>> optSet = rules.reduce1(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.reduce2(pair); optSet = optSet.isPresent() ? optSet : rules.reduce2(pair);
optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair, fc); optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair, fc);
@ -324,6 +696,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
// Adapt, AdaptExt, AdaptSup // Adapt, AdaptExt, AdaptSup
//try {
// logFile.write("PAIR2 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
opt = rules.adapt(pair, fc); opt = rules.adapt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptExt(pair, fc); opt = opt.isPresent() ? opt : rules.adaptExt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptSup(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 // Init all 8 cases
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
result.add(new HashSet<>()); result.add(new HashSet<>());
ArrayList<UnifyPair> eq2sprime = new ArrayList<>(eq2s);
for(UnifyPair pair : 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(); PairOperator pairOp = pair.getPairOp();
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType(); UnifyType rhsType = pair.getRhsType();
// Case 1: (a <. Theta') // Case 1: (a <. Theta')
if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) { if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) {
System.out.println(pair); //System.out.println(pair);
Set<Set<UnifyPair>> x1 = unifyCase1((PlaceholderType) pair.getLhsType(), pair.getRhsType(), fc); if (first) { //writeLog(pair.toString()+"\n");
System.out.println(x1); Set<Set<UnifyPair>> x1 = unifyCase1(pair, fc);
result.get(0).add(x1); //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') // Case 2: (a <.? ? ext Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType) 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') // Case 3: (a <.? ? sup Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType) 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 was replaced by an inference rule
// Case 4: (a <.? Theta') // Case 4: (a <.? Theta')
@ -413,7 +830,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Case 5: (Theta <. a) // Case 5: (Theta <. a)
else if(pairOp == PairOperator.SMALLERDOT && rhsType instanceof PlaceholderType) 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 was replaced by an inference rule.
// Case 6: (? ext Theta <.? a) // Case 6: (? ext Theta <.? a)
@ -427,7 +855,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// Case 8: (Theta <.? a) // Case 8: (Theta <.? a)
else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType) 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. // 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. // 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. // 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); undefined.add(pair);
break; break;
} }
first = false;
} }
// Filter empty sets or sets that only contain an empty set. // 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)); .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') * 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<>(); Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = thetaPrime.getTypeParams().size() > 0; boolean allGen = thetaPrime.getTypeParams().size() > 0;
@ -462,7 +908,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//cs.add(thetaPrime); //cs.add(thetaPrime);
//PL 18-02-06 entfernt //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. //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.smaller(c).stream().collect(Collectors.toCollection(HashSet::new));
//Set<UnifyType> thetaQs = fc.getChildren(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) { 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); Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime);
if (!opt.isPresent()) if (!opt.isPresent()) {
continue; continue;
}
Unifier unifier = opt.get(); Unifier unifier = opt.get();
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams()); unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams());
Set<UnifyPair> substitutionSet = new HashSet<>(); Set<UnifyPair> substitutionSet = new HashSet<>();
for (Entry<PlaceholderType, UnifyType> sigma : unifier) for (Entry<PlaceholderType, UnifyType> sigma : unifier) {
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); 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 //List<UnifyType> freshTphs = new ArrayList<>(); PL 18-02-06 in die For-Schleife verschoben
for (UnifyType tq : thetaQs) { for (UnifyType tq : thetaQs) {
Set<UnifyType> smaller = fc.smaller(unifier.apply(tq)); 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) { for(UnifyType theta : smaller) {
List<UnifyType> freshTphs = new ArrayList<>(); List<UnifyType> freshTphs = new ArrayList<>();
Set<UnifyPair> resultPrime = new HashSet<>(); 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++) { for(int i = 0; !allGen && i < theta.getTypeParams().size(); i++) {
if(freshTphs.size()-1 < i) if(freshTphs.size()-1 < i)
freshTphs.add(PlaceholderType.freshPlaceholder()); 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) if(allGen) {
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT)); UnifyPair up = new UnifyPair(a, theta, PairOperator.EQUALSDOT, pair.getSubstitution(), pair);
else Iterator<UnifyType> upit = up.getRhsType().getTypeParams().iterator();
resultPrime.add(new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT)); 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); 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); 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') * 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<>(); Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder(); UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType extAPrime = new ExtendsType(aPrime); UnifyType extAPrime = new ExtendsType(aPrime);
UnifyType thetaPrime = extThetaPrime.getExtendedType(); UnifyType thetaPrime = extThetaPrime.getExtendedType();
Set<UnifyPair> resultPrime = new HashSet<>(); 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); result.add(resultPrime);
resultPrime = new HashSet<>(); resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT)); resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(aPrime, thetaPrime, PairOperator.SMALLERDOT)); 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); result.add(resultPrime);
//writeLog("Result: " + resultPrime.toString());
return result; return result;
} }
/** /**
* Cartesian Product Case 3: (a <.? ? sup Theta') * 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<>(); Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder(); UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType supAPrime = new SuperType(aPrime); UnifyType supAPrime = new SuperType(aPrime);
UnifyType thetaPrime = subThetaPrime.getSuperedType(); UnifyType thetaPrime = subThetaPrime.getSuperedType();
Set<UnifyPair> resultPrime = new HashSet<>(); 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); result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>(); resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT)); resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(thetaPrime, aPrime, PairOperator.SMALLERDOT)); 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); result.add(resultPrime);
//writeLog(resultPrime.toString());
return result; return result;
} }
@ -576,7 +1067,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/** /**
* Cartesian Product Case 5: (Theta <. a) * 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<>(); Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = theta.getTypeParams().size() > 0; 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()]; UnifyType[] freshTphs = new UnifyType[thetaS.getTypeParams().size()];
for(int i = 0; !allGen && i < freshTphs.length; i++) { for(int i = 0; !allGen && i < freshTphs.length; i++) {
freshTphs[i] = PlaceholderType.freshPlaceholder(); 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) if(allGen)
resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT)); resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
else 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); result.add(resultPrime);
//writeLog(resultPrime.toString());
} }
return result; return result;
@ -608,23 +1104,30 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/** /**
* Cartesian Product Case 8: (Theta <.? a) * 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<>(); Set<Set<UnifyPair>> result = new HashSet<>();
//for(UnifyType thetaS : fc.grArg(theta)) { //for(UnifyType thetaS : fc.grArg(theta)) {
Set<UnifyPair> resultPrime = new HashSet<>(); 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); result.add(resultPrime);
//writeLog(resultPrime.toString());
UnifyType freshTph = PlaceholderType.freshPlaceholder(); UnifyType freshTph = PlaceholderType.freshPlaceholder();
resultPrime = new HashSet<>(); resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT)); resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT)); resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair));
result.add(resultPrime); result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>(); resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT)); resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair));
resultPrime.add(new UnifyPair(freshTph, theta, PairOperator.SMALLERDOT)); 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); result.add(resultPrime);
//writeLog(resultPrime.toString());
//} //}
return result; return result;
@ -662,4 +1165,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
permuteParams(candidates, idx+1, result, current); 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.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType; 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.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.SuperType;
@ -60,5 +61,7 @@ public interface IFiniteClosure {
public Optional<UnifyType> getLeftHandedType(String typeName); public Optional<UnifyType> getLeftHandedType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t); public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(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 * Match
* @author Martin Pluemicke * @author Martin Pluemicke
* abgeleitet aus IUnify.java
*/ */
public interface IMatch { public interface IMatch {
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = t1' , ... sigma(tn) = tn'.
* @param terms The set of terms to be unified * @param terms The set of terms to be matched
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier. * @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); 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> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
/*
* vgl. JAVA_BSP/Wildcard6.java
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair); public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair); public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
*/
/* /*
* Additional Rules which replace cases of the cartesian product * 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 { public interface IUnify {
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified * @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. * @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); public Optional<Unifier> unify(Set<UnifyType> terms);
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified * @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. * @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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* An extends wildcard type "? extends T". * An extends wildcard type "? extends T".
*/ */
public final class ExtendsType extends WildcardType { 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. * Creates a new extends wildcard type.
* @param extendedType The extended type e.g. Integer in "? extends Integer" * @param extendedType The extended type e.g. Integer in "? extends Integer"
*/ */
public ExtendsType(UnifyType extendedType) { 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.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//PL 18-02-05 Unifier durch Matcher ersetzt import com.google.common.collect.Ordering;
//mus greater noch erstezt werden
//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.MartelliMontanariUnify;
import de.dhbwstuttgart.typeinference.unify.Match; 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.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; 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 * The finite closure for the type unification
* @author Florian Steurer * @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. * 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) { protected Set<UnifyType> computeGreater(Set<UnifyType> types) {
HashSet<UnifyType> result = new HashSet<>(); 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) { for(UnifyType t : types) {
@ -215,7 +220,11 @@ public class FiniteClosure implements IFiniteClosure {
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName()); Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) { for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent(); 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()) if(!optSigma.isPresent())
continue; continue;
@ -369,7 +378,7 @@ public class FiniteClosure implements IFiniteClosure {
return Optional.empty(); return Optional.empty();
for(UnifyPair pair : pairs) 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.of(pair.getLhsType());
return Optional.empty(); return Optional.empty();
@ -430,4 +439,33 @@ public class FiniteClosure implements IFiniteClosure {
public String toString(){ public String toString(){
return this.inheritanceGraph.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; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* A real function type in java. * A real function type in java.
@ -10,6 +12,10 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
*/ */
public class FunNType extends UnifyType { 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. * 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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* An unbounded placeholder type. * An unbounded placeholder type.
@ -35,6 +38,21 @@ public final class PlaceholderType extends UnifyType{
*/ */
private final boolean IsGenerated; 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. * Creates a new placeholder type with the specified name.
*/ */
@ -54,6 +72,10 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = isGenerated; 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. * 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. * 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; 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 @Override
Set<UnifyType> smArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc) {
return fc.smArg(this); return fc.smArg(this);
@ -96,8 +133,11 @@ public final class PlaceholderType extends UnifyType{
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unif) {
if(unif.hasSubstitute(this)) if(unif.hasSubstitute(this)) {
return unif.getSubstitute(this); UnifyType ret = unif.getSubstitute(this);
ret.accept(new distributeVariance(), this.getVariance());
return ret;
}
return this; return this;
} }

View File

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

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* A super wildcard type e.g. ? super Integer. * 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 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" * Creates a new instance "? extends superedType"
* @param superedType The type that is supered e.g. Integer in "? super Integer" * @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]; 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 * 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. * that equals this object, except for the i-th type.

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function; 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 * @return A new pair where the left and right-hand side are applied
*/ */
public UnifyPair apply(UnifyPair p) { 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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* A pair which contains two types and an operator, e.q. (Integer <. a). * A pair which contains two types and an operator, e.q. (Integer <. a).
@ -25,6 +28,29 @@ public class UnifyPair {
*/ */
private PairOperator pairOp; 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; private final int hashCode;
/** /**
@ -37,6 +63,20 @@ public class UnifyPair {
this.lhs = lhs; this.lhs = lhs;
this.rhs = rhs; this.rhs = rhs;
pairOp = op; 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 // Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
@ -63,6 +103,41 @@ public class UnifyPair {
return pairOp; 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 @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair)) if(!(obj instanceof UnifyPair))
@ -73,6 +148,13 @@ public class UnifyPair {
UnifyPair other = (UnifyPair) obj; UnifyPair other = (UnifyPair) obj;
if (isUndefinedPair()) {
if (!other.getBasePair().equals(basePair) ||
!other.getAllSubstitutions().equals(getAllSubstitutions())) {
return false;
}
}
return other.getPairOp() == pairOp return other.getPairOp() == pairOp
&& other.getLhsType().equals(lhs) && other.getLhsType().equals(lhs)
&& other.getRhsType().equals(rhs); && other.getRhsType().equals(rhs);
@ -85,7 +167,14 @@ public class UnifyPair {
@Override @Override
public String toString() { 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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* Represents a java type. * Represents a java type.
@ -33,6 +36,9 @@ public abstract class UnifyType {
typeParams = p; typeParams = p;
} }
abstract public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht);
/** /**
* Returns the name of the type. * Returns the name of the type.
* @return The name e.q. List for List<T>, Integer or ? extends Integer * @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()); ret.addAll(typeParams.getInvolvedPlaceholderTypes());
return ret; return ret;
} }
public Boolean doubleExtended() {//default
return false;
}
@Override @Override
public int hashCode() { public int hashCode() {

View File

@ -40,6 +40,11 @@ public abstract class WildcardType extends UnifyType {
return wildcardedType.getTypeParams(); return wildcardedType.getTypeParams();
} }
@Override
public Boolean doubleExtended () {//This is an error
return (wildcardedType instanceof WildcardType);
}
@Override @Override
public int hashCode() { public int hashCode() {
return wildcardedType.hashCode() + getName().hashCode() + 17; 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.util.Vector;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Boolean; import java.lang.Boolean;
import java.lang.String;
class Matrix extends Vector<Vector<Integer>> { class Matrix extends Vector<Vector<Integer>> {
Integer mul1(Integer x, Integer y) { return x;}
Integer add1(Integer x, Integer y) { return x;}
mul(m) { mul(m) {
var ret = new Matrix(); var ret = new Matrix();
var i = 0; var i = 0;
//while(i < size()) { while(i < size()) {
var v1 = this.elementAt(i); var v1 = this.elementAt(i);
//var v2 = new Vector<Integer>(); var v2 = new Vector<Integer>();
//var j = 0; var j = 0;
//while(j < v1.size()) { while(j < v1.size()) {
//var erg = 0; var erg = 0;
//var k = 0; var k = 0;
//while(k < v1.size()) { while(k < v1.size()) {
//erg = erg + v1.elementAt(k) //erg = erg + v1.elementAt(k) * m.elementAt(k).elementAt(j);
// * m.elementAt(k).elementAt(j); erg = add1(erg, mul1(v1.elementAt(k),
//k++; } m.elementAt(k).elementAt(j)));
//v2.addElement(new Integer(erg)); k++; }
//j++; } v2.addElement(new Integer(erg));
//ret.addElement(v2); j++; }
//i++; } ret.addElement(v2);
i++; }
return ret; return ret;
} }
} }

View File

@ -99,7 +99,11 @@ public class JavaTXCompilerTest {
// //filesToTest.add(new File(rootDirectory+"mathStruc.jav")); // //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
// //filesToTest.add(new File(rootDirectory+"test.jav")); // //filesToTest.add(new File(rootDirectory+"test.jav"));
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest); 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(); List<ResultSet> results = compiler.typeInference();
for(File f : compiler.sourceFiles.keySet()){ 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);
}
}