This commit is contained in:
Florian Steurer 2015-11-01 22:12:41 +01:00
parent 931fb01d74
commit 92d81ac097
17 changed files with 460 additions and 194 deletions

View File

@ -15,7 +15,7 @@
* Test b <. a, a <. b
*/
-
- Transitiven Abschluss von FC bilden um schneller Subtypen bestimmen zu können
@ -23,8 +23,17 @@
- Equals der Typen schreiben um instanceof Prüfungen zu vermeiden
- Refactoring der Klassen Menge und Pair erlaubt?
++++++++++++++++++++++++++++++++++++++++++++++
SPEED UP
Instanceof wird verwendet da:
-> Entscheidung für diese Lösung, da 2-Fach-Visitor oder DoubleDispatch Pattern
enorm viele überladene Methoden zur folge hätten, nicht intuitiv wären und die rules in die Typen verschoben hätten.
Gilt reduce für alle Typen oder nur für simple und tphs? (Vermutlich nur s und tph sonst bräuchte man keine upLow regel)
EED UP
- Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...)
- Erase vor Reduce
- Rechenarm vor rechenintensiv

View File

@ -1,5 +0,0 @@
package de.dhbwstuttgart.typeinference;
public interface IPair{
}

View File

@ -31,7 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.WildcardType;
// Klasse, die ein Paar in der Menge Eq speichern kann
// ino.end
// ino.class.Pair.26540.declaration
public class Pair implements IPair, Serializable, DeepCloneable
public class Pair implements Serializable, DeepCloneable
// ino.end
// ino.class.Pair.26540.body
{

View File

@ -1,7 +1,31 @@
package de.dhbwstuttgart.typeinference.unify.interfaces;
import de.dhbwstuttgart.typeinference.IPair;
import java.util.Set;
import de.dhbwstuttgart.typinference.unify.model.Type;
public interface IFiniteClosure<T extends IPair> {
public interface IFiniteClosure {
/**
* Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument.
*/
public Set<Type> smaller(Type type);
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*/
public Set<Type> greater(Type type);
public Set<Type> grArg(Type type);
public Set<Type> smArg(Type type);
public boolean isSubtype(Type subT, Type superT);
public boolean isSupertype(Type superT, Type subT);
public boolean isInGrArg(Type grArgT, Type t);
public boolean isInSmArg(Type smArgT, Type t);
}

View File

@ -0,0 +1,25 @@
package de.dhbwstuttgart.typeinference.unify.interfaces;
import de.dhbwstuttgart.typinference.unify.model.MPair;
public interface IRuleSet {
public boolean reduceUp(MPair pair);
public boolean reduceLow(MPair pair);
public boolean reduceUpLow(MPair pair);
public boolean reduceExt(MPair pair);
public boolean reduceSup(MPair pair);
public boolean reduceEq(MPair pair);
public boolean reduce1(MPair pair);
public boolean reduce2(MPair pair);
public boolean erase1(MPair pair);
public boolean erase2(MPair pair);
public boolean erase3(MPair pair);
public MPair swap(MPair pair);
public MPair adapt(MPair pair);
public MPair adaptExt(MPair pair);
public MPair adaptSup(MPair pair);
}

View File

@ -0,0 +1,69 @@
package de.dhbwstuttgart.typeinference.unifynew;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
/**
* First three bits indicate the meta type:
* 000b = 0 = Simpletype
* 001b = 1 = Extends
* 010b = 2 = Super
* 011b = 3 = Type Placeholder
* 100b = 4 = Function
*
* @author DH10STF
*
*/
public class Mapping {
private static final int ST_MASK = 0;
private static final int EXTENDS_MASK = 536870912;
private static final int SUPER_MASK = 1073741824;
private static final int TPH_MASK = 1610612736;
private static final int FUN_MASK = -2147483648;
private static HashMap<Type, Type> mapping;
public Set<Type> createMapping(Iterable<Type> types) {
mapping = new HashMap<>();
Iterator<Type> iterator = types.iterator();
while(iterator.hasNext() && mapping.size() <= 536870911)
createMapping(iterator.next());
return mapping.keySet();
}
private void createMapping(Type type) {
/*if(type instanceof RefType) {
Set<Type> params = ((RefType) type).get_ParaList();
params.stream().forEach(x -> createMapping(x));
}
*/
int typeId = mapping.size();
if(type instanceof RefType)
typeId |= ST_MASK;
else if(type instanceof SuperWildcardType)
typeId |= SUPER_MASK;
else if(type instanceof ExtendsWildcardType)
typeId |= EXTENDS_MASK;
else if(type instanceof TypePlaceholder)
typeId |= TPH_MASK;
else if(type instanceof FunN)
typeId |= FUN_MASK;
//mapping.put(new MType())
}
}

View File

@ -0,0 +1,167 @@
package de.dhbwstuttgart.typeinference.unifynew;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
import de.dhbwstuttgart.typinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typinference.unify.model.MPair;
import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator;
import de.dhbwstuttgart.typinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typinference.unify.model.SimpleType;
import de.dhbwstuttgart.typinference.unify.model.SuperType;
import de.dhbwstuttgart.typinference.unify.model.Type;
public class RuleSet implements IRuleSet{
protected IFiniteClosure finiteClosure;
public RuleSet(IFiniteClosure fc) {
finiteClosure = fc;
}
@Override
public boolean reduceUp(MPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOT)
return false;
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof SuperType))
return false;
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType))
return false;
pair.setRhsType(((SuperType) rhsType).GetSuperedType());
return true;
}
@Override
public boolean reduceLow(MPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOT)
return false;
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof ExtendsType))
return false;
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType))
return false;
pair.setLhsType(((ExtendsType) lhsType).GetExtendedType());
return true;
}
@Override
public boolean reduceUpLow(MPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOT)
return false;
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof ExtendsType))
return false;
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof SuperType))
return false;
pair.setLhsType(((ExtendsType) lhsType).GetExtendedType());
pair.setRhsType(((SuperType) rhsType).GetSuperedType());
return true;
}
@Override
public boolean reduceExt(MPair pair) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean reduceSup(MPair pair) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean reduceEq(MPair pair) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean reduce1(MPair pair) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean reduce2(MPair pair) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean erase1(MPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOT)
return false;
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType))
return false;
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType))
return false;
return finiteClosure.isSubtype(lhsType, rhsType);
}
@Override
public boolean erase2(MPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
return false;
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType))
return false;
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof ExtendsType))
return false;
return finiteClosure.isInGrArg(lhsType, ((ExtendsType) rhsType).GetExtendedType());
}
@Override
public boolean erase3(MPair pair) {
if(pair.getPairOp() != PairOperator.EQUALSDOT)
return false;
return pair.getLhsType().equals(pair.getRhsType());
}
@Override
public MPair swap(MPair pair) {
// TODO Auto-generated method stub
return null;
}
@Override
public MPair adapt(MPair pair) {
// TODO Auto-generated method stub
return null;
}
@Override
public MPair adaptExt(MPair pair) {
// TODO Auto-generated method stub
return null;
}
@Override
public MPair adaptSup(MPair pair) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,31 +0,0 @@
package de.dhbwstuttgart.typeinference.unifynew;
import de.dhbwstuttgart.syntaxtree.type.Type;
/*
* TODO: Ist es möglich das Mapping austauschbar zu machen indem man ein IMapper Interface erstellt?
* Zu einem späteren Zeitpunkt prüfen.
*
* interface IMapper<T>
* Menge<T> createMapping(Menge<Type>)
* Menge<Type> resolveMapping(Menge<T>)
* bool isTPH(T)
* bool isSimpleType(T)
* ...
*
*
* Mapping Pair To long
*
* 0-1 Pair Operator
* 2-3 LHS type (00 = Simple, 01 = extends, 02 = super, 03 = function)
* 4-5 RHS type (00 = Simple, 01 = extends, 02 = super, 03 = function)
* 6-35 LHS Simple Type (500.000.000 possible simple types)
* 36-64 RHS Simple Type (500.000.000 possible simple types)
*/
public class TypeMapper {
public int[] createMapping(Iterable<Type> types) {
return new int[0];
}
}

View File

@ -69,8 +69,10 @@ public class Unify {
* 2.1 Apply all rules repeatedly except for erase rules. If
* the application of a rule creates new pairs, check immediately
* against the erase rules.
* 2.2 Always use the ordering (IComparable) of the mapped types as the permutation.
* This is saving the time to generate and test permutations.
*
* Regel funktioniert so nicht
* 2.2 Always use the ordering (IComparable) of the mapped types as the permutation.
* This is saving the time to generate and test permutations.
*/

View File

@ -0,0 +1,9 @@
package de.dhbwstuttgart.typinference.unify.model;
public class ExtendsType extends Type {
public Type GetExtendedType() {
return null;
// TODO
}
}

View File

@ -4,32 +4,32 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator;
public class FiniteClosure<T extends MPair> implements IFiniteClosure<T> {
public class FiniteClosure implements IFiniteClosure {
private HashMap<MType, Node<MType>> inheritanceGraph;
private HashMap<Type, Node<Type>> inheritanceGraph;
public FiniteClosure(Set<T> pairs) {
public FiniteClosure(Set<MPair> pairs) {
inheritanceGraph = new HashMap<MType, Node<MType>>();
inheritanceGraph = new HashMap<Type, Node<Type>>();
// Build the transitive closure of the inheritance tree
for(T pair : pairs) {
for(MPair pair : pairs) {
// TODO smaller oder smallerExtends?
if(pair.GetPairOp() != PairOperator.SmallerExtends)
if(pair.getPairOp() != PairOperator.SMALLER)
continue;
// Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.GetType1()))
inheritanceGraph.put(pair.GetType1(), new Node<MType>(pair.GetType1()));
if(!inheritanceGraph.containsKey(pair.GetType2()))
inheritanceGraph.put(pair.GetType2(), new Node<MType>(pair.GetType2()));
if(!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<Type>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<Type>(pair.getRhsType()));
Node<MType> childNode = inheritanceGraph.get(pair.GetType2());
Node<MType> parentNode = inheritanceGraph.get(pair.GetType1());
Node<Type> childNode = inheritanceGraph.get(pair.getRhsType());
Node<Type> parentNode = inheritanceGraph.get(pair.getLhsType());
// Add edge
parentNode.AddDescendant(childNode);
@ -43,7 +43,8 @@ public class FiniteClosure<T extends MPair> implements IFiniteClosure<T> {
* Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument.
*/
public Set<MType> smaller(MType type) {
@Override
public Set<Type> smaller(Type type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
@ -54,18 +55,41 @@ public class FiniteClosure<T extends MPair> implements IFiniteClosure<T> {
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*/
public Set<MType> greater(MType type) {
@Override
public Set<Type> greater(Type type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
return inheritanceGraph.get(type).getContentOfPredecessors();
}
public Set<MType> grArg(MType type) {
@Override
public Set<Type> grArg(Type type) {
throw new NotImplementedException();
}
public Set<MType> smArg(MType type) {
@Override
public Set<Type> smArg(Type type) {
throw new NotImplementedException();
}
@Override
public boolean isSubtype(Type subT, Type superT) {
return smaller(superT).contains(subT);
}
@Override
public boolean isSupertype(Type superT, Type subT) {
return smaller(superT).contains(subT);
}
@Override
public boolean isInGrArg(Type grArgT, Type t) {
return grArg(grArgT).contains(t);
}
@Override
public boolean isInSmArg(Type smArgT, Type t) {
return smArg(smArgT).contains(t);
}
}

View File

@ -1,35 +1,48 @@
package de.dhbwstuttgart.typinference.unify.model;
import de.dhbwstuttgart.typeinference.IPair;
import de.dhbwstuttgart.typeinference.Pair.PairOperator;
public class MPair {
public class MPair implements IPair {
private MType type1;
private MType type2;
private PairOperator pairOp;
public MPair(MType t1, MType t2) {
type1 = t1;
type2 = t2;
pairOp = PairOperator.Smaller;
public enum PairOperator {
SMALLER,
SMALLERDOT,
SMALLERDOTWC,
EQUALS,
EQUALSDOT
}
public MPair(MType t1, MType t2, PairOperator op) {
private Type type1;
private Type type2;
private PairOperator pairOp;
public MPair(Type t1, Type t2) {
type1 = t1;
type2 = t2;
pairOp = PairOperator.SMALLER;
}
public MPair(Type t1, Type t2, PairOperator op) {
type1 = t1;
type2 = t2;
pairOp = op;
}
public MType GetType1() {
public Type getLhsType() {
return type1;
}
public MType GetType2() {
public Type getRhsType() {
return type2;
}
public PairOperator GetPairOp() {
public void setLhsType(Type newLhs) {
type1 = newLhs;
}
public void setRhsType(Type newRhs) {
type2 = newRhs;
}
public PairOperator getPairOp() {
return pairOp;
}
@ -42,9 +55,9 @@ public class MPair implements IPair {
MPair other = (MPair) obj;
return other.GetPairOp() == pairOp
&& other.GetType1().equals(type1)
&& other.GetType2().equals(type2);
return other.getPairOp() == pairOp
&& other.getLhsType().equals(type1)
&& other.getRhsType().equals(type2);
}
@Override

View File

@ -1,115 +0,0 @@
package de.dhbwstuttgart.typinference.unify.model;
import java.util.Arrays;
/**
*
* @author DH10STF
*
* TODO SPEEDUP
* - Caching of the results
* - Global map from int to mtype und mtype[] array mit int[] austauschen und wenn nötig nachschlagen
* - Vorteil: Jeder Typ wäre globally unique -> Memory effizient
* - Nachteil: Nachschlagen kostet zeit, Dictionary muss gemanaged werden
* - TypeArgs in HashCode berechnung stärker / weniger einbeziehen
*/
public class MType implements Comparable<MType>{
/**
* First three bits indicate the meta type:
* 000b = 0 = Simpletype
* 001b = 1 = Extends
* 010b = 2 = Super
* 011b = 3 = Type Placeholder
* 100b = 4 = Function
*
* Advantages of using a unique identifier for mapping:
* - Fast checks (Equality and Membership)
* - Easy Hashing
* - Memory efficient
*/
private int identifier = 0;
private MType[] typeArgs = null;
/**
* Used to mask the first three bits of an integer.
* -53870912d == 1110000...00b
*/
private final int mask = -53870912;
public MType(int identifier, MType... typeArgs) {
this.identifier = identifier;
this.typeArgs = Arrays.copyOf(typeArgs, typeArgs.length);
Arrays.sort(typeArgs);
}
public boolean isSimpleType() {
return (identifier & mask) == 0;
}
public boolean isExtendsType() {
return (identifier & mask) == 1;
}
public boolean isSuperType() {
return (identifier & mask) == 2;
}
public boolean isTypePlaceholder() {
return (identifier & mask) == 3;
}
public boolean isFunctionType() {
return (identifier & mask) == 4;
}
public int getIdentifier() {
return identifier;
}
public MType[] getTypeArgs() {
return typeArgs;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof MType))
return false;
if(obj.hashCode() != hashCode())
return false;
MType other = (MType) obj;
if(other.getIdentifier() != identifier)
return false;
MType[] otherTypeArgs = other.getTypeArgs();
if(otherTypeArgs.length != typeArgs.length)
return false;
for(int i = 0; i < typeArgs.length; i++)
if(!typeArgs[i].equals(otherTypeArgs[i]))
return false;
return true;
}
@Override
public int hashCode() {
return 17 + 31 * identifier + 31 * typeArgs.length;
}
@Override
public int compareTo(MType o) {
// Comparison is insensitive to type arguments.
if(o.getIdentifier() > identifier)
return -1;
if(o.getIdentifier() < identifier)
return 1;
return 0;
}
}

View File

@ -0,0 +1,5 @@
package de.dhbwstuttgart.typinference.unify.model;
public class PlaceholderType extends Type{
}

View File

@ -0,0 +1,5 @@
package de.dhbwstuttgart.typinference.unify.model;
public class SimpleType extends Type {
}

View File

@ -0,0 +1,8 @@
package de.dhbwstuttgart.typinference.unify.model;
public class SuperType extends Type {
public Type GetSuperedType() {
return null;
}
}

View File

@ -0,0 +1,57 @@
package de.dhbwstuttgart.typinference.unify.model;
public abstract class Type implements Comparable<Type> {
protected int identifier = 0;
protected Type[] typeArgs = null;
public int getIdentifier() {
return identifier;
}
public Type[] getTypeArgs() {
return typeArgs;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Type))
return false;
if(obj.hashCode() != hashCode())
return false;
Type other = (Type) obj;
if(other.getIdentifier() != identifier)
return false;
Type[] otherTypeArgs = other.getTypeArgs();
if(otherTypeArgs.length != typeArgs.length)
return false;
for(int i = 0; i < typeArgs.length; i++)
if(!typeArgs[i].equals(otherTypeArgs[i]))
return false;
return true;
}
@Override
public int hashCode() {
return 17 + 31 * identifier + 31 * typeArgs.length;
}
@Override
public int compareTo(Type o) {
// Comparison is insensitive to type arguments.
if(o.getIdentifier() > identifier)
return -1;
if(o.getIdentifier() < identifier)
return 1;
return 0;
}
}