Support for FunN in FC added // swap for unifiers

This commit is contained in:
Florian Steurer 2016-04-07 22:24:35 +02:00
parent 284447aad2
commit 53cfb4b046
8 changed files with 132 additions and 22 deletions

View File

@ -65,6 +65,13 @@ public class FiniteClosure implements IFiniteClosure {
*/
@Override
public Set<UnifyType> smaller(UnifyType type) {
if(type instanceof FunNType)
return computeSmallerFunN((FunNType) type);
return computeSmaller(type);
}
private Set<UnifyType> computeSmaller(UnifyType type) {
if(inheritanceGraph.containsKey(type)) {
Set<UnifyType> result = new HashSet<>();
result.add(type);
@ -82,8 +89,7 @@ public class FiniteClosure implements IFiniteClosure {
for (UnifyType param : type.getTypeParams())
paramCandidates.add(smArg(param));
Set<TypeParams> permResult = new HashSet<>();
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
Set<TypeParams> permResult = permuteParams(paramCandidates);
for (TypeParams newParams : permResult)
result1.add(type.setTypeParams(newParams));}
@ -94,16 +100,18 @@ public class FiniteClosure implements IFiniteClosure {
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
for(UnifyType typePrime : result1) {
for (UnifyType theta2 : candidates) {
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
if (!sigma2.isPresent())
for (UnifyType theta2 : candidates) {
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
if (!sigma2Opt.isPresent())
continue;
Unifier sigma2 = sigma2Opt.get();
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
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.get().apply(theta1);
UnifyType sigma1Theta1 = sigma2.apply(theta1);
result2.add(sigma1Theta1);
}
}
@ -118,8 +126,7 @@ public class FiniteClosure implements IFiniteClosure {
for (UnifyType param : t.getTypeParams())
paramCandidates.add(smArg(param));
Set<TypeParams> permResult = new HashSet<>();
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
Set<TypeParams> permResult = permuteParams(paramCandidates);
for (TypeParams newParams : permResult) {
UnifyType tPrime = t.setTypeParams(newParams);
@ -127,19 +134,44 @@ public class FiniteClosure implements IFiniteClosure {
result3.add(t);
else
result3.addAll(smaller(tPrime));
}
}
}
return result3;
}
private Set<UnifyType> computeSmallerFunN(FunNType type) {
Set<UnifyType> result = new HashSet<>();
// if T = T' then T <=* T'
result.add(type);
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
paramCandidates.add(smaller(type.getTypeParams().get(0)));
for (int i = 1; i < type.getTypeParams().size(); i++)
paramCandidates.add(greater(type.getTypeParams().get(i)));
Set<TypeParams> permResult = permuteParams(paramCandidates);
for (TypeParams newParams : permResult)
result.add(type.setTypeParams(newParams));
return result;
}
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*/
@Override
public Set<UnifyType> greater(UnifyType type) {
public Set<UnifyType> greater(UnifyType type) {
if(type instanceof FunNType)
return computeGreaterFunN((FunNType) type);
return computeGreater(type);
}
protected Set<UnifyType> computeGreater(UnifyType type) {
IUnify unify = new MartelliMontanariUnify();
Set<UnifyType> result1 = new HashSet<>();
@ -166,22 +198,25 @@ public class FiniteClosure implements IFiniteClosure {
for(UnifyType typePrime : result1) {
for (UnifyType theta2 : candidates) {
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
if (!sigma2.isPresent())
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
if (!sigma2Opt.isPresent())
continue;
if(type.equals(theta2))
continue;
Unifier sigma2 = sigma2Opt.get();
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
Set<UnifyType> theta1s = greater(theta2);
for (UnifyType theta1 : theta1s) {
// Because only the most general type is calculated, sigma1 = sigma2
UnifyType sigma1Theta1 = sigma2.get().apply(theta1);
UnifyType sigma1Theta1 = sigma2.apply(theta1);
result2.add(sigma1Theta1);
}
}
}
}
result2.addAll(result1);
result2.addAll(result1);
Set<UnifyType> result3 = new HashSet<>();
for(UnifyType t : result2) {
@ -203,8 +238,13 @@ public class FiniteClosure implements IFiniteClosure {
}
return result3;
}
protected Set<UnifyType> computeGreaterFunN(FunNType type) {
// TODO Auto-generated method stub
return null;
}
@Override
public Set<UnifyType> grArg(UnifyType type) {
@ -370,6 +410,12 @@ public class FiniteClosure implements IFiniteClosure {
return result;
}
protected Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
Set<TypeParams> result = new HashSet<>();
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
return result;
}
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
if(candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length)));

View File

@ -43,13 +43,26 @@ public class FunNType extends UnifyType {
Set<UnifyType> grArg(IFiniteClosure fc) {
return fc.grArg(this);
}
@Override
UnifyType apply(Unifier unif) {
// TODO Auto-generated method stub
return null;
}
// TODO equals und hashcode
@Override
public int hashCode() {
return 31 + typeParams.hashCode();
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof FunNType))
return false;
FunNType other = (FunNType) obj;
return other.getTypeParams().equals(typeParams);
}
}

View File

@ -22,7 +22,7 @@ public final class ReferenceType extends UnifyType {
Set<UnifyType> grArg(IFiniteClosure fc) {
return fc.grArg(this);
}
@Override
UnifyType apply(Unifier unif) {
return new ReferenceType(typeName, typeParams.apply(unif));
@ -35,7 +35,7 @@ public final class ReferenceType extends UnifyType {
@Override
public int hashCode() {
return typeName.hashCode();
return 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
}
@Override

View File

@ -5,8 +5,6 @@ import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
public final class SuperType extends WildcardType {
public SuperType(UnifyType superedType) {
super("? super " + superedType.getName(), superedType, superedType.getTypeParams());
}

View File

@ -77,6 +77,9 @@ public final class TypeParams implements Iterable<UnifyType>{
return new TypeParams(newparams);
}
public UnifyType[] toArray() {
return Arrays.copyOf(typeParams, typeParams.length);
}
@Override
public Iterator<UnifyType> iterator() {

View File

@ -52,6 +52,18 @@ public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/
public Set<Entry<PlaceholderType, UnifyType>> getSubstitutions() {
return substitutions.entrySet();
}
public void swapPlaceholderSubstitutions(UnifyType... targetParams) {
for(UnifyType tph : targetParams) {
if(!(tph instanceof PlaceholderType))
continue;
if(substitutions.containsKey(tph) && substitutions.get(tph) instanceof PlaceholderType) {
PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph);
substitutions.remove(tph);
substitutions.put(newLhs, tph);
}
}
}
@Override
public String toString() {

View File

@ -169,6 +169,7 @@ public class FiniteClosureTest {
setExtT1, hashSetExtT1, treeSetExtT1, linkedHashSetExtT1
}).collect(Collectors.toSet()));
System.out.println(fc.smaller(setExtT1));
Assert.assertEquals(expectedResult, fc.smaller(setExtT1));
/*
@ -395,7 +396,37 @@ public class FiniteClosureTest {
Assert.assertEquals(82, actual.size());
Assert.assertTrue(actual.contains(myMapExtInt));
Assert.assertTrue(actual.contains(myMapInt));
Assert.assertTrue(actual.contains(myMapInt));
/*
* Test Case 16:
*
* smaller(FunN<Number, Number, Number>) =
* { FunN<Number, Number, Number>, FunN<Number, Object, Number>,
* FunN<Number, Number, Object>, FunN<Number, Object, Object>,
* FunN<Integer, Number, Number>, FunN<Integer, Object, Number>,
* FunN<Integer, Number, Object>, FunN<Integer, Object, Object> }
*/
UnifyType object = tf.getSimpleType("Object");
fcb = new FiniteClosureBuilder();
fcb.add(integer, number);
fcb.add(number, object);
fc = fcb.getCollectionExample();
UnifyType funNNumber = tf.getFunNType(number, number, number);
expectedResult = new HashSet<>(Arrays.stream(new UnifyType[] {
tf.getFunNType(number, number, number), tf.getFunNType(number, object, number),
tf.getFunNType(number, number, object), tf.getFunNType(number, object, object),
tf.getFunNType(integer, number, number), tf.getFunNType(integer, object, number),
tf.getFunNType(integer, number, object), tf.getFunNType(integer, object, object),
}).collect(Collectors.toSet()));
actual = fc.smaller(funNNumber);
System.out.println(actual);
Assert.assertEquals(expectedResult, actual);
}
@Test

View File

@ -4,9 +4,11 @@ import java.util.Arrays;
import java.util.stream.Collectors;
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;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class TypeFactory {
@ -34,4 +36,9 @@ public class TypeFactory {
public PlaceholderType getPlaceholderType(String name) {
return new PlaceholderType(name);
}
public FunNType getFunNType(UnifyType... typeParams) {
return FunNType.getFunNType(new TypeParams(typeParams));
}
}