Merge branch 'unify' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into unify
This commit is contained in:
commit
0ca4f16c49
@ -361,8 +361,13 @@ public class SourceFile
|
|||||||
*/
|
*/
|
||||||
typinferenzLog.debug("\nUnifiziere Constraints:\n"+constraints, Section.TYPEINFERENCE);
|
typinferenzLog.debug("\nUnifiziere Constraints:\n"+constraints, Section.TYPEINFERENCE);
|
||||||
typinferenzLog.debug("\nFC:\n"+finiteClosure, Section.TYPEINFERENCE);
|
typinferenzLog.debug("\nFC:\n"+finiteClosure, Section.TYPEINFERENCE);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
Set<Set<UnifyPair>> unifyResult = new TypeUnify().unify(constraints, finiteClosure);
|
Set<Set<UnifyPair>> unifyResult = new TypeUnify().unify(constraints, finiteClosure);
|
||||||
|
long time = System.currentTimeMillis()-start;
|
||||||
typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE);
|
typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE);
|
||||||
|
typinferenzLog.debug("\nAnzahl Lösungen:\n"+unifyResult.size(), Section.TYPEINFERENCE);
|
||||||
|
typinferenzLog.debug("\nZeit für Unifizierung: "+time + "ms", Section.TYPEINFERENCE);
|
||||||
|
|
||||||
|
|
||||||
Menge<Menge<Pair>> convertedResult = unifyResult.parallelStream().<Menge<Pair>>map((Set<UnifyPair> resultSet)->{
|
Menge<Menge<Pair>> convertedResult = unifyResult.parallelStream().<Menge<Pair>>map((Set<UnifyPair> resultSet)->{
|
||||||
Menge<Pair> innerConvert = resultSet.stream().map((UnifyPair mp)->UnifyTypeFactory.convert(mp))
|
Menge<Pair> innerConvert = resultSet.stream().map((UnifyPair mp)->UnifyTypeFactory.convert(mp))
|
||||||
|
@ -50,12 +50,6 @@ public class MartelliMontanariUnify implements IUnify {
|
|||||||
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
TypeParams rhsTypeParams = rhsType.getTypeParams();
|
||||||
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
TypeParams lhsTypeParams = lhsType.getTypeParams();
|
||||||
|
|
||||||
// DELETE - Rule
|
|
||||||
if(pair.getRhsType().equals(pair.getLhsType())) {
|
|
||||||
termsList.remove(idx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// REDUCE - Rule
|
// REDUCE - Rule
|
||||||
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
|
||||||
Set<UnifyPair> result = new HashSet<>();
|
Set<UnifyPair> result = new HashSet<>();
|
||||||
@ -79,6 +73,12 @@ public class MartelliMontanariUnify implements IUnify {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DELETE - Rule
|
||||||
|
if(pair.getRhsType().equals(pair.getLhsType())) {
|
||||||
|
termsList.remove(idx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// SWAP - Rule
|
// SWAP - Rule
|
||||||
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {
|
||||||
termsList.remove(idx);
|
termsList.remove(idx);
|
||||||
|
@ -3,6 +3,7 @@ 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.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -10,6 +11,7 @@ import java.util.List;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
@ -47,6 +49,10 @@ public class TypeUnify {
|
|||||||
*/
|
*/
|
||||||
protected IRuleSet rules = new RuleSet();
|
protected IRuleSet rules = new RuleSet();
|
||||||
|
|
||||||
|
// Scheint momentan eher zu verlangsamen, vermutlich zu viele threads,
|
||||||
|
// threadpool und task-queue einbauen und minimale problemgröße für neuen thread
|
||||||
|
protected boolean parallel = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes all principal type unifiers for a set of constraints.
|
* Computes all principal type unifiers for a set of constraints.
|
||||||
* @param eq The set of constraints
|
* @param eq The set of constraints
|
||||||
@ -110,7 +116,7 @@ public class TypeUnify {
|
|||||||
|
|
||||||
// Sub cartesian products of the second level (pattern matched) sets
|
// Sub cartesian products of the second level (pattern matched) sets
|
||||||
// "the big (x)"
|
// "the big (x)"
|
||||||
// TODO Optimierungsmöglichkeit: Parallelisierung der Schleife möglich
|
// TODO Optimierungsmöglichkeit: Parallelisierung der Schleife möglich (scheint sich nicht zu lohnen)
|
||||||
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
|
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
|
||||||
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);
|
||||||
@ -133,7 +139,7 @@ public class TypeUnify {
|
|||||||
//System.out.println(result);
|
//System.out.println(result);
|
||||||
|
|
||||||
// Flatten the cartesian product
|
// Flatten the cartesian product
|
||||||
// TODO parallelisierung möglich
|
// TODO parallelisierung möglich (scheint sich nicht zu lohnen)
|
||||||
Set<Set<UnifyPair>> eqPrimeSetFlat = new HashSet<>();
|
Set<Set<UnifyPair>> eqPrimeSetFlat = new HashSet<>();
|
||||||
for(Set<Set<UnifyPair>> setToFlatten : eqPrimeSet) {
|
for(Set<Set<UnifyPair>> setToFlatten : eqPrimeSet) {
|
||||||
Set<UnifyPair> buffer = new HashSet<>();
|
Set<UnifyPair> buffer = new HashSet<>();
|
||||||
@ -148,6 +154,23 @@ public class TypeUnify {
|
|||||||
Set<Set<UnifyPair>> restartSet = new HashSet<>();
|
Set<Set<UnifyPair>> restartSet = new HashSet<>();
|
||||||
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
|
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
if(parallel) {
|
||||||
|
Set<Set<UnifyPair>> restartSetSync = Collections.synchronizedSet(restartSet);
|
||||||
|
Set<Set<UnifyPair>> eqPrimePrimeSetSync = Collections.synchronizedSet(eqPrimePrimeSet);
|
||||||
|
|
||||||
|
eqPrimeSetFlat.parallelStream().forEach(eqPrime -> {
|
||||||
|
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
|
||||||
|
|
||||||
|
if (eqPrime.equals(eq))
|
||||||
|
eqPrimePrimeSetSync.add(eqPrime);
|
||||||
|
else if(eqPrimePrime.isPresent())
|
||||||
|
restartSetSync.add(eqPrimePrime.get());
|
||||||
|
else
|
||||||
|
restartSetSync.add(eqPrime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
for(Set<UnifyPair> eqPrime : eqPrimeSetFlat) {
|
for(Set<UnifyPair> eqPrime : eqPrimeSetFlat) {
|
||||||
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
|
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
|
||||||
|
|
||||||
@ -158,16 +181,23 @@ public class TypeUnify {
|
|||||||
else
|
else
|
||||||
restartSet.add(eqPrime);
|
restartSet.add(eqPrime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 6 a) Restart for pairs where subst was applied
|
* Step 6 a) Restart for pairs where subst was applied
|
||||||
* b) Build the union over everything
|
* b) Build the union over everything
|
||||||
*/
|
*/
|
||||||
// TODO parallelisierung möglich (lohnt sich vermutlich)
|
// TODO parallelisierung möglich (lohnt sich vermutlich)
|
||||||
|
|
||||||
|
if(parallel) {
|
||||||
|
Set<Set<UnifyPair>> eqPrimePrimeSetSync = Collections.synchronizedSet(eqPrimePrimeSet);
|
||||||
|
restartSet.parallelStream().forEach( x -> eqPrimePrimeSetSync.addAll(unify(x, fc)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
for(Set<UnifyPair> eqss : restartSet)
|
for(Set<UnifyPair> eqss : restartSet)
|
||||||
eqPrimePrimeSet.addAll(this.unify(eqss, fc));
|
eqPrimePrimeSet.addAll(this.unify(eqss, fc));
|
||||||
/*restartSet.parallelStream().forEach(
|
}
|
||||||
x -> eqPrimePrimeSet.addAll(unify(x, fc)));*/
|
|
||||||
/*
|
/*
|
||||||
* Step 7: Filter empty sets;
|
* Step 7: Filter empty sets;
|
||||||
*/
|
*/
|
||||||
|
@ -106,10 +106,10 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
|
|
||||||
// Permute all params with values that are in smArg() of that type.
|
// Permute all params with values that are in smArg() of that type.
|
||||||
// This corresponds to Case 3 in the definition of the subtyping relation.
|
// This corresponds to Case 3 in the definition of the subtyping relation.
|
||||||
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
/*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
for (UnifyType param : type.getTypeParams())
|
for (UnifyType param : type.getTypeParams())
|
||||||
paramCandidates.add(smArg(param));
|
paramCandidates.add(smArg(param));
|
||||||
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}
|
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/
|
||||||
|
|
||||||
// This is case 2 of the definition of the subtyping relation.
|
// This is case 2 of the definition of the subtyping relation.
|
||||||
Set<UnifyType> result2 = new HashSet<>();
|
Set<UnifyType> result2 = new HashSet<>();
|
||||||
@ -117,16 +117,18 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
HashSet<UnifyType> candidates = new HashSet<>();
|
HashSet<UnifyType> candidates = new HashSet<>();
|
||||||
// All types with the same name
|
// All types with the same name
|
||||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
for(UnifyType typePrime : result1) {
|
//for(UnifyType typePrime : result1) {
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
// Find the substitution
|
// Find the substitution
|
||||||
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
|
||||||
if (!sigma2Opt.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
Unifier sigma2 = sigma2Opt.get();
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams());
|
if(sigma2.size() == 0)
|
||||||
if(type.equals(theta2))
|
|
||||||
continue;
|
continue;
|
||||||
|
sigma2.swapPlaceholderSubstitutions(type.getTypeParams());
|
||||||
|
//if(type.equals(theta2))
|
||||||
|
// continue;
|
||||||
Set<UnifyType> theta1s = smaller(theta2);
|
Set<UnifyType> theta1s = smaller(theta2);
|
||||||
for (UnifyType theta1 : theta1s) {
|
for (UnifyType theta1 : theta1s) {
|
||||||
// Because only the most general type is calculated, sigma1 = sigma2
|
// Because only the most general type is calculated, sigma1 = sigma2
|
||||||
@ -135,7 +137,6 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
result2 = result1;
|
result2 = result1;
|
||||||
|
|
||||||
@ -210,10 +211,10 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
|
|
||||||
// Permute all params with values that are in smArg() of that type.
|
// Permute all params with values that are in smArg() of that type.
|
||||||
// This corresponds to Case 3 in the definition of the subtyping relation.
|
// This corresponds to Case 3 in the definition of the subtyping relation.
|
||||||
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
/*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
|
||||||
for (UnifyType param : type.getTypeParams())
|
for (UnifyType param : type.getTypeParams())
|
||||||
paramCandidates.add(grArg(param));
|
paramCandidates.add(grArg(param));
|
||||||
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}
|
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/
|
||||||
|
|
||||||
// This is case 2 of the definition of the subtyping relation.
|
// This is case 2 of the definition of the subtyping relation.
|
||||||
Set<UnifyType> result2 = new HashSet<>();
|
Set<UnifyType> result2 = new HashSet<>();
|
||||||
@ -222,23 +223,26 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
// All types with the same name
|
// All types with the same name
|
||||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
|
|
||||||
for(UnifyType typePrime : result1) {
|
// for(UnifyType typePrime : result1)
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
// Find the substitution
|
// Find the substitution
|
||||||
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
|
||||||
if (!sigma2Opt.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
if(type.equals(theta2))
|
//if (type.equals(theta2))
|
||||||
continue;
|
// continue;
|
||||||
Unifier sigma2 = sigma2Opt.get();
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams());
|
if(sigma2.size() == 0) // type.equals(theta2)
|
||||||
|
continue;
|
||||||
|
sigma2.swapPlaceholderSubstitutions(type.getTypeParams());
|
||||||
Set<UnifyType> theta1s = greater(theta2);
|
Set<UnifyType> theta1s = greater(theta2);
|
||||||
for (UnifyType theta1 : theta1s) {
|
for (UnifyType theta1 : theta1s) {
|
||||||
// Because only the most general type is calculated, sigma1 = sigma2
|
// Because only the most general type is calculated, sigma1
|
||||||
|
// = sigma2
|
||||||
UnifyType sigma1Theta1 = sigma2.apply(theta1);
|
UnifyType sigma1Theta1 = sigma2.apply(theta1);
|
||||||
result2.add(sigma1Theta1);
|
result2.add(sigma1Theta1);
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
*/
|
*/
|
||||||
private final UnifyType[] typeParams;
|
private final UnifyType[] typeParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashcode calculation is expensive and must be cached.
|
||||||
|
*/
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new set of type parameters.
|
* Creates a new set of type parameters.
|
||||||
* @param types The type parameters.
|
* @param types The type parameters.
|
||||||
@ -23,6 +28,9 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
typeParams = new UnifyType[types.size()];
|
typeParams = new UnifyType[types.size()];
|
||||||
for(int i=0;i<types.size();i++)
|
for(int i=0;i<types.size();i++)
|
||||||
typeParams[i] = types.get(i);
|
typeParams[i] = types.get(i);
|
||||||
|
|
||||||
|
// Hashcode calculation is expensive and must be cached.
|
||||||
|
hashCode = Arrays.hashCode(typeParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,6 +39,9 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
*/
|
*/
|
||||||
public TypeParams(UnifyType... types) {
|
public TypeParams(UnifyType... types) {
|
||||||
typeParams = types;
|
typeParams = types;
|
||||||
|
|
||||||
|
// Hashcode calculation is expensive and must be cached.
|
||||||
|
hashCode = Arrays.hashCode(typeParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +119,7 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Arrays.hashCode(typeParams);
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,6 +81,13 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
|
|||||||
return substitutions.get(t);
|
return substitutions.get(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of substitutions in the unifier. If zero, this is the identity function.
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return substitutions.size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Garantuees that if there is a substitutions (a -> b) in this unifier,
|
* Garantuees that if there is a substitutions (a -> b) in this unifier,
|
||||||
* a is not an element of the targetParams. Substitutions that do not
|
* a is not an element of the targetParams. Substitutions that do not
|
||||||
|
@ -9,18 +9,20 @@ public class UnifyPair {
|
|||||||
/**
|
/**
|
||||||
* The type on the left hand side of the pair.
|
* The type on the left hand side of the pair.
|
||||||
*/
|
*/
|
||||||
private UnifyType lhs;
|
private final UnifyType lhs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type on the right hand side of the pair.
|
* The type on the right hand side of the pair.
|
||||||
*/
|
*/
|
||||||
private UnifyType rhs;
|
private final UnifyType rhs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The operator that determines the relation between the left and right hand side type.
|
* The operator that determines the relation between the left and right hand side type.
|
||||||
*/
|
*/
|
||||||
private PairOperator pairOp;
|
private PairOperator pairOp;
|
||||||
|
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the pair.
|
* Creates a new instance of the pair.
|
||||||
* @param lhs The type on the left hand side of the pair.
|
* @param lhs The type on the left hand side of the pair.
|
||||||
@ -31,6 +33,9 @@ public class UnifyPair {
|
|||||||
this.lhs = lhs;
|
this.lhs = lhs;
|
||||||
this.rhs = rhs;
|
this.rhs = rhs;
|
||||||
pairOp = op;
|
pairOp = op;
|
||||||
|
|
||||||
|
// Caching hashcode
|
||||||
|
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +73,7 @@ public class UnifyPair {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user