smaller / smArg / grArg / TODO: greater

This commit is contained in:
Florian Steurer 2016-03-26 00:03:26 +01:00
parent a5b86dc84c
commit bbfd8699e8
3 changed files with 31 additions and 84 deletions

View File

@ -24,11 +24,13 @@ public class FiniteClosure implements IFiniteClosure {
}
public FiniteClosure(Set<MPair> pairs) {
inheritanceGraph = new HashMap<Type, Node<Type>>();
// Build the transitive closure of the inheritance tree
for(MPair pair : pairs) {
if(!pair.getLhsType().getTypeParams().arePlaceholders())
throw new IllegalArgumentException("The finite closure only has pairs of the form D<a1, a2, ... , an> <= C<...>");
if(pair.getPairOp() != PairOperator.SMALLER)
continue;
@ -66,14 +68,15 @@ public class FiniteClosure implements IFiniteClosure {
*/
@Override
public Set<Type> smaller(Type type) {
// - if(T < T') then T <=* T'
Set<Type> result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : new HashSet<>();
Set<Type> result = new HashSet<>();
result.add(type);
// - if(T < T') then T <=* T'
// if T1 <=* T2 then sigma1(T1) <=* sigma1(T2)
// where foreach type var a in T2:
// sigma1(T1) <=* sigma2(T2)
/*if(strInheritanceGraph.containsKey(type.getName())) {
//If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied)
if(strInheritanceGraph.containsKey(type.getName())) {
IUnify unify = new MartelliMontanariUnify();
HashSet<Node<Type>> candidateNodes = strInheritanceGraph.get(type.getName());
for(Node<Type> candidateNode : candidateNodes) {
@ -81,67 +84,27 @@ public class FiniteClosure implements IFiniteClosure {
Optional<Unifier> sigma2 = unify.unify(theta2, type);
if(!sigma2.isPresent())
continue;
for(Type sigma1theta1 : candidateNode.getContentOfDescendants()) {
Type theta1 = sigma2.get().apply(sigma1theta1);
Set<Type> theta1s = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : smaller(theta2);
for(Type theta1 : theta1s) {
// Because only the most general type is calculated, sigma1 = sigma2
Type sigma1Theta1 = sigma2.get().apply(theta1);
ArrayList<Set<Type>> paramCandidates = new ArrayList<>();
for(Type param : sigma1Theta1.getTypeParams())
paramCandidates.add(smArg(param));
Set<TypeParams> permResult = new HashSet<>();
permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]);
for(TypeParams newParams : permResult)
result.add(sigma1Theta1.setTypeParams(newParams));
}
}
}*/
if(type.getTypeParams().size() == 0)
return result;
ArrayList<Set<Type>> paramCandidates = new ArrayList<>();
for(Type param : type.getTypeParams()) {
if(param instanceof ExtendsType || param instanceof SuperType) {
Set<Type> pc = param.smArg(this);
paramCandidates.add(pc);
} else {
HashSet<Type> pc = new HashSet<>();
pc.add(param);
paramCandidates.add(pc);
}
}
Set<TypeParams> permResult = new HashSet<>();
permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]);
for(TypeParams newParams : permResult)
result.add(type.setTypeParams(newParams));
return result;
}
/**
* @param t1
* @param t2
* @return
*/
protected Optional<Unifier> match(Type t1, Type t2) {
if(!t1.getName().equals(t2.getName()))
return Optional.empty();
TypeParams t1Params = t1.getTypeParams();
TypeParams t2Params = t2.getTypeParams();
if(t1Params.size() != t2Params.size())
return Optional.empty();
Unifier result = new Unifier();
for(int i = 0; i < t1Params.size(); i++) {
Type t1i = t1Params.get(i);
Type t2i = t2Params.get(i);
boolean equal = t1i.equals(t2i);
if(!equal && !(t2i instanceof PlaceholderType))
return Optional.empty();
if(!equal && t2i instanceof PlaceholderType)
result.Add((PlaceholderType) t2i, t1i);
}
return Optional.of(result);
}
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
@ -182,9 +145,6 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(SimpleType type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
@ -201,9 +161,6 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(ExtendsType type) {
if(!inheritanceGraph.containsKey(type.getExtendedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
@ -216,9 +173,6 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(SuperType type) {
if(!inheritanceGraph.containsKey(type.getSuperedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
@ -245,13 +199,10 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> smArg(SimpleType type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
smaller(type).forEach(x -> result.add(new ExtendsType(x)));
// smaller(type).forEach(x -> result.add(new ExtendsType(x))); TODO inkorrekt? daher erstmal raus
return result;
}
@ -263,9 +214,6 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> smArg(ExtendsType type) {
if(!inheritanceGraph.containsKey(type.getExtendedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
@ -283,9 +231,6 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> smArg(SuperType type) {
if(!inheritanceGraph.containsKey(type.getSuperedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
result.add(type);
@ -304,8 +249,8 @@ public class FiniteClosure implements IFiniteClosure {
public Set<Type> smArg(PlaceholderType type) {
HashSet<Type> result = new HashSet<>();
result.add(type);
result.add(new SuperType(type));
result.add(new ExtendsType(type));
//result.add(new SuperType(type)); TODO inkorrekt, daher erstmal raus
//result.add(new ExtendsType(type));
return result;
}

View File

@ -8,8 +8,6 @@ import java.util.function.Function;
public class Unifier implements Function<Type, Type> /*, Set<MPair>*/ { // TODO set implementieren
private HashMap<PlaceholderType, Type> substitutions = new HashMap<>();
public static Unifier IDENTITY = new Unifier();
public Unifier(PlaceholderType source, Type target) {
substitutions.put(source, target);
}
@ -21,6 +19,10 @@ public class Unifier implements Function<Type, Type> /*, Set<MPair>*/ { // TODO
}
public static Unifier Identity() {
return new Unifier();
}
public void Add(PlaceholderType source, Type target) {
Unifier tempU = new Unifier(source, target);
for(PlaceholderType pt : substitutions.keySet())

View File

@ -26,7 +26,7 @@ public class MartelliMontanariUnify implements IUnify {
@Override
public Optional<Unifier> unify(Set<Type> terms) {
if(terms.size() < 2)
return Optional.of(Unifier.IDENTITY);
return Optional.of(Unifier.Identity());
ArrayList<MPair> termsQ = new ArrayList<MPair>();
Iterator<Type> iter = terms.iterator();
@ -37,7 +37,7 @@ public class MartelliMontanariUnify implements IUnify {
prev = next;
}
Unifier mgu = Unifier.IDENTITY;
Unifier mgu = Unifier.Identity();
int idx = 0;
while(idx < termsQ.size()) {
@ -101,7 +101,7 @@ public class MartelliMontanariUnify implements IUnify {
TypeParams rhsTypeParams = rhs.getTypeParams();
TypeParams lhsTypeParams = lhs.getTypeParams();
if(!rhs.getName().equals(lhs.getName()) || rhsTypeParams.size() != lhsTypeParams.size())
if(rhsTypeParams.size() != lhsTypeParams.size() || (!rhs.getName().equals(lhs.getName()) && rhsTypeParams.size() != 0))
return null; // conflict
if(rhsTypeParams.size() == 0 || lhsTypeParams.size() == 0)