step 4 rule 1

This commit is contained in:
Florian Steurer 2016-03-14 14:46:10 +01:00
parent 863904a4e8
commit 6acc3c1366
8 changed files with 113 additions and 38 deletions

View File

@ -36,6 +36,11 @@ public final class ExtendsType extends Type {
return extendedType.getTypeParams(); return extendedType.getTypeParams();
} }
@Override
public Type setTypeParams(TypeParams newTp) {
return new ExtendsType(extendedType.setTypeParams(newTp));
}
@Override @Override
Set<Type> smArg(IFiniteClosure fc) { Set<Type> smArg(IFiniteClosure fc) {
return fc.smArg(this); return fc.smArg(this);

View File

@ -20,6 +20,11 @@ public final class PlaceholderType extends Type{
return fc.grArg(this); return fc.grArg(this);
} }
@Override
public Type setTypeParams(TypeParams newTp) {
return this;
}
@Override @Override
public int hashCode() { public int hashCode() {
return typeName.hashCode(); return typeName.hashCode();

View File

@ -28,6 +28,11 @@ public final class SimpleType extends Type {
return new SimpleType(typeName, typeParams.apply(unif)); return new SimpleType(typeName, typeParams.apply(unif));
} }
@Override
public Type setTypeParams(TypeParams newTp) {
return new SimpleType(new String(typeName), newTp);
}
@Override @Override
public int hashCode() { public int hashCode() {
return typeName.hashCode(); return typeName.hashCode();

View File

@ -27,6 +27,11 @@ public final class SuperType extends Type {
return superedType.getTypeParams(); return superedType.getTypeParams();
} }
@Override
public Type setTypeParams(TypeParams newTp) {
return new SuperType(superedType.setTypeParams(newTp));
}
@Override @Override
Set<Type> smArg(IFiniteClosure fc) { Set<Type> smArg(IFiniteClosure fc) {
return fc.smArg(this); return fc.smArg(this);

View File

@ -27,6 +27,8 @@ public abstract class Type {
return typeParams; return typeParams;
} }
public abstract Type setTypeParams(TypeParams newTp);
abstract Set<Type> smArg(IFiniteClosure fc); abstract Set<Type> smArg(IFiniteClosure fc);
abstract Set<Type> grArg(IFiniteClosure fc); abstract Set<Type> grArg(IFiniteClosure fc);

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap; import java.util.HashMap;
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<Type, Type> { public class Unifier implements Function<Type, Type> {
@ -44,6 +45,10 @@ public class Unifier implements Function<Type, Type> {
return substitutions.get(t); return substitutions.get(t);
} }
public Set<Entry<PlaceholderType, Type>> getSubstitutions() {
return substitutions.entrySet();
}
@Override @Override
public String toString() { public String toString() {
String result = "{ "; String result = "{ ";

View File

@ -1,11 +1,13 @@
package de.dhbwstuttgart.typeinference.unifynew; package de.dhbwstuttgart.typeinference.unifynew;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -24,6 +26,7 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.Type; import de.dhbwstuttgart.typeinference.unify.model.Type;
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
/** /**
@ -225,48 +228,47 @@ public class Unify {
// Case 1: (a <. Theta') // Case 1: (a <. Theta')
if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) { if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) {
Type thetaPrime = pair.getRhsType();
Set<MPair> set = new HashSet<>();
IUnify unify = new MartelliMontanariUnify(); IUnify unify = new MartelliMontanariUnify();
Set<Type> possibleCs = fc.getAllTypes(rhsType.getName()); //Set<Type> cs = fc.getAllTypes(rhsType.getName());
Type c = rhsType;
//Set<Type> thetaQs = cs.stream().flatMap(x -> fc.smaller(x).stream()).collect(Collectors.toCollection(HashSet::new));
Set<Type> thetaQs = fc.smaller(c);
Set<Type> thetaQPrimes = new HashSet<>();
TypeParams cParams = c.getTypeParams();
if(cParams.size() == 0)
thetaQPrimes.add(c);
else {
ArrayList<Set<Type>> candidateParams = new ArrayList<>();
for(Type param : cParams)
candidateParams.add(fc.grArg(param));
Set<TypeParams> permutations = new HashSet<TypeParams>();
permuteParams(candidateParams, 0, permutations, new Type[candidateParams.size()]);
for(TypeParams tp : permutations)
thetaQPrimes.add(c.setTypeParams(tp));
}
/*IUnify unify = new MartelliMontanariUnify(); for(Type tqp : thetaQPrimes) {
Optional<Unifier> opt = unify.unify(tqp, thetaPrime);
if(opt.isPresent()) {
Unifier unifier = opt.get();
Set<Entry<PlaceholderType, Type>> substitutions = unifier.getSubstitutions();
for(Entry<PlaceholderType, Type> sigma : substitutions)
set.add(new MPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
for(Type tq : thetaQs) {
Set<Type> smaller = fc.smaller(unifier.apply(tq));
smaller.stream().map(x -> new MPair(lhsType, x, PairOperator.EQUALSDOT)).forEach(x -> set.add(x));
}
}
}
Set<Type> possibleCs = fc.getAllTypes(rhsType.getName()); result.add(set);
Set<Type> possibleThetas = possibleCs.stream()
.flatMap(x -> fc.smaller(x).stream())
.collect(Collectors.toCollection(HashSet::new));
Set<Type> possibleThetaPrimes = possibleThetas.stream()
.flatMap(x -> getAllInstantiations(x, fc).stream())
.collect(Collectors.toCollection(HashSet::new));
*/
// TODO
/*Set<Unifier> unifiers = possibleThetaPrimes.stream()
.map(x -> unify.unify(x, rhsType))
.filter(x -> x.isPresent())
.flatMap(x -> x.get().stream())
.map(x -> new Unifier(x.getLhsType(), x.getRhsType()))
.collect(Collectors.toCollection(HashSet::new));
Set<Type> thetas = new HashSet<>();
for(Unifier sigma : unifiers)
for(Type thetaQuer : possibleThetas)
thetas.addAll(fc.smaller(sigma.apply(thetaQuer)));
Set<MPair> resultSet = new HashSet<>();
thetas.forEach(x -> resultSet.add(new MPair(lhsType, x, PairOperator.EQUALSDOT)));
unifiers.forEach(x -> resultSet.add(new MPair(x.getSource(), x.getTarget(), PairOperator.EQUALSDOT)));
result.add(resultSet);
// TODO Speedup - Potenzial durch auschließen unmöglicher kombinationen (z.B. wenn in theta' eine Variable festgelegt ist)
// TODO speedup durch pipelining mit streams
// TODO speedup teure berechnungen mit proxy rauszögern
*/
} }
// Case 2: (a <.? ? ext Theta') // Case 2: (a <.? ? ext Theta')
@ -285,7 +287,7 @@ public class Unify {
// Case 4: (a <.? Theta') // Case 4: (a <.? Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType) { else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType) {
Set<MPair> set = new HashSet<>(); Set<MPair> set = new HashSet<>();
set.add(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT)); set.add(new MPair(lhsType, rhsType, PairOperator.EQUALSDOT));
result.add(set); result.add(set);
} }
@ -322,6 +324,20 @@ public class Unify {
return result; return result;
} }
protected void permuteParams(ArrayList<Set<Type>> candidates, int idx, Set<TypeParams> result, Type[] current) {
if(candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
return;
}
Set<Type> localCandidates = candidates.get(idx);
for(Type t : localCandidates) {
current[idx] = t;
permuteParams(candidates, idx+1, result, current);
}
}
private Set<Type> getAllInstantiations(Type t, IFiniteClosure fc) { private Set<Type> getAllInstantiations(Type t, IFiniteClosure fc) {
Set<Type> result = new HashSet<>(); Set<Type> result = new HashSet<>();
result.add(t); result.add(t);

View File

@ -1,5 +1,6 @@
package unify; package unify;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -8,6 +9,8 @@ import org.junit.Test;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.MPair;
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.Type;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unifynew.Unify; import de.dhbwstuttgart.typeinference.unifynew.Unify;
public class UnifyTest extends Unify { public class UnifyTest extends Unify {
@ -21,6 +24,7 @@ public class UnifyTest extends Unify {
//fcb.add(tf.getSimpleType("Number"), tf.getSimpleType("Object")); //fcb.add(tf.getSimpleType("Number"), tf.getSimpleType("Object"));
fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number"));
fcb.add(tf.getSimpleType("Double"), tf.getSimpleType("Number")); fcb.add(tf.getSimpleType("Double"), tf.getSimpleType("Number"));
//fcb.add(tf.getSimpleType("List", "T"));
IFiniteClosure fc = fcb.getCollectionExample(); IFiniteClosure fc = fcb.getCollectionExample();
@ -31,9 +35,9 @@ public class UnifyTest extends Unify {
// Double <. B // Double <. B
// B <. Object // B <. Object
eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT)); eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT));
eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Number")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Number")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT));
//eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "C"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "C"), PairOperator.SMALLERDOT));
//eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("Integer"), PairOperator.SMALLERDOT)); eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("List", tf.getSimpleType("Number")), PairOperator.SMALLERDOT));
//eq.add(new MPair(tf.getSimpleType("Number"), tf.getPlaceholderType("A"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getSimpleType("Number"), tf.getPlaceholderType("A"), PairOperator.SMALLERDOT));
//eq.add(new MPair(tf.getPlaceholderType("A"), tf.getPlaceholderType("C"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getPlaceholderType("A"), tf.getPlaceholderType("C"), PairOperator.SMALLERDOT));
//eq.add(new MPair(tf.getSimpleType("Double"), tf.getPlaceholderType("B"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getSimpleType("Double"), tf.getPlaceholderType("B"), PairOperator.SMALLERDOT));
@ -53,4 +57,32 @@ public class UnifyTest extends Unify {
} }
@Test
public void permuteParamsTest() {
TypeFactory tf = new TypeFactory();
ArrayList<Set<Type>> candidates = new ArrayList<>();
Set<Type> p1 = new HashSet<>();
p1.add(tf.getPlaceholderType("p11"));
p1.add(tf.getExtendsType(tf.getSimpleType("p12")));
p1.add(tf.getSimpleType("p13"));
Set<Type> p2 = new HashSet<>();
p2.add(tf.getPlaceholderType("p21"));
p2.add(tf.getPlaceholderType("p22"));
Set<Type> p3 = new HashSet<>();
p3.add(tf.getSimpleType("p31", "T"));
p3.add(tf.getSimpleType("p32"));
candidates.add(p1);
candidates.add(p2);
candidates.add(p3);
Set<TypeParams> result = new HashSet<>();
permuteParams(candidates, 0, result, new Type[candidates.size()]);
System.out.println(result);
}
} }