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
|
@Override
|
||||||
public Set<UnifyType> smaller(UnifyType type) {
|
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)) {
|
if(inheritanceGraph.containsKey(type)) {
|
||||||
Set<UnifyType> result = new HashSet<>();
|
Set<UnifyType> result = new HashSet<>();
|
||||||
result.add(type);
|
result.add(type);
|
||||||
@ -82,8 +89,7 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
for (UnifyType param : type.getTypeParams())
|
for (UnifyType param : type.getTypeParams())
|
||||||
paramCandidates.add(smArg(param));
|
paramCandidates.add(smArg(param));
|
||||||
|
|
||||||
Set<TypeParams> permResult = new HashSet<>();
|
Set<TypeParams> permResult = permuteParams(paramCandidates);
|
||||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
|
||||||
|
|
||||||
for (TypeParams newParams : permResult)
|
for (TypeParams newParams : permResult)
|
||||||
result1.add(type.setTypeParams(newParams));}
|
result1.add(type.setTypeParams(newParams));}
|
||||||
@ -94,16 +100,18 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
|
|
||||||
for(UnifyType typePrime : result1) {
|
for(UnifyType typePrime : result1) {
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
||||||
if (!sigma2.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
|
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
|
||||||
if(type.equals(theta2))
|
if(type.equals(theta2))
|
||||||
continue;
|
continue;
|
||||||
Set<UnifyType> theta1s = smaller(theta2);
|
Set<UnifyType> theta1s = smaller(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
|
||||||
UnifyType sigma1Theta1 = sigma2.get().apply(theta1);
|
UnifyType sigma1Theta1 = sigma2.apply(theta1);
|
||||||
result2.add(sigma1Theta1);
|
result2.add(sigma1Theta1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,8 +126,7 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
for (UnifyType param : t.getTypeParams())
|
for (UnifyType param : t.getTypeParams())
|
||||||
paramCandidates.add(smArg(param));
|
paramCandidates.add(smArg(param));
|
||||||
|
|
||||||
Set<TypeParams> permResult = new HashSet<>();
|
Set<TypeParams> permResult = permuteParams(paramCandidates);
|
||||||
permuteParams(paramCandidates, 0, permResult, new UnifyType[paramCandidates.size()]);
|
|
||||||
|
|
||||||
for (TypeParams newParams : permResult) {
|
for (TypeParams newParams : permResult) {
|
||||||
UnifyType tPrime = t.setTypeParams(newParams);
|
UnifyType tPrime = t.setTypeParams(newParams);
|
||||||
@ -127,19 +134,44 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
result3.add(t);
|
result3.add(t);
|
||||||
else
|
else
|
||||||
result3.addAll(smaller(tPrime));
|
result3.addAll(smaller(tPrime));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result3;
|
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.
|
* Returns all types of the finite closure that are supertypes of the argument.
|
||||||
* @return The set of supertypes of the argument.
|
* @return The set of supertypes of the argument.
|
||||||
*/
|
*/
|
||||||
@Override
|
@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();
|
IUnify unify = new MartelliMontanariUnify();
|
||||||
Set<UnifyType> result1 = new HashSet<>();
|
Set<UnifyType> result1 = new HashSet<>();
|
||||||
|
|
||||||
@ -166,22 +198,25 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
|
|
||||||
for(UnifyType typePrime : result1) {
|
for(UnifyType typePrime : result1) {
|
||||||
for (UnifyType theta2 : candidates) {
|
for (UnifyType theta2 : candidates) {
|
||||||
Optional<Unifier> sigma2 = unify.unify(typePrime, theta2);
|
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2);
|
||||||
if (!sigma2.isPresent())
|
if (!sigma2Opt.isPresent())
|
||||||
continue;
|
continue;
|
||||||
if(type.equals(theta2))
|
if(type.equals(theta2))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Unifier sigma2 = sigma2Opt.get();
|
||||||
|
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams().toArray());
|
||||||
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
|
||||||
UnifyType sigma1Theta1 = sigma2.get().apply(theta1);
|
UnifyType sigma1Theta1 = sigma2.apply(theta1);
|
||||||
result2.add(sigma1Theta1);
|
result2.add(sigma1Theta1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result2.addAll(result1);
|
result2.addAll(result1);
|
||||||
|
|
||||||
Set<UnifyType> result3 = new HashSet<>();
|
Set<UnifyType> result3 = new HashSet<>();
|
||||||
for(UnifyType t : result2) {
|
for(UnifyType t : result2) {
|
||||||
@ -203,8 +238,13 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result3;
|
return result3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Set<UnifyType> computeGreaterFunN(FunNType type) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> grArg(UnifyType type) {
|
public Set<UnifyType> grArg(UnifyType type) {
|
||||||
@ -370,6 +410,12 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
return result;
|
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) {
|
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||||
if(candidates.size() == idx) {
|
if(candidates.size() == idx) {
|
||||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||||
|
@ -43,13 +43,26 @@ public class FunNType extends UnifyType {
|
|||||||
Set<UnifyType> grArg(IFiniteClosure fc) {
|
Set<UnifyType> grArg(IFiniteClosure fc) {
|
||||||
return fc.grArg(this);
|
return fc.grArg(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
UnifyType apply(Unifier unif) {
|
UnifyType apply(Unifier unif) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
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) {
|
Set<UnifyType> grArg(IFiniteClosure fc) {
|
||||||
return fc.grArg(this);
|
return fc.grArg(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
UnifyType apply(Unifier unif) {
|
UnifyType apply(Unifier unif) {
|
||||||
return new ReferenceType(typeName, typeParams.apply(unif));
|
return new ReferenceType(typeName, typeParams.apply(unif));
|
||||||
@ -35,7 +35,7 @@ public final class ReferenceType extends UnifyType {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return typeName.hashCode();
|
return 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,8 +5,6 @@ import java.util.Set;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
|
|
||||||
public final class SuperType extends WildcardType {
|
public final class SuperType extends WildcardType {
|
||||||
|
|
||||||
|
|
||||||
public SuperType(UnifyType superedType) {
|
public SuperType(UnifyType superedType) {
|
||||||
super("? super " + superedType.getName(), superedType, superedType.getTypeParams());
|
super("? super " + superedType.getName(), superedType, superedType.getTypeParams());
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,9 @@ public final class TypeParams implements Iterable<UnifyType>{
|
|||||||
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() {
|
||||||
|
@ -52,6 +52,18 @@ public class Unifier implements Function<UnifyType, UnifyType> /*, Set<MPair>*/
|
|||||||
public Set<Entry<PlaceholderType, UnifyType>> getSubstitutions() {
|
public Set<Entry<PlaceholderType, UnifyType>> getSubstitutions() {
|
||||||
return substitutions.entrySet();
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -169,6 +169,7 @@ public class FiniteClosureTest {
|
|||||||
setExtT1, hashSetExtT1, treeSetExtT1, linkedHashSetExtT1
|
setExtT1, hashSetExtT1, treeSetExtT1, linkedHashSetExtT1
|
||||||
}).collect(Collectors.toSet()));
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
System.out.println(fc.smaller(setExtT1));
|
||||||
Assert.assertEquals(expectedResult, fc.smaller(setExtT1));
|
Assert.assertEquals(expectedResult, fc.smaller(setExtT1));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -395,7 +396,37 @@ public class FiniteClosureTest {
|
|||||||
|
|
||||||
Assert.assertEquals(82, actual.size());
|
Assert.assertEquals(82, actual.size());
|
||||||
Assert.assertTrue(actual.contains(myMapExtInt));
|
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
|
@Test
|
||||||
|
@ -4,9 +4,11 @@ import java.util.Arrays;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
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.PlaceholderType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
|
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
|
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||||
|
|
||||||
public class TypeFactory {
|
public class TypeFactory {
|
||||||
@ -34,4 +36,9 @@ public class TypeFactory {
|
|||||||
public PlaceholderType getPlaceholderType(String name) {
|
public PlaceholderType getPlaceholderType(String name) {
|
||||||
return new PlaceholderType(name);
|
return new PlaceholderType(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunNType getFunNType(UnifyType... typeParams) {
|
||||||
|
return FunNType.getFunNType(new TypeParams(typeParams));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user