Merge branch 'unify' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into refactoring
This commit is contained in:
commit
b0aeaae80e
@ -25,7 +25,7 @@ public class MartelliMontanariUnify implements IUnify {
|
|||||||
public Optional<Unifier> unify(Set<UnifyType> terms) {
|
public Optional<Unifier> unify(Set<UnifyType> terms) {
|
||||||
// Sets with less than 2 terms are trivially unified
|
// Sets with less than 2 terms are trivially unified
|
||||||
if(terms.size() < 2)
|
if(terms.size() < 2)
|
||||||
return Optional.of(Unifier.Identity());
|
return Optional.of(Unifier.identity());
|
||||||
|
|
||||||
// For the the set of terms {t1,...,tn},
|
// For the the set of terms {t1,...,tn},
|
||||||
// build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....}
|
// build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....}
|
||||||
@ -39,7 +39,7 @@ public class MartelliMontanariUnify implements IUnify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start with the identity unifier. Substitutions will be added later.
|
// Start with the identity unifier. Substitutions will be added later.
|
||||||
Unifier mgu = Unifier.Identity();
|
Unifier mgu = Unifier.identity();
|
||||||
|
|
||||||
// Apply rules while possible
|
// Apply rules while possible
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -91,7 +91,7 @@ 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));
|
termsList = termsList.stream().map(mgu::apply).collect(Collectors.toCollection(ArrayList::new));
|
||||||
idx = idx+1 == termsList.size() ? 0 : idx+1;
|
idx = idx+1 == termsList.size() ? 0 : idx+1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -417,9 +417,9 @@ public class RuleSet implements IRuleSet{
|
|||||||
TypeParams typeDParams = typeD.getTypeParams();
|
TypeParams typeDParams = typeD.getTypeParams();
|
||||||
TypeParams typeDgenParams = typeDgen.getTypeParams();
|
TypeParams typeDgenParams = typeDgen.getTypeParams();
|
||||||
|
|
||||||
Unifier unif = Unifier.Identity();
|
Unifier unif = Unifier.identity();
|
||||||
for(int i = 0; i < typeDParams.size(); i++)
|
for(int i = 0; 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), typeDs, PairOperator.SMALLERDOT));
|
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT));
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0));
|
Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0));
|
||||||
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));
|
||||||
}
|
}
|
||||||
@ -517,7 +517,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0));
|
Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0));
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -375,9 +375,9 @@ public class Unify {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Unifier unifier = opt.get();
|
Unifier unifier = opt.get();
|
||||||
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams().toArray());
|
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams());
|
||||||
Set<UnifyPair> substitutionSet = new HashSet<>();
|
Set<UnifyPair> substitutionSet = new HashSet<>();
|
||||||
for (Entry<PlaceholderType, UnifyType> sigma : unifier.getSubstitutions())
|
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));
|
||||||
|
|
||||||
List<UnifyType> freshTphs = new ArrayList<>();
|
List<UnifyType> freshTphs = new ArrayList<>();
|
||||||
|
@ -17,15 +17,16 @@ public final class ExtendsType extends WildcardType {
|
|||||||
super("? extends " + extendedType.getName(), extendedType);
|
super("? extends " + extendedType.getName(), extendedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The extended type e.g. Integer in "? extends Integer"
|
||||||
|
*/
|
||||||
public UnifyType getExtendedType() {
|
public UnifyType getExtendedType() {
|
||||||
return wildcardedType;
|
return wildcardedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public TypeParams getTypeParams() {
|
* Sets the type parameters of the wildcarded type and returns a new extendstype that extends that type.
|
||||||
return wildcardedType.getTypeParams();
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnifyType setTypeParams(TypeParams newTp) {
|
public UnifyType setTypeParams(TypeParams newTp) {
|
||||||
return new ExtendsType(wildcardedType.setTypeParams(newTp));
|
return new ExtendsType(wildcardedType.setTypeParams(newTp));
|
||||||
|
@ -105,7 +105,7 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
if (!sigma2Opt.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
Unifier sigma2 = sigma2Opt.get();
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
|
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams());
|
||||||
if(type.equals(theta2))
|
if(type.equals(theta2))
|
||||||
continue;
|
continue;
|
||||||
Set<UnifyType> theta1s = smaller(theta2);
|
Set<UnifyType> theta1s = smaller(theta2);
|
||||||
@ -205,7 +205,7 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Unifier sigma2 = sigma2Opt.get();
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
|
sigma2.swapPlaceholderSubstitutions(typePrime.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
|
||||||
@ -372,21 +372,6 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isGenericType(UnifyType t) {
|
|
||||||
if(t.getTypeParams().size() == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(!strInheritanceGraph.containsKey(t.getName()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for(UnifyPair pair : pairs)
|
|
||||||
if(pair.getLhsType().equals(t))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> getAllTypesByName(String typeName) {
|
public Set<UnifyType> getAllTypesByName(String typeName) {
|
||||||
if(!strInheritanceGraph.containsKey(typeName))
|
if(!strInheritanceGraph.containsKey(typeName))
|
||||||
|
@ -1,22 +1,42 @@
|
|||||||
package de.dhbwstuttgart.typeinference.unify.model;
|
package de.dhbwstuttgart.typeinference.unify.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operators of pairs of the unification.
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
public enum PairOperator {
|
public enum PairOperator {
|
||||||
|
/**
|
||||||
|
* The smaller operator (T < P) is used to express a subtyping relation between
|
||||||
|
* T and P for example in the finite closure. It is necessarily true.
|
||||||
|
*/
|
||||||
SMALLER,
|
SMALLER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The smallerdot operator (T <. P) is used to express a subtyping relation between
|
||||||
|
* of T and P in a CONSTRAINT during the unification. It is not necessarily true.
|
||||||
|
*/
|
||||||
SMALLERDOT,
|
SMALLERDOT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The smallerdot operator for arguments (T <.? P) is used to express that
|
||||||
|
* T is an element of smArg(P) (or P is an element of grArg(T)) in a CONSTRAINT
|
||||||
|
* during the unification. It is not necessarily true.
|
||||||
|
*/
|
||||||
SMALLERDOTWC,
|
SMALLERDOTWC,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The equalsdot operator (T =. P) is used to express that two types during the unification
|
||||||
|
* should be equal. It is not necessarily true.
|
||||||
|
*/
|
||||||
EQUALSDOT;
|
EQUALSDOT;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case SMALLER:
|
case SMALLER: return "<";
|
||||||
return "<";
|
case SMALLERDOT: return "<.";
|
||||||
case SMALLERDOT:
|
case SMALLERDOTWC: return "<.?";
|
||||||
return "<.";
|
default: return "=."; // EQUALSDOT
|
||||||
case SMALLERDOTWC:
|
|
||||||
return "<.?";
|
|
||||||
default:
|
|
||||||
return "=.";
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
@ -1,48 +1,73 @@
|
|||||||
package de.dhbwstuttgart.typeinference.unify.model;
|
package de.dhbwstuttgart.typeinference.unify.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
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.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unbounded placeholder type.
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
public final class PlaceholderType extends UnifyType{
|
public final class PlaceholderType extends UnifyType{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static list containing the names of all existing placeholders.
|
||||||
|
* Used for generating fresh placeholders.
|
||||||
|
*/
|
||||||
protected static final HashSet<String> EXISTING_PLACEHOLDERS = new HashSet<String>();
|
protected static final HashSet<String> EXISTING_PLACEHOLDERS = new HashSet<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix of auto-generated placeholder names.
|
||||||
|
*/
|
||||||
protected static String nextName = "gen_";
|
protected static String nextName = "gen_";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Random number generator used to generate fresh placeholder name.
|
||||||
|
*/
|
||||||
protected static Random rnd = new Random(43558747548978L);
|
protected static Random rnd = new Random(43558747548978L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this object was auto-generated, false if this object was user-generated.
|
||||||
|
*/
|
||||||
private final boolean IsGenerated;
|
private final boolean IsGenerated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new placeholder type with the specified name.
|
||||||
|
*/
|
||||||
public PlaceholderType(String name) {
|
public PlaceholderType(String name) {
|
||||||
super(name, new TypeParams());
|
super(name, new TypeParams());
|
||||||
EXISTING_PLACEHOLDERS.add(name);
|
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
|
||||||
IsGenerated = false;
|
IsGenerated = false; // This type is user generated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new placeholdertype
|
||||||
|
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.
|
||||||
|
*/
|
||||||
protected PlaceholderType(String name, boolean isGenerated) {
|
protected PlaceholderType(String name, boolean isGenerated) {
|
||||||
super(name, new TypeParams());
|
super(name, new TypeParams());
|
||||||
EXISTING_PLACEHOLDERS.add(name);
|
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
|
||||||
IsGenerated = isGenerated;
|
IsGenerated = isGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a fresh placeholder type with a name that does so far not exist.
|
||||||
|
* A user could later instantiate a type using the same name that is equivalent to this type.
|
||||||
|
* @return A fresh placeholder type.
|
||||||
|
*/
|
||||||
public static PlaceholderType freshPlaceholder() {
|
public static PlaceholderType freshPlaceholder() {
|
||||||
String name = nextName + randomChar();
|
String name = nextName + (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
|
||||||
|
// Add random chars while the name is in use.
|
||||||
while(EXISTING_PLACEHOLDERS.contains(name));
|
while(EXISTING_PLACEHOLDERS.contains(name));
|
||||||
name += randomChar();
|
name += (char) (rnd.nextInt(22) + 97); // Returns random char between 'a' and 'z'
|
||||||
|
|
||||||
return new PlaceholderType(name, true);
|
return new PlaceholderType(name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns random char between 'a' and 'z'
|
* True if this placeholder is auto-generated, false if it is user-generated.
|
||||||
*/
|
*/
|
||||||
private static char randomChar() {
|
|
||||||
return (char) (rnd.nextInt(22) + 97);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isGenerated() {
|
public boolean isGenerated() {
|
||||||
return IsGenerated;
|
return IsGenerated;
|
||||||
}
|
}
|
||||||
@ -59,7 +84,7 @@ public final class PlaceholderType extends UnifyType{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnifyType setTypeParams(TypeParams newTp) {
|
public UnifyType setTypeParams(TypeParams newTp) {
|
||||||
return this;
|
return this; // Placeholders never have params.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,7 +4,13 @@ import java.util.Set;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference type e.q. Integer or List<T>.
|
||||||
|
* @author Florian Steurer
|
||||||
|
*
|
||||||
|
*/
|
||||||
public final class ReferenceType extends UnifyType {
|
public final class ReferenceType extends UnifyType {
|
||||||
|
|
||||||
public ReferenceType(String name, UnifyType... typeParams) {
|
public ReferenceType(String name, UnifyType... typeParams) {
|
||||||
super(name, new TypeParams(typeParams));
|
super(name, new TypeParams(typeParams));
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,23 @@ import java.util.Set;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A super wildcard type e.g. ? super Integer.
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
public final class SuperType extends WildcardType {
|
public final class SuperType extends WildcardType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance "? extends superedType"
|
||||||
|
* @param superedType The type that is supered e.g. Integer in "? super Integer"
|
||||||
|
*/
|
||||||
public SuperType(UnifyType superedType) {
|
public SuperType(UnifyType superedType) {
|
||||||
super("? super " + superedType.getName(), superedType);
|
super("? super " + superedType.getName(), superedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type that is supered e.g. Integer in "? super Integer"
|
||||||
|
*/
|
||||||
public UnifyType getSuperedType() {
|
public UnifyType getSuperedType() {
|
||||||
return wildcardedType;
|
return wildcardedType;
|
||||||
}
|
}
|
||||||
@ -18,11 +30,9 @@ public final class SuperType extends WildcardType {
|
|||||||
return "? super " + wildcardedType;
|
return "? super " + wildcardedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public TypeParams getTypeParams() {
|
* Sets the type parameters of the wildcarded type and returns a new supertype that supers that type.
|
||||||
return wildcardedType.getTypeParams();
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnifyType setTypeParams(TypeParams newTp) {
|
public UnifyType setTypeParams(TypeParams newTp) {
|
||||||
return new SuperType(wildcardedType.setTypeParams(newTp));
|
return new SuperType(wildcardedType.setTypeParams(newTp));
|
||||||
|
@ -5,43 +5,61 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.Menge;
|
import de.dhbwstuttgart.typeinference.Menge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The generic or non-generic parameters of a type e.g. <T> for List<T>
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
public final class TypeParams implements Iterable<UnifyType>{
|
public final class TypeParams implements Iterable<UnifyType>{
|
||||||
|
/**
|
||||||
|
* The array which backs the type parameters.
|
||||||
|
*/
|
||||||
private final UnifyType[] typeParams;
|
private final UnifyType[] typeParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new set of type parameters.
|
||||||
|
* @param types The type parameters.
|
||||||
|
*/
|
||||||
public TypeParams(Menge<UnifyType> types){
|
public TypeParams(Menge<UnifyType> types){
|
||||||
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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new set of type parameters.
|
||||||
|
* @param types The type parameters.
|
||||||
|
*/
|
||||||
public TypeParams(UnifyType... types) {
|
public TypeParams(UnifyType... types) {
|
||||||
typeParams = types;
|
typeParams = types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if every parameter in this object is a placeholder type, false otherwise.
|
||||||
|
*/
|
||||||
public boolean arePlaceholders() {
|
public boolean arePlaceholders() {
|
||||||
for(UnifyType t : typeParams)
|
return Arrays.stream(typeParams).allMatch(x -> x instanceof PlaceholderType);
|
||||||
if(!(t instanceof PlaceholderType))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
String res = "";
|
|
||||||
for(UnifyType t : typeParams)
|
|
||||||
res += t + ",";
|
|
||||||
return "<" + res.substring(0, res.length()-1) + ">";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of the type parameters in this object.
|
||||||
|
* @return number of type parameters, always positive (including 0).
|
||||||
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
return typeParams.length;
|
return typeParams.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this object has size() of zero, false otherwise.
|
||||||
|
*/
|
||||||
public boolean empty() {
|
public boolean empty() {
|
||||||
return typeParams.length == 0;
|
return typeParams.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a unifier to every parameter in this object.
|
||||||
|
* @param unif The applied unifier.
|
||||||
|
* @return A new type parameter object, where the unifier was applied to every parameter.
|
||||||
|
*/
|
||||||
public TypeParams apply(Unifier unif) {
|
public TypeParams apply(Unifier unif) {
|
||||||
UnifyType[] newParams = new UnifyType[typeParams.length];
|
UnifyType[] newParams = new UnifyType[typeParams.length];
|
||||||
for(int i = 0; i < typeParams.length; i++)
|
for(int i = 0; i < typeParams.length; i++)
|
||||||
@ -49,6 +67,10 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
return new TypeParams(newParams);
|
return new TypeParams(newParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the PlaceholderType t is a parameter of this object, or if any parameter
|
||||||
|
* contains t (arbitrary depth of recursion), false otherwise.
|
||||||
|
*/
|
||||||
public boolean occurs(PlaceholderType t) {
|
public boolean occurs(PlaceholderType t) {
|
||||||
for(UnifyType p : typeParams)
|
for(UnifyType p : typeParams)
|
||||||
if(p instanceof PlaceholderType)
|
if(p instanceof PlaceholderType)
|
||||||
@ -60,26 +82,24 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(UnifyType t) {
|
/**
|
||||||
for(UnifyType t1 : typeParams)
|
* Returns the i-th parameter of this object.
|
||||||
if(t1.equals(t1))
|
* @throws ArrayOutOfBoundsException if i > this.size()-1.
|
||||||
return true;
|
*/
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnifyType get(int i) {
|
public UnifyType get(int i) {
|
||||||
return typeParams[i];
|
return typeParams[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @throws ArrayOutOfBoundsException if i > this.size()-1.
|
||||||
|
*/
|
||||||
public TypeParams set(UnifyType t, int idx) {
|
public TypeParams set(UnifyType t, int idx) {
|
||||||
UnifyType[] newparams = Arrays.copyOf(typeParams, typeParams.length);
|
UnifyType[] newparams = Arrays.copyOf(typeParams, typeParams.length);
|
||||||
newparams[idx] = t;
|
newparams[idx] = t;
|
||||||
return new TypeParams(newparams);
|
return new TypeParams(newparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifyType[] toArray() {
|
|
||||||
return Arrays.copyOf(typeParams, typeParams.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<UnifyType> iterator() {
|
public Iterator<UnifyType> iterator() {
|
||||||
@ -107,5 +127,13 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String res = "";
|
||||||
|
for(UnifyType t : typeParams)
|
||||||
|
res += t + ",";
|
||||||
|
return "<" + res.substring(0, res.length()-1) + ">";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,26 @@
|
|||||||
package de.dhbwstuttgart.typeinference.unify.model;
|
package de.dhbwstuttgart.typeinference.unify.model;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/ { // TODO set implementieren
|
* A set of substitutions (s -> t) that is an applicable function to types and pairs.
|
||||||
|
* @author Florian Steurer
|
||||||
|
*/
|
||||||
|
public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<PlaceholderType, UnifyType>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of substitutions that unify a type-term
|
||||||
|
*/
|
||||||
private HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>();
|
private HashMap<PlaceholderType, UnifyType> substitutions = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance with a single substitution (source -> target).
|
||||||
|
* @param The type that is replaced
|
||||||
|
* @param The type that replaces
|
||||||
|
*/
|
||||||
public Unifier(PlaceholderType source, UnifyType target) {
|
public Unifier(PlaceholderType source, UnifyType target) {
|
||||||
substitutions.put(source, target);
|
substitutions.put(source, target);
|
||||||
}
|
}
|
||||||
@ -20,13 +31,23 @@ public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/
|
|||||||
protected Unifier() {
|
protected Unifier() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Unifier Identity() {
|
/**
|
||||||
|
* Creates an unifier that is the identity function (thus has no substitutions).
|
||||||
|
*/
|
||||||
|
public static Unifier identity() {
|
||||||
return new Unifier();
|
return new Unifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(PlaceholderType source, UnifyType target) {
|
/**
|
||||||
|
* Adds a substitution to the unifier from (source -> target)
|
||||||
|
* @param The type that is replaced
|
||||||
|
* @param The type that replaces
|
||||||
|
*/
|
||||||
|
public void add(PlaceholderType source, UnifyType target) {
|
||||||
Unifier tempU = new Unifier(source, target);
|
Unifier tempU = new Unifier(source, target);
|
||||||
|
// Every new substitution must be applied to previously added substitutions
|
||||||
|
// otherwise the unifier needs to be applied multiple times to unify two terms
|
||||||
for(PlaceholderType pt : substitutions.keySet())
|
for(PlaceholderType pt : substitutions.keySet())
|
||||||
substitutions.put(pt, substitutions.get(pt).apply(tempU));
|
substitutions.put(pt, substitutions.get(pt).apply(tempU));
|
||||||
substitutions.put(source, target);
|
substitutions.put(source, target);
|
||||||
@ -37,26 +58,39 @@ public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/
|
|||||||
return t.apply(this);
|
return t.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the unifier to the two terms of the pair.
|
||||||
|
* @return A new pair where the left and right-hand side are applied
|
||||||
|
*/
|
||||||
public UnifyPair apply(UnifyPair p) {
|
public UnifyPair apply(UnifyPair p) {
|
||||||
return new UnifyPair(this.apply(p.getLhsType()), this.apply(p.getRhsType()), p.getPairOp());
|
return new UnifyPair(this.apply(p.getLhsType()), this.apply(p.getRhsType()), p.getPairOp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the typevariable t will be substituted if the unifier is applied.
|
||||||
|
* false otherwise.
|
||||||
|
*/
|
||||||
public boolean hasSubstitute(PlaceholderType t) {
|
public boolean hasSubstitute(PlaceholderType t) {
|
||||||
return substitutions.containsKey(t);
|
return substitutions.containsKey(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type that will replace the typevariable t if the unifier is applied.
|
||||||
|
*/
|
||||||
public UnifyType getSubstitute(PlaceholderType t) {
|
public UnifyType getSubstitute(PlaceholderType t) {
|
||||||
return substitutions.get(t);
|
return substitutions.get(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Entry<PlaceholderType, UnifyType>> getSubstitutions() {
|
/**
|
||||||
return substitutions.entrySet();
|
* Garantuees that if there is a substitutions (a -> b) in this unifier,
|
||||||
}
|
* a is not an element of the targetParams. Substitutions that do not
|
||||||
|
* satisfy this condition, are swapped.
|
||||||
public void swapPlaceholderSubstitutions(UnifyType... targetParams) {
|
*/
|
||||||
|
public void swapPlaceholderSubstitutions(Iterable<UnifyType> targetParams) {
|
||||||
for(UnifyType tph : targetParams) {
|
for(UnifyType tph : targetParams) {
|
||||||
if(!(tph instanceof PlaceholderType))
|
if(!(tph instanceof PlaceholderType))
|
||||||
continue;
|
continue;
|
||||||
|
// Swap a substitutions (a -> b) if a is an element of the target params.
|
||||||
if(substitutions.containsKey(tph) && substitutions.get(tph) instanceof PlaceholderType) {
|
if(substitutions.containsKey(tph) && substitutions.get(tph) instanceof PlaceholderType) {
|
||||||
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
|
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
|
||||||
substitutions.remove(tph);
|
substitutions.remove(tph);
|
||||||
@ -75,5 +109,10 @@ public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/
|
|||||||
result += " }";
|
result += " }";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Entry<PlaceholderType, UnifyType>> iterator() {
|
||||||
|
return substitutions.entrySet().iterator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,14 @@ public abstract class WildcardType extends UnifyType {
|
|||||||
return wildcardedType;
|
return wildcardedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type parameters of the WILDCARDED TYPE.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TypeParams getTypeParams() {
|
||||||
|
return wildcardedType.getTypeParams();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return wildcardedType.hashCode() + getName().hashCode() + 17;
|
return wildcardedType.hashCode() + getName().hashCode() + 17;
|
||||||
|
Loading…
Reference in New Issue
Block a user