Merge branch 'unify' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into refactoring

This commit is contained in:
JanUlrich 2016-05-03 12:42:04 +02:00
commit 4a6a8d62e3

View File

@ -81,85 +81,56 @@ public class FiniteClosure implements IFiniteClosure {
if(type instanceof FunNType) if(type instanceof FunNType)
return computeSmallerFunN((FunNType) type); return computeSmallerFunN((FunNType) type);
return computeSmaller(type); Set<UnifyType> ts = new HashSet<>();
ts.add(type);
return computeSmaller(ts);
} }
/** /**
* Computes the smaller functions for every type except FunNTypes. * Computes the smaller functions for every type except FunNTypes.
*/ */
private Set<UnifyType> computeSmaller(UnifyType type) { private Set<UnifyType> computeSmaller(Set<UnifyType> types) {
// Base Case: The type is in the inheritance tree. Add all children. HashSet<UnifyType> result = new HashSet<>();
// This is Case 1 in the definition of the subtyping relation.
if(inheritanceGraph.containsKey(type)) {
Set<UnifyType> result = new HashSet<>();
result.add(type);
result.addAll(inheritanceGraph.get(type).getContentOfDescendants());
return result;
}
IUnify unify = new MartelliMontanariUnify(); IUnify unify = new MartelliMontanariUnify();
Set<UnifyType> result1 = new HashSet<>();
// if T = T' then T <=* T' for(UnifyType t : types) {
result1.add(type);
// Permute all params with values that are in smArg() of that type. // if T = T' then T <* T'
// This corresponds to Case 3 in the definition of the subtyping relation. result.add(t);
/*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (UnifyType param : type.getTypeParams())
paramCandidates.add(smArg(param));
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/
// This is case 2 of the definition of the subtyping relation. // if C<...> <* C<...> then ... (third case in definition of <*)
Set<UnifyType> result2 = new HashSet<>(); if(t.getTypeParams().size() > 0) {
if (strInheritanceGraph.containsKey(type.getName())) { ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
HashSet<UnifyType> candidates = new HashSet<>(); for (int i = 0; i < t.getTypeParams().size(); i++)
// All types with the same name paramCandidates.add(smArg(t.getTypeParams().get(i)));
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x)));
//for(UnifyType typePrime : result1) {
for (UnifyType theta2 : candidates) {
// Find the substitution
Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
if (!sigma2Opt.isPresent())
continue;
Unifier sigma2 = sigma2Opt.get();
if(sigma2.size() == 0)
continue;
sigma2.swapPlaceholderSubstitutions(type.getTypeParams());
//if(type.equals(theta2))
// continue;
Set<UnifyType> theta1s = smaller(theta2);
for (UnifyType theta1 : theta1s) {
// Because only the most general type is calculated, sigma1 = sigma2
UnifyType sigma1Theta1 = sigma2.apply(theta1);
result2.add(sigma1Theta1);
}
}
}
else
result2 = result1;
// Permute the params again.
// This corresponds again to Case 3 of the definition of the subtyping relation.
Set<UnifyType> result3 = new HashSet<>();
for(UnifyType t : result2) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (UnifyType param : t.getTypeParams())
paramCandidates.add(smArg(param));
Set<TypeParams> permResult = permuteParams(paramCandidates);
for (TypeParams newParams : permResult) {
UnifyType tPrime = t.setTypeParams(newParams);
if(tPrime.equals(t))
result3.add(t);
else
result3.addAll(smaller(tPrime));
} }
if(!strInheritanceGraph.containsKey(t.getName()))
continue;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) {
UnifyType theta2 = candidate.getContent();
Optional<Unifier> optSigma = unify.unify(theta2, t);
if(!optSigma.isPresent())
continue;
Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutions(t.getTypeParams());
Set<UnifyType> theta1Set = candidate.getContentOfDescendants();
for(UnifyType theta1 : theta1Set)
result.add(theta1.apply(sigma));
}
} }
return result3; if(result.equals(types))
return result;
return computeSmaller(result);
} }
/** /**
@ -190,82 +161,58 @@ public class FiniteClosure implements IFiniteClosure {
public Set<UnifyType> greater(UnifyType type) { public Set<UnifyType> greater(UnifyType type) {
if(type instanceof FunNType) if(type instanceof FunNType)
return computeGreaterFunN((FunNType) type); return computeGreaterFunN((FunNType) type);
return computeGreater(type);
Set<UnifyType> ts = new HashSet<>();
ts.add(type);
return computeGreater(ts);
} }
/** /**
* Computes the greater function for all types except function types. * Computes the greater function for all types except function types.
*/ */
protected Set<UnifyType> computeGreater(UnifyType type) { protected Set<UnifyType> computeGreater(Set<UnifyType> types) {
HashSet<UnifyType> result = new HashSet<>();
IUnify unify = new MartelliMontanariUnify(); IUnify unify = new MartelliMontanariUnify();
Set<UnifyType> result1 = new HashSet<>();
// The type is in the inheritance tree. Add all children. for(UnifyType t : types) {
// This is Case 1 in the definition of the subtyping relation.
if(inheritanceGraph.containsKey(type))
result1.addAll(inheritanceGraph.get(type).getContentOfPredecessors());
// if T = T' then T <=* T' // if T = T' then T <=* T'
result1.add(type); result.add(t);
// Permute all params with values that are in smArg() of that type. // if C<...> <* C<...> then ... (third case in definition of <*)
// This corresponds to Case 3 in the definition of the subtyping relation. if(t.getTypeParams().size() > 0) {
/*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (UnifyType param : type.getTypeParams()) for (int i = 0; i < t.getTypeParams().size(); i++)
paramCandidates.add(grArg(param)); paramCandidates.add(grArg(t.getTypeParams().get(i)));
permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/ permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x)));
// This is case 2 of the definition of the subtyping relation.
Set<UnifyType> result2 = new HashSet<>();
if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) {
HashSet<UnifyType> candidates = new HashSet<>();
// All types with the same name
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
// for(UnifyType typePrime : result1)
for (UnifyType theta2 : candidates) {
// Find the substitution
Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
if (!sigma2Opt.isPresent())
continue;
//if (type.equals(theta2))
// continue;
Unifier sigma2 = sigma2Opt.get();
if(sigma2.size() == 0) // type.equals(theta2)
continue;
sigma2.swapPlaceholderSubstitutionsReverse(type.getTypeParams());
Set<UnifyType> theta1s = greater(theta2);
for (UnifyType theta1 : theta1s) {
// Because only the most general type is calculated, sigma1
// = sigma2
UnifyType sigma1Theta1 = sigma2.apply(theta1);
result2.add(sigma1Theta1);
}
// }
} }
}
result2.addAll(result1); if(!strInheritanceGraph.containsKey(t.getName()))
continue;
// Permute the params again. // if T <* T' then sigma(T) <* sigma(T')
// This corresponds again to Case 3 of the definition of the subtyping relation. Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
Set<UnifyType> result3 = new HashSet<>(); for(Node<UnifyType> candidate : candidates) {
for(UnifyType t : result2) { UnifyType theta1 = candidate.getContent();
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); Optional<Unifier> optSigma = unify.unify(theta1, t);
for (UnifyType param : t.getTypeParams()) if(!optSigma.isPresent())
paramCandidates.add(grArg(param)); continue;
for (TypeParams newParams : permuteParams(paramCandidates)) { Unifier sigma = optSigma.get();
UnifyType tPrime = t.setTypeParams(newParams); sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams());
if(tPrime.equals(t))
result3.add(t); Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
else
result3.addAll(greater(tPrime)); for(UnifyType theta2 : theta2Set)
result.add(theta2.apply(sigma));
} }
} }
return result3; if(result.equals(types))
return result;
return computeGreater(result);
} }
/** /**