forked from JavaTX/JavaCompilerCore
Support for FunN in FC added // swap for unifiers
This commit is contained in:
parent
284447aad2
commit
53cfb4b046
@ -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)));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user