From b0153be1cd89cee6fe9bc8f5db79206965bb11d5 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 24 Oct 2015 17:47:46 +0200 Subject: [PATCH 01/47] . --- notizen/stf/Notes | 14 +++- .../unify/interfaces/IFiniteClosure.java | 5 ++ .../unify/interfaces/ITypeMapper.java | 7 ++ .../typeinference/unifynew/TypeMapper.java | 31 +++++++ .../typeinference/unifynew/Unify.java | 68 +++++++++++++++ .../unify/model/FiniteClosure.java | 7 ++ .../typinference/unify/model/MPair.java | 22 +++++ .../typinference/unify/model/MType.java | 84 +++++++++++++++++++ test/unify/UnifyTest.java | 1 - 9 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java create mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/ITypeMapper.java create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/Unify.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/MPair.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/MType.java diff --git a/notizen/stf/Notes b/notizen/stf/Notes index c9fe69a5..81d1c211 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -13,4 +13,16 @@ - Wie kommen die Mengen des Unify-Algorithmus zustande? Siehe test: /* * Test b <. a, a <. b - */ \ No newline at end of file + */ + + + + + +- Equals der Typen schreiben um instanceof Prüfungen zu vermeiden + + +SPEED UP + - Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...) + - Erase vor Reduce + - Rechenarm vor rechenintensiv \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java new file mode 100644 index 00000000..1270c8ce --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -0,0 +1,5 @@ +package de.dhbwstuttgart.typeinference.unify.interfaces; + +public interface IFiniteClosure { + +} diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/ITypeMapper.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/ITypeMapper.java new file mode 100644 index 00000000..85efc20a --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/ITypeMapper.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.typeinference.unify.interfaces; + +import de.dhbwstuttgart.typeinference.Menge; + +public interface ITypeMapper { + +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java b/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java new file mode 100644 index 00000000..e1fa193f --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java @@ -0,0 +1,31 @@ +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 + * Menge createMapping(Menge) + * Menge resolveMapping(Menge) + * 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 types) { + return new int[0]; + } + +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java new file mode 100644 index 00000000..789feacb --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -0,0 +1,68 @@ +package de.dhbwstuttgart.typeinference.unifynew; + +import java.util.HashSet; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.Pair; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.MPair; + +/** + * Implementierung des Unifikationsalgorithmus. + * @author Florian Steurer + */ +public class Unify { + + public Menge> unify(Menge eq, IFiniteClosure fc) { + /* + * Preparations: Create Mapping + */ + Set eq0 = null; + + + /* + * Step 1: Repeated application of reduce, adapt, erase, swap + */ + Set eq1 = applyTypeUnificationRules(eq0, fc); + + + /* + * Step 2: Create subset of pairs where both sides are TPH + */ + + /* + * Step 3: Create subset of pairs that where not included in Step 2 + */ + + /* + * Step 4: Magic + */ + + /* + * Step 5: Repeated substitution + */ + + /* + * Step 6: a) Restart for pairs where subst was applied + * b) Union over everything + */ + + /* + * Step 7: Filter result for solved pairs + */ + + throw new NotImplementedException(); + } + + private Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { + + boolean changedInLastIteration = true; + + HashSet + + + throw new NotImplementedException(); + } +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java new file mode 100644 index 00000000..f0e90fdc --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.typinference.unify.model; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + +public class FiniteClosure implements IFiniteClosure { + +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java new file mode 100644 index 00000000..49e905af --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -0,0 +1,22 @@ +package de.dhbwstuttgart.typinference.unify.model; + +import de.dhbwstuttgart.typeinference.Pair.PairOperator; + +public class MPair { + + public final MType TYPE_1; + public final MType TYPE_2; + public final PairOperator PAIR_OP; + + public MPair(MType t1, MType t2) { + TYPE_1 = t1; + TYPE_2 = t2; + PAIR_OP = PairOperator.SmallerExtends; + } + + public MPair(MType t1, MType t2, PairOperator pairOp) { + TYPE_1 = t1; + TYPE_2 = t2; + PAIR_OP = pairOp; + } +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MType.java b/src/de/dhbwstuttgart/typinference/unify/model/MType.java new file mode 100644 index 00000000..c24b549d --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/MType.java @@ -0,0 +1,84 @@ +package de.dhbwstuttgart.typinference.unify.model; + +import java.util.Arrays; + +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; + +/** + * + * @author DH10STF + * + * SPEEDUP + * - Caching of the results + */ +public class 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) + * - Perfect Hashing + */ + private int identifier = 0; + + private int[] typeArgs = null; + + /** + * Used to mask the first three bits of an integer. + * -53870912d == 1110000...00b + */ + private final int mask = -53870912; + + public MType(int identifier, int...typeArgs) { + this.identifier = identifier; + + if(typeArgs.length != 0) { + 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; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof MType)) + return false; + + throw new NotImplementedException(); + } + + @Override + public int hashCode() { + // TODO Auto-generated method stub + return super.hashCode(); + } +} diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 59671c90..93f0d9c0 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -18,7 +18,6 @@ public class UnifyTest { @Test public void unifyTestSimpleTypes() { - // Init Factories and Builders UnifyTypeFactory typeFactory = new UnifyTypeFactory(); Unify_FC_TTO_Builder fcBuilder = new Unify_FC_TTO_Builder(); From 3d38ea2e086c4cc564456284dde8d0e4b1f0aabe Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 24 Oct 2015 18:53:11 +0200 Subject: [PATCH 02/47] hashcode, equals and compareTo --- .../typinference/unify/model/MType.java | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MType.java b/src/de/dhbwstuttgart/typinference/unify/model/MType.java index c24b549d..60c99dcf 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MType.java @@ -2,17 +2,19 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Arrays; -import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; - /** * * @author DH10STF * - * SPEEDUP + * 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 { - +public class MType implements Comparable{ + /** * First three bits indicate the meta type: * 000b = 0 = Simpletype @@ -23,11 +25,12 @@ public class MType { * * Advantages of using a unique identifier for mapping: * - Fast checks (Equality and Membership) - * - Perfect Hashing + * - Easy Hashing + * - Memory efficient */ private int identifier = 0; - private int[] typeArgs = null; + private MType[] typeArgs = null; /** * Used to mask the first three bits of an integer. @@ -35,13 +38,10 @@ public class MType { */ private final int mask = -53870912; - public MType(int identifier, int...typeArgs) { + public MType(int identifier, MType... typeArgs) { this.identifier = identifier; - - if(typeArgs.length != 0) { - this.typeArgs = Arrays.copyOf(typeArgs, typeArgs.length); - Arrays.sort(typeArgs); - } + this.typeArgs = Arrays.copyOf(typeArgs, typeArgs.length); + Arrays.sort(typeArgs); } public boolean isSimpleType() { @@ -68,17 +68,48 @@ public class MType { 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; - throw new NotImplementedException(); + 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() { - // TODO Auto-generated method stub - return super.hashCode(); + return 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; } } From 4539faf2411b67214a645ba6d9a98f3e18b02eac Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 24 Oct 2015 19:05:48 +0200 Subject: [PATCH 03/47] hashcodes and work on Mpair --- .../typinference/unify/model/MPair.java | 51 +++++++++++++++---- .../typinference/unify/model/MType.java | 2 +- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index 49e905af..abf6c2c7 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -4,19 +4,50 @@ import de.dhbwstuttgart.typeinference.Pair.PairOperator; public class MPair { - public final MType TYPE_1; - public final MType TYPE_2; - public final PairOperator PAIR_OP; + private MType type1; + private MType type2; + private PairOperator pairOp; public MPair(MType t1, MType t2) { - TYPE_1 = t1; - TYPE_2 = t2; - PAIR_OP = PairOperator.SmallerExtends; + type1 = t1; + type2 = t2; + pairOp = PairOperator.Smaller; } - public MPair(MType t1, MType t2, PairOperator pairOp) { - TYPE_1 = t1; - TYPE_2 = t2; - PAIR_OP = pairOp; + public MPair(MType t1, MType t2, PairOperator op) { + type1 = t1; + type2 = t2; + pairOp = op; } + + public MType GetType1() { + return type1; + } + + public MType GetType2() { + return type2; + } + + public PairOperator GetPairOp() { + return pairOp; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof MPair)) + return false; + if(obj.hashCode() != hashCode()) + return false; + + MPair other = (MPair) obj; + + return other.GetPairOp() == pairOp + && other.GetType1().equals(type1) + && other.GetType2().equals(type2); + } + + @Override + public int hashCode() { + return 17 + 31 * type1.hashCode() + 31 * type2.hashCode() + 31 * pairOp.hashCode(); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MType.java b/src/de/dhbwstuttgart/typinference/unify/model/MType.java index 60c99dcf..35da6b1a 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MType.java @@ -98,7 +98,7 @@ public class MType implements Comparable{ @Override public int hashCode() { - return identifier + 31 * typeArgs.length; + return 17 + 31 * identifier + 31 * typeArgs.length; } @Override From 5f9452cfda5fc949f5f82fba3026b18502aa6864 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 24 Oct 2015 19:46:51 +0200 Subject: [PATCH 04/47] commenting and rule application --- .../typeinference/unifynew/Unify.java | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 789feacb..3158f6e7 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -1,6 +1,11 @@ package de.dhbwstuttgart.typeinference.unifynew; +import java.util.AbstractQueue; +import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Queue; import java.util.Set; import de.dhbwstuttgart.typeinference.Menge; @@ -56,13 +61,58 @@ public class Unify { throw new NotImplementedException(); } - private Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { + private LinkedHashSet applyTypeUnificationRules(Set eq, IFiniteClosure fc) { - boolean changedInLastIteration = true; + /* + * Strategy for better performance + * + * 1. Erase all erasable rules + * 2. Apply all possible rules to a single pair, then move it to the result set. + * Iterating over pairs first, then iterating over rules prevents the algorithm + * from trying to apply rules to a "finished" pair over and over. + * 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. + */ - HashSet + LinkedHashSet targetSet = new LinkedHashSet(); + + ArrayList eqQueue = new ArrayList<>(); + + /* + * Erase all erasable pairs or add them to the queue for further processing + */ + for(MPair pair : eq) + if(!(erase1(pair) || erase2(pair) || erase3(pair))) + eqQueue.add(pair); + + while(!eq.isEmpty()) { + boolean ruleWasApplied = true; + + MPair pair = eqQueue.get(0); + + while(ruleWasApplied) { + ruleWasApplied = false; + + + } + } throw new NotImplementedException(); } + + private boolean erase1(MPair pair) { + return true; + } + + private boolean erase2(MPair pair) { + return true; + } + + private boolean erase3(MPair pair) { + return true; + } } From 11fc7a4512a087109de308766913b7ccce3d8bf6 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 24 Oct 2015 20:32:05 +0200 Subject: [PATCH 05/47] . --- notizen/stf/Notes | 10 +++-- src/de/dhbwstuttgart/typeinference/IPair.java | 5 +++ src/de/dhbwstuttgart/typeinference/Pair.java | 2 +- .../unify/interfaces/IFiniteClosure.java | 4 +- .../typeinference/unifynew/Unify.java | 4 -- .../unify/model/FiniteClosure.java | 10 ++++- .../typinference/unify/model/MPair.java | 3 +- .../typinference/unify/model/Node.java | 38 +++++++++++++++++++ 8 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/de/dhbwstuttgart/typeinference/IPair.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/Node.java diff --git a/notizen/stf/Notes b/notizen/stf/Notes index 81d1c211..940b13f8 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -14,13 +14,15 @@ /* * Test b <. a, a <. b */ + + + - - - - +- Transitiven Abschluss von FC bilden um schneller Subtypen bestimmen zu können + - Problem: 2 FCs für Pairs und MPairs durch das Mapping - Equals der Typen schreiben um instanceof Prüfungen zu vermeiden +- Refactoring der Klassen Menge und Pair erlaubt? SPEED UP - Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...) diff --git a/src/de/dhbwstuttgart/typeinference/IPair.java b/src/de/dhbwstuttgart/typeinference/IPair.java new file mode 100644 index 00000000..a98693cd --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/IPair.java @@ -0,0 +1,5 @@ +package de.dhbwstuttgart.typeinference; + +public interface IPair { + +} diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index dcb13958..40dd3acc 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -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 Serializable, DeepCloneable +public class Pair implements IPair, Serializable, DeepCloneable // ino.end // ino.class.Pair.26540.body { diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 1270c8ce..dd527653 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; -public interface IFiniteClosure { +import de.dhbwstuttgart.typeinference.IPair; +public interface IFiniteClosure { + } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 3158f6e7..9bbf8e26 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -1,11 +1,7 @@ package de.dhbwstuttgart.typeinference.unifynew; -import java.util.AbstractQueue; import java.util.ArrayList; -import java.util.HashSet; import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Queue; import java.util.Set; import de.dhbwstuttgart.typeinference.Menge; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index f0e90fdc..7c10d8ff 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -1,7 +1,13 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.IPair; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class FiniteClosure implements IFiniteClosure { - +public class FiniteClosure implements IFiniteClosure { + + public FiniteClosure(Set pairs) { + + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index abf6c2c7..0259e92e 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -1,8 +1,9 @@ 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; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Node.java b/src/de/dhbwstuttgart/typinference/unify/model/Node.java new file mode 100644 index 00000000..a7c6e534 --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/Node.java @@ -0,0 +1,38 @@ +package de.dhbwstuttgart.typinference.unify.model; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class Node { + private T content; + + private HashSet> predecessors = new HashSet<>(); + private HashSet> descendants = new HashSet<>(); + + public Node(T content) { + this.content = content; + } + + public void AddDescendant(Node descendant) { + descendants.add(descendant); + } + + public void AddPredecessor(Node predecessor) { + predecessors.add(predecessor); + predecessor.AddDescendant(this); + } + + public T getContent() { + return content; + } + + public Set> getPredecessors() { + return null; + } + + public Set> getDescendants() { + return null; + } +} From 931fb01d7413bb05c73a5d3db33cd465796b6d4b Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 25 Oct 2015 11:12:36 +0100 Subject: [PATCH 06/47] finite closure --- src/de/dhbwstuttgart/typeinference/IPair.java | 4 +- .../unify/model/FiniteClosure.java | 62 ++++++++++++++++++- .../typinference/unify/model/Node.java | 22 +++++-- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/IPair.java b/src/de/dhbwstuttgart/typeinference/IPair.java index a98693cd..2a1c8056 100644 --- a/src/de/dhbwstuttgart/typeinference/IPair.java +++ b/src/de/dhbwstuttgart/typeinference/IPair.java @@ -1,5 +1,5 @@ package de.dhbwstuttgart.typeinference; -public interface IPair { - +public interface IPair{ + } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 7c10d8ff..c26166e6 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -1,13 +1,71 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.HashMap; +import java.util.HashSet; import java.util.Set; -import de.dhbwstuttgart.typeinference.IPair; +import de.dhbwstuttgart.typeinference.Pair.PairOperator; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class FiniteClosure implements IFiniteClosure { +public class FiniteClosure implements IFiniteClosure { + + private HashMap> inheritanceGraph; public FiniteClosure(Set pairs) { + inheritanceGraph = new HashMap>(); + + // Build the transitive closure of the inheritance tree + for(T pair : pairs) { + // TODO smaller oder smallerExtends? + if(pair.GetPairOp() != PairOperator.SmallerExtends) + continue; + + // Add nodes if not already in the graph + if(!inheritanceGraph.containsKey(pair.GetType1())) + inheritanceGraph.put(pair.GetType1(), new Node(pair.GetType1())); + if(!inheritanceGraph.containsKey(pair.GetType2())) + inheritanceGraph.put(pair.GetType2(), new Node(pair.GetType2())); + + Node childNode = inheritanceGraph.get(pair.GetType2()); + Node parentNode = inheritanceGraph.get(pair.GetType1()); + + // Add edge + parentNode.AddDescendant(childNode); + + // Add edges to build the transitive closure + parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode)); + } + } + + /** + * Returns all types of the finite closure that are subtypes of the argument. + * @return The set of subtypes of the argument. + */ + public Set smaller(MType type) { + if(!inheritanceGraph.containsKey(type)) + return new HashSet<>(); + + return inheritanceGraph.get(type).getContentOfDescendants(); + } + + /** + * Returns all types of the finite closure that are supertypes of the argument. + * @return The set of supertypes of the argument. + */ + public Set greater(MType type) { + if(!inheritanceGraph.containsKey(type)) + return new HashSet<>(); + + return inheritanceGraph.get(type).getContentOfPredecessors(); + } + + public Set grArg(MType type) { + throw new NotImplementedException(); + } + + public Set smArg(MType type) { + throw new NotImplementedException(); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Node.java b/src/de/dhbwstuttgart/typinference/unify/model/Node.java index a7c6e534..f0eaa635 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Node.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Node.java @@ -1,9 +1,8 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; +import java.util.stream.Collectors; public class Node { private T content; @@ -16,10 +15,17 @@ public class Node { } public void AddDescendant(Node descendant) { + if(descendants.contains(descendant)) + return; + descendants.add(descendant); + descendant.AddPredecessor(this); } public void AddPredecessor(Node predecessor) { + if(predecessors.contains(predecessor)) + return; + predecessors.add(predecessor); predecessor.AddDescendant(this); } @@ -29,10 +35,18 @@ public class Node { } public Set> getPredecessors() { - return null; + return predecessors; } public Set> getDescendants() { - return null; + return descendants; + } + + public Set getContentOfDescendants() { + return descendants.stream().map(x -> x.getContent()).collect(Collectors.toSet()); + } + + public Set getContentOfPredecessors() { + return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet()); } } From 92d81ac09739dc2569fad7a9b831a583734d93b0 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 1 Nov 2015 22:12:41 +0100 Subject: [PATCH 07/47] rules --- notizen/stf/Notes | 13 +- src/de/dhbwstuttgart/typeinference/IPair.java | 5 - src/de/dhbwstuttgart/typeinference/Pair.java | 2 +- .../unify/interfaces/IFiniteClosure.java | 28 ++- .../unify/interfaces/IRuleSet.java | 25 +++ .../typeinference/unifynew/Mapping.java | 69 ++++++++ .../typeinference/unifynew/RuleSet.java | 167 ++++++++++++++++++ .../typeinference/unifynew/TypeMapper.java | 31 ---- .../typeinference/unifynew/Unify.java | 6 +- .../typinference/unify/model/ExtendsType.java | 9 + .../unify/model/FiniteClosure.java | 58 ++++-- .../typinference/unify/model/MPair.java | 51 ++++-- .../typinference/unify/model/MType.java | 115 ------------ .../unify/model/PlaceholderType.java | 5 + .../typinference/unify/model/SimpleType.java | 5 + .../typinference/unify/model/SuperType.java | 8 + .../typinference/unify/model/Type.java | 57 ++++++ 17 files changed, 460 insertions(+), 194 deletions(-) delete mode 100644 src/de/dhbwstuttgart/typeinference/IPair.java create mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java delete mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java delete mode 100644 src/de/dhbwstuttgart/typinference/unify/model/MType.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/SuperType.java create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/Type.java diff --git a/notizen/stf/Notes b/notizen/stf/Notes index 940b13f8..515019a7 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -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 \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/IPair.java b/src/de/dhbwstuttgart/typeinference/IPair.java deleted file mode 100644 index 2a1c8056..00000000 --- a/src/de/dhbwstuttgart/typeinference/IPair.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.dhbwstuttgart.typeinference; - -public interface IPair{ - -} diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index 40dd3acc..dcb13958 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -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 { diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index dd527653..0dd264a5 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -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 { +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 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 greater(Type type); + + public Set grArg(Type type); + + public Set 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); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java new file mode 100644 index 00000000..eb23e17f --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -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); +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java b/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java new file mode 100644 index 00000000..d21c5b60 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Mapping.java @@ -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 mapping; + + public Set createMapping(Iterable types) { + mapping = new HashMap<>(); + + Iterator 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 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()) + } + +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java new file mode 100644 index 00000000..d0c6e272 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -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; + } + +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java b/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java deleted file mode 100644 index e1fa193f..00000000 --- a/src/de/dhbwstuttgart/typeinference/unifynew/TypeMapper.java +++ /dev/null @@ -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 - * Menge createMapping(Menge) - * Menge resolveMapping(Menge) - * 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 types) { - return new int[0]; - } - -} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 9bbf8e26..75427372 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -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. */ diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java new file mode 100644 index 00000000..ca7f5c32 --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.typinference.unify.model; + +public class ExtendsType extends Type { + + public Type GetExtendedType() { + return null; + // TODO + } +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index c26166e6..5d326b47 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -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 implements IFiniteClosure { +public class FiniteClosure implements IFiniteClosure { - private HashMap> inheritanceGraph; + private HashMap> inheritanceGraph; - public FiniteClosure(Set pairs) { + public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // 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(pair.GetType1())); - if(!inheritanceGraph.containsKey(pair.GetType2())) - inheritanceGraph.put(pair.GetType2(), new Node(pair.GetType2())); + if(!inheritanceGraph.containsKey(pair.getLhsType())) + inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); + if(!inheritanceGraph.containsKey(pair.getRhsType())) + inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); - Node childNode = inheritanceGraph.get(pair.GetType2()); - Node parentNode = inheritanceGraph.get(pair.GetType1()); + Node childNode = inheritanceGraph.get(pair.getRhsType()); + Node parentNode = inheritanceGraph.get(pair.getLhsType()); // Add edge parentNode.AddDescendant(childNode); @@ -43,7 +43,8 @@ public class FiniteClosure implements IFiniteClosure { * Returns all types of the finite closure that are subtypes of the argument. * @return The set of subtypes of the argument. */ - public Set smaller(MType type) { + @Override + public Set smaller(Type type) { if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); @@ -54,18 +55,41 @@ public class FiniteClosure implements IFiniteClosure { * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. */ - public Set greater(MType type) { + @Override + public Set greater(Type type) { if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); return inheritanceGraph.get(type).getContentOfPredecessors(); } - public Set grArg(MType type) { + @Override + public Set grArg(Type type) { throw new NotImplementedException(); } - public Set smArg(MType type) { + @Override + public Set 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); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index 0259e92e..0ef52ee4 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -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 diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MType.java b/src/de/dhbwstuttgart/typinference/unify/model/MType.java deleted file mode 100644 index 35da6b1a..00000000 --- a/src/de/dhbwstuttgart/typinference/unify/model/MType.java +++ /dev/null @@ -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{ - - /** - * 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; - } -} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java new file mode 100644 index 00000000..7ef1f38b --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -0,0 +1,5 @@ +package de.dhbwstuttgart.typinference.unify.model; + +public class PlaceholderType extends Type{ + +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java new file mode 100644 index 00000000..0ff65f96 --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -0,0 +1,5 @@ +package de.dhbwstuttgart.typinference.unify.model; + +public class SimpleType extends Type { + +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java new file mode 100644 index 00000000..fcd8534c --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -0,0 +1,8 @@ +package de.dhbwstuttgart.typinference.unify.model; + +public class SuperType extends Type { + + public Type GetSuperedType() { + return null; + } +} diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java new file mode 100644 index 00000000..72ac1839 --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -0,0 +1,57 @@ +package de.dhbwstuttgart.typinference.unify.model; + +public abstract class Type implements Comparable { + + 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; + } +} \ No newline at end of file From a86b70e6726ab5a3465261c0209be422321987d4 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 6 Nov 2015 21:02:43 +0100 Subject: [PATCH 08/47] reduce1 regel --- notizen/stf/Notes | 3 + .../unify/interfaces/IFiniteClosure.java | 4 + .../unify/interfaces/IRuleSet.java | 19 +-- .../typeinference/unifynew/RuleSet.java | 135 +++++++++++++----- .../unify/model/FiniteClosure.java | 29 ++-- .../typinference/unify/model/MPair.java | 8 -- .../typinference/unify/model/Type.java | 24 +--- 7 files changed, 148 insertions(+), 74 deletions(-) diff --git a/notizen/stf/Notes b/notizen/stf/Notes index 515019a7..ddca19be 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -32,6 +32,9 @@ Instanceof wird verwendet da: 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) ++++++++++++++++++++++++++++++++++++++++++++++++ + +- Typen sind anhand ihres identifiers durchgängig identifizierbar EED UP - Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 0dd264a5..7c020817 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -28,4 +28,8 @@ public interface IFiniteClosure { public boolean isInGrArg(Type grArgT, Type t); public boolean isInSmArg(Type smArgT, Type t); + + public Set smaller(String typeName); + + public Type getType(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index eb23e17f..5fdb53d3 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -1,17 +1,20 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; +import java.util.Optional; +import java.util.Set; + 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 Optional reduceUp(MPair pair); + public Optional reduceLow(MPair pair); + public Optional reduceUpLow(MPair pair); + public Optional> reduceExt(MPair pair); + public Optional> reduceSup(MPair pair); + public Optional> reduceEq(MPair pair); + public Optional> reduce1(MPair pair); + public Optional> reduce2(MPair pair); public boolean erase1(MPair pair); public boolean erase2(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index d0c6e272..bbf6a3bf 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -1,5 +1,10 @@ package de.dhbwstuttgart.typeinference.unifynew; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import junit.framework.Assert; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typinference.unify.model.ExtendsType; @@ -19,85 +24,108 @@ public class RuleSet implements IRuleSet{ } @Override - public boolean reduceUp(MPair pair) { + public Optional reduceUp(MPair pair) { if(pair.getPairOp() != PairOperator.SMALLERDOT) - return false; + return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof SuperType)) - return false; + return Optional.empty(); Type lhsType = pair.getLhsType(); if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) - return false; + return Optional.empty(); - pair.setRhsType(((SuperType) rhsType).GetSuperedType()); - return true; + return Optional.of(new MPair(lhsType, ((SuperType) rhsType).GetSuperedType())); } @Override - public boolean reduceLow(MPair pair) { + public Optional reduceLow(MPair pair) { if(pair.getPairOp() != PairOperator.SMALLERDOT) - return false; + return Optional.empty(); Type lhsType = pair.getLhsType(); if(!(lhsType instanceof ExtendsType)) - return false; + return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) - return false; - - pair.setLhsType(((ExtendsType) lhsType).GetExtendedType()); - return true; + return Optional.empty(); + + return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(), rhsType)); } @Override - public boolean reduceUpLow(MPair pair) { + public Optional reduceUpLow(MPair pair) { if(pair.getPairOp() != PairOperator.SMALLERDOT) - return false; + return Optional.empty(); Type lhsType = pair.getLhsType(); if(!(lhsType instanceof ExtendsType)) - return false; + return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof SuperType)) - return false; + return Optional.empty(); - pair.setLhsType(((ExtendsType) lhsType).GetExtendedType()); - pair.setRhsType(((SuperType) rhsType).GetSuperedType()); - return true; + return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(),((SuperType) rhsType).GetSuperedType())); } @Override - public boolean reduceExt(MPair pair) { - // TODO Auto-generated method stub - return false; + public Optional> reduceExt(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + + return null; } @Override - public boolean reduceSup(MPair pair) { + public Optional> reduceSup(MPair pair) { // TODO Auto-generated method stub - return false; + return null; } @Override - public boolean reduceEq(MPair pair) { + public Optional> reduceEq(MPair pair) { // TODO Auto-generated method stub - return false; + return null; } @Override - public boolean reduce1(MPair pair) { - // TODO Auto-generated method stub - return false; + public Optional> reduce1(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(!(lhsType instanceof SimpleType)) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(!(rhsType instanceof SimpleType)) + return Optional.empty(); + + SimpleType lhsSType = (SimpleType) lhsType; + SimpleType rhsSType = (SimpleType) rhsType; + + if(lhsSType.getTypeArgs().length == 0 || rhsSType.getTypeArgs().length == 0 || lhsSType.getTypeArgs() != rhsSType.getTypeArgs()) + return Optional.empty(); + + int[] pi = pi(lhsSType, rhsSType); + Type[] rhsTypeArgs = rhsType.getTypeArgs(); + Type[] lhsTypeArgs = lhsType.getTypeArgs(); + Set result = new HashSet<>(); + + for(int rhsIdx = 0; rhsIdx < rhsTypeArgs.length; rhsIdx++) + result.add(new MPair(lhsTypeArgs[pi[rhsIdx]], rhsTypeArgs[rhsIdx])); + + return Optional.of(result); } @Override - public boolean reduce2(MPair pair) { + public Optional> reduce2(MPair pair) { // TODO Auto-generated method stub - return false; + return null; } @Override @@ -164,4 +192,47 @@ public class RuleSet implements IRuleSet{ return null; } + /** + * Finds the permutation pi of the type arguments of two types based on the finite closure + * @param C The type which arguments are permuted + * @param D The other type + * @return An array containing the values of pi for every type argument of C or an empty array if the search failed. + */ + private int[] pi(Type C, Type D) { + Type dFromFc = finiteClosure.getType(D.getName()); + if(dFromFc == null) + return new int[0]; + + Set smallerRhs = finiteClosure.smaller(dFromFc); + Optional opt = smallerRhs.stream().filter(x -> x.getName().equals(C.getName())).findAny(); + + if(!opt.isPresent()) + return new int[0]; + + Type cFromFc = opt.get(); + + Assert.assertEquals(cFromFc.getTypeArgs().length, dFromFc.getTypeArgs().length); + Assert.assertTrue(dFromFc.getTypeArgs().length > 0); + + Type[] cArgs = cFromFc.getTypeArgs(); + Type[] dArgs = dFromFc.getTypeArgs(); + + int[] permutation = new int[dArgs.length]; + + boolean succ = true; + for (int dArgIdx = 0; dArgIdx < dArgs.length && succ; dArgIdx++) { + Type dArg = dArgs[dArgIdx]; + succ = false; + for (int pi = 0; pi < cArgs.length; pi++) + if (cArgs[pi].getName().equals(dArg.getName())) { + permutation[dArgIdx] = pi; + succ = true; + break; + } + } + + if(succ) return permutation; + return new int[0]; + } + } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 5d326b47..6509060c 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -10,11 +10,11 @@ import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; public class FiniteClosure implements IFiniteClosure { - private HashMap> inheritanceGraph; + private HashMap> inheritanceGraph; public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { @@ -23,10 +23,10 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType())) - inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); - if(!inheritanceGraph.containsKey(pair.getRhsType())) - inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); + if(!inheritanceGraph.containsKey(pair.getLhsType().getName())) + inheritanceGraph.put(pair.getLhsType().getName(), new Node(pair.getLhsType())); + if(!inheritanceGraph.containsKey(pair.getRhsType().getName())) + inheritanceGraph.put(pair.getRhsType().getName(), new Node(pair.getRhsType())); Node childNode = inheritanceGraph.get(pair.getRhsType()); Node parentNode = inheritanceGraph.get(pair.getLhsType()); @@ -45,10 +45,23 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - if(!inheritanceGraph.containsKey(type)) + return smaller(type.getName()); + } + + @Override + public Set smaller(String typeName) { + if(!inheritanceGraph.containsKey(typeName)) return new HashSet<>(); - return inheritanceGraph.get(type).getContentOfDescendants(); + return inheritanceGraph.get(typeName).getContentOfDescendants(); + } + + @Override + public Type getType(String typeName) { + if(!inheritanceGraph.containsKey(typeName)) + return null; + + return inheritanceGraph.get(typeName).getContent(); } /** diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index 0ef52ee4..ea32f9a7 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -34,14 +34,6 @@ public class MPair { return type2; } - public void setLhsType(Type newLhs) { - type1 = newLhs; - } - - public void setRhsType(Type newRhs) { - type2 = newRhs; - } - public PairOperator getPairOp() { return pairOp; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index 72ac1839..201dc80d 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -1,12 +1,12 @@ package de.dhbwstuttgart.typinference.unify.model; -public abstract class Type implements Comparable { +public abstract class Type { - protected int identifier = 0; + protected String typeName = ""; protected Type[] typeArgs = null; - public int getIdentifier() { - return identifier; + public String getName() { + return typeName; } public Type[] getTypeArgs() { @@ -22,7 +22,7 @@ public abstract class Type implements Comparable { Type other = (Type) obj; - if(other.getIdentifier() != identifier) + if(!other.getName().equals(typeName)) return false; Type[] otherTypeArgs = other.getTypeArgs(); @@ -40,18 +40,6 @@ public abstract class Type implements Comparable { @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; + return typeName.hashCode(); } } \ No newline at end of file From 2483044e0c8b02a002e47ed7706eb2a49b0935e2 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 10:57:17 +0100 Subject: [PATCH 09/47] rules --- .../typeinference/unify/Unify.java | 149 ++++++------------ .../unify/interfaces/IRuleSet.java | 2 +- .../typeinference/unifynew/RuleSet.java | 96 +++++++++-- .../unify/model/FiniteClosure.java | 4 +- .../typinference/unify/model/MPair.java | 51 ++++-- .../typinference/unify/model/SimpleType.java | 5 +- .../typinference/unify/model/SuperType.java | 13 +- .../typinference/unify/model/Type.java | 33 ++-- .../typinference/unify/model/TypeParams.java | 37 +++++ test/unify/RuleSetTest.java | 78 +++++++++ 10 files changed, 319 insertions(+), 149 deletions(-) create mode 100644 src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java create mode 100644 test/unify/RuleSetTest.java diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index c5afe522..f11b8f3d 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -2738,105 +2738,56 @@ tempKlasse.get_Superclass_Name() ); System.out.println( "P. S.: */ // ino.end - // ino.method.pi.28118.definition - public static int pi( int n, String C, String D, Menge tto ) - throws SCException - // ino.end - // ino.method.pi.28118.body - { - // otth: Permutation, benoetigt fuer Unifikation - // C, D: Namen von Klassen - // z.B. class C --- class D - // pi(1) = 2 - - // MyCompiler.printDebugInfo("---------------- Permutation: n = " + String.valueOf(n) + " - C = " + C + " - D = " + D, 6); - - // Klassen suchen - //Class KlasseC = null; - //Class KlasseD = null; - //Class tempKlasse = null; - // for( int i = 0; i < KlassenVektor.size(); i++ ) - // { - // // MyCompiler.printDebugInfo("---------------- Permutation: i = " + String.valueOf(i) + " - Classname = " + ((Class)KlassenVektor.elementAt(i)).get_classname(), 6); - - // if( KlasseC != null && KlasseD != null ) - // break; - - // tempKlasse = (Class)KlassenVektor.elementAt(i); - // if( C.equals( tempKlasse.get_classname() ) ) - // { - // KlasseC = tempKlasse; - // // MyCompiler.printDebugInfo("---------------- Permutation: C-Klasse gefunden!", 6); - // } - - // if( D.equals( tempKlasse.get_classname() ) ) - // { - // KlasseD = tempKlasse; - // // MyCompiler.printDebugInfo("---------------- Permutation: D-Klasse gefunden!", 6); - // } - // } - - if (C.equals(D)) return n; //Reduktion mit gleichen Typkonstruktoren - - else { - RefType KlasseC = null; - RefType KlasseD = null; - //RefType tempKlasse = null; - - for( int i = 0; i < tto.size(); i++ ) { - - KlasseC = (RefType)((Pair)tto.elementAt(i)).TA1; - KlasseD = (RefType)((Pair)tto.elementAt(i)).TA2; - - if (KlasseC.getTypeName().equals(C) && KlasseD.getTypeName().equals(D)) { - break; - } - else { - KlasseC = null; - KlasseD = null; - } - - } - - SCException F = new SCException(); - if( KlasseC == null && KlasseD == null ) - throw F; // Fehler - - // Vektorlisten extrahieren - Menge vC = KlasseC.get_ParaList(); - Menge vD = KlasseD.get_ParaList(); - - if( vC == null || vD == null ) - throw F; - - if( n >= vD.size() ) - throw F; - - // Permuationswert f�r 'n' berechnen - Type TV = (Type)vD.elementAt(n); - - int nPos = -1; - - // MyCompiler.printDebugInfo("---------------- Permutation: vC.size() = " + String.valueOf( vC.size() ), 6); - - for( int i = 0; i < vC.size(); i++ ) - { - // MyCompiler.printDebugInfo("---------------- Permutation: TV = " + ((Type)vC.elementAt(i)).getName_(), 6); - if( ((Type)vC.elementAt(i)).getName().equals( TV.getName() ) ) - { - nPos = i; - break; - } - } - - if (nPos == -1) - throw F; - - // MyCompiler.printDebugInfo("---------------- Permutation: = " + String.valueOf( nPos ), 6); - - return nPos; - } - } + // ino.method.pi.28118.definition + public static int pi(int n, String C, String D, Menge tto) + throws SCException { + + if (C.equals(D)) + return n; // Reduktion mit gleichen Typkonstruktoren + + RefType KlasseC = null; + RefType KlasseD = null; + + for (int i = 0; i < tto.size(); i++) { + + KlasseC = (RefType) ((Pair) tto.elementAt(i)).TA1; + KlasseD = (RefType) ((Pair) tto.elementAt(i)).TA2; + + if (KlasseC.getTypeName().equals(C) + && KlasseD.getTypeName().equals(D)) + break; + else { + KlasseC = null; + KlasseD = null; + } + } + + SCException F = new SCException(); + if (KlasseC == null && KlasseD == null) + throw F; // Fehler + + // Vektorlisten extrahieren + Menge vC = KlasseC.get_ParaList(); + Menge vD = KlasseD.get_ParaList(); + + if (vC == null || vD == null) + throw F; + + if (n >= vD.size()) + throw F; + + // Permuationswert f�r 'n' berechnen + Type TV = (Type) vD.elementAt(n); + int nPos = -1; + for (int i = 0; i < vC.size(); i++) + if (((Type) vC.elementAt(i)).getName().equals(TV.getName())) { + nPos = i; + break; + } + + return nPos; + + } // ino.end // ino.method.printMengeUnifier.28121.definition public static void printMengeUnifier(String strMenge, Menge> Uni, int nDebug ) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index 5fdb53d3..88f98ac7 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -20,7 +20,7 @@ public interface IRuleSet { public boolean erase2(MPair pair); public boolean erase3(MPair pair); - public MPair swap(MPair pair); + public Optional swap(MPair pair); public MPair adapt(MPair pair); public MPair adaptExt(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index bbf6a3bf..fca0e120 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -36,7 +36,7 @@ public class RuleSet implements IRuleSet{ if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) return Optional.empty(); - return Optional.of(new MPair(lhsType, ((SuperType) rhsType).GetSuperedType())); + return Optional.of(new MPair(lhsType, ((SuperType) rhsType).GetSuperedType(), PairOperator.SMALLERDOT)); } @Override @@ -52,7 +52,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) return Optional.empty(); - return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(), rhsType)); + return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(), rhsType, PairOperator.SMALLERDOT)); } @Override @@ -68,7 +68,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SuperType)) return Optional.empty(); - return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(),((SuperType) rhsType).GetSuperedType())); + return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(),((SuperType) rhsType).GetSuperedType(), PairOperator.SMALLERDOT)); } @Override @@ -76,6 +76,14 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); + Type lhsType = pair.getLhsType(); + SimpleType lhsSType; + + if(lhsType instanceof SimpleType) + lhsSType = (SimpleType) lhsType; + else if(lhsType instanceof ExtendsType) + lhsSType = (SimpleType) ((ExtendsType) lhsType).GetExtendedType(); + else return null; } @@ -108,24 +116,70 @@ public class RuleSet implements IRuleSet{ SimpleType lhsSType = (SimpleType) lhsType; SimpleType rhsSType = (SimpleType) rhsType; - if(lhsSType.getTypeArgs().length == 0 || rhsSType.getTypeArgs().length == 0 || lhsSType.getTypeArgs() != rhsSType.getTypeArgs()) + if(lhsSType.getTypeParams().empty()|| rhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) return Optional.empty(); int[] pi = pi(lhsSType, rhsSType); - Type[] rhsTypeArgs = rhsType.getTypeArgs(); - Type[] lhsTypeArgs = lhsType.getTypeArgs(); + + if(pi.length == 0) + return Optional.empty(); + + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); Set result = new HashSet<>(); - for(int rhsIdx = 0; rhsIdx < rhsTypeArgs.length; rhsIdx++) - result.add(new MPair(lhsTypeArgs[pi[rhsIdx]], rhsTypeArgs[rhsIdx])); + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) + result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOT)); return Optional.of(result); } @Override public Optional> reduce2(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.EQUALSDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + SimpleType lhsSType; + + if(lhsType instanceof SimpleType) + lhsSType = (SimpleType) lhsType; + else if(lhsType instanceof ExtendsType) + lhsSType = (SimpleType) ((ExtendsType) lhsType).GetExtendedType(); + else if(lhsType instanceof SuperType) + lhsSType = (SimpleType) ((SuperType) lhsType).GetSuperedType(); + else + return Optional.empty(); + + if(lhsSType.getTypeParams().empty()) + return Optional.empty(); + + Type rhsType = pair.getLhsType(); + SimpleType rhsSType; + + if(rhsType instanceof SimpleType) + rhsSType = (SimpleType) rhsType; + else if(rhsType instanceof ExtendsType) + rhsSType = (SimpleType) ((ExtendsType) rhsType).GetExtendedType(); + else if(rhsType instanceof SuperType) + rhsSType = (SimpleType) ((SuperType) rhsType).GetSuperedType(); + else + return Optional.empty(); + + if(rhsSType.getTypeParams().empty()) + return Optional.empty(); + + if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + return Optional.empty(); + + Set result = new HashSet<>(); + + Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + for(int i = 0; i < rhsTypeParams.length; i++) + result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.SMALLERDOT)); + + return Optional.of(result); } @Override @@ -169,9 +223,17 @@ public class RuleSet implements IRuleSet{ } @Override - public MPair swap(MPair pair) { - // TODO Auto-generated method stub - return null; + public Optional swap(MPair pair) { + if(pair.getPairOp() != PairOperator.EQUALSDOT) + return Optional.empty(); + + if(pair.getLhsType() instanceof PlaceholderType) + return Optional.empty(); + + if(!(pair.getRhsType() instanceof PlaceholderType)) + return Optional.empty(); + + return Optional.of(new MPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT)); } @Override @@ -211,11 +273,11 @@ public class RuleSet implements IRuleSet{ Type cFromFc = opt.get(); - Assert.assertEquals(cFromFc.getTypeArgs().length, dFromFc.getTypeArgs().length); - Assert.assertTrue(dFromFc.getTypeArgs().length > 0); + Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); + Assert.assertTrue(dFromFc.getTypeParams().size() > 0); - Type[] cArgs = cFromFc.getTypeArgs(); - Type[] dArgs = dFromFc.getTypeArgs(); + Type[] cArgs = cFromFc.getTypeParams().asArray(); + Type[] dArgs = dFromFc.getTypeParams().asArray(); int[] permutation = new int[dArgs.length]; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 6509060c..4ca7b250 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -28,8 +28,8 @@ public class FiniteClosure implements IFiniteClosure { if(!inheritanceGraph.containsKey(pair.getRhsType().getName())) inheritanceGraph.put(pair.getRhsType().getName(), new Node(pair.getRhsType())); - Node childNode = inheritanceGraph.get(pair.getRhsType()); - Node parentNode = inheritanceGraph.get(pair.getLhsType()); + Node childNode = inheritanceGraph.get(pair.getLhsType().getName()); + Node parentNode = inheritanceGraph.get(pair.getRhsType().getName()); // Add edge parentNode.AddDescendant(childNode); diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index ea32f9a7..4a811940 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -7,31 +7,47 @@ public class MPair { SMALLERDOT, SMALLERDOTWC, EQUALS, - EQUALSDOT + EQUALSDOT; + + @Override + public String toString() { + switch (this) { + case SMALLER: + return "<"; + case SMALLERDOT: + return "<."; + case SMALLERDOTWC: + return "<.?"; + case EQUALS: + return "="; + default: + return "=."; + } + }; } - private Type type1; - private Type type2; + private Type lhs; + private Type rhs; private PairOperator pairOp; - public MPair(Type t1, Type t2) { - type1 = t1; - type2 = t2; + /*public MPair(Type t1, Type t2) { + lhs = t1; + rhs = t2; pairOp = PairOperator.SMALLER; - } + }*/ public MPair(Type t1, Type t2, PairOperator op) { - type1 = t1; - type2 = t2; + lhs = t1; + rhs = t2; pairOp = op; } public Type getLhsType() { - return type1; + return lhs; } public Type getRhsType() { - return type2; + return rhs; } public PairOperator getPairOp() { @@ -48,12 +64,19 @@ public class MPair { MPair other = (MPair) obj; return other.getPairOp() == pairOp - && other.getLhsType().equals(type1) - && other.getRhsType().equals(type2); + && other.getLhsType().equals(lhs) + && other.getRhsType().equals(rhs); } @Override public int hashCode() { - return 17 + 31 * type1.hashCode() + 31 * type2.hashCode() + 31 * pairOp.hashCode(); + return 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); + } + + @Override + public String toString() { + return "(" + lhs + " " + pairOp + " " + rhs + ")"; } } + + diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 0ff65f96..8104202d 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.typinference.unify.model; public class SimpleType extends Type { - + public SimpleType(String name, Type... typeParams) { + this.typeName = name; + this.typeParams = new TypeParams(typeParams); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index fcd8534c..a5377bb8 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -2,7 +2,18 @@ package de.dhbwstuttgart.typinference.unify.model; public class SuperType extends Type { + private Type superedType; + + public SuperType(Type superedType) { + this.superedType = superedType; + } + public Type GetSuperedType() { - return null; + return superedType; + } + + @Override + public String toString() { + return "? super " + superedType; } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index 201dc80d..ed317e73 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -1,16 +1,18 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Arrays; + public abstract class Type { protected String typeName = ""; - protected Type[] typeArgs = null; + protected TypeParams typeParams; public String getName() { return typeName; } - public Type[] getTypeArgs() { - return typeArgs; + public TypeParams getTypeParams() { + return typeParams; } @Override @@ -24,17 +26,8 @@ public abstract class Type { if(!other.getName().equals(typeName)) 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; + + return other.getTypeParams().equals(typeParams); } @@ -42,4 +35,16 @@ public abstract class Type { public int hashCode() { return typeName.hashCode(); } + + @Override + public String toString() { + String params = ""; + if(typeParams.size() != 0) { + for(Type param : typeParams) + params += param.toString() + ","; + params = "<" + params.substring(0, params.length()-1) + ">"; + } + + return typeName + params; + } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java new file mode 100644 index 00000000..bf2bdde9 --- /dev/null +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -0,0 +1,37 @@ +package de.dhbwstuttgart.typinference.unify.model; + +import java.util.Arrays; +import java.util.Iterator; + +public class TypeParams implements Iterable{ + private Type[] typeParams; + + public TypeParams(Type... types) { + typeParams = types; + } + + @Override + public String toString() { + String res = ""; + for(Type t : typeParams) + res += t + ","; + return "<" + res.substring(0, res.length()-1) + ">"; + } + + public int size() { + return typeParams.length; + } + + public boolean empty() { + return typeParams.length == 0; + } + + public Type[] asArray() { + return typeParams; + } + + @Override + public Iterator iterator() { + return Arrays.stream(typeParams).iterator(); + } +} diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java new file mode 100644 index 00000000..5a8ee772 --- /dev/null +++ b/test/unify/RuleSetTest.java @@ -0,0 +1,78 @@ +package unify; + + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import org.junit.Test; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; +import de.dhbwstuttgart.typeinference.unifynew.RuleSet; +import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; +import de.dhbwstuttgart.typinference.unify.model.SimpleType; +import de.dhbwstuttgart.typinference.unify.model.SuperType; + + +public class RuleSetTest { + + @Test + public void testReduceUp() { + Set pairs = new HashSet(); + + SimpleType t1 = new SimpleType("Set"); + SimpleType t2 = new SimpleType("HashSet"); + SimpleType t3 = new SimpleType("Something"); + + SuperType s = new SuperType(t2); + + pairs.add(new MPair(t1, t2, PairOperator.SMALLER)); + + FiniteClosure fc = new FiniteClosure(pairs); + + IRuleSet rules = new RuleSet(fc); + + MPair test = new MPair(t3, s, PairOperator.SMALLERDOT); + + + Optional res = rules.reduceUp(test); + + System.out.println(res); + } + + @Test + public void testReduce1() { + Set pairs = new HashSet(); + + SimpleType t1 = new SimpleType("t1"); + SimpleType t2 = new SimpleType("t2"); + SimpleType t3 = new SimpleType("t3"); + SimpleType t4 = new SimpleType("t4"); + SimpleType t5 = new SimpleType("t5"); + SimpleType t6 = new SimpleType("t6"); + SimpleType t7 = new SimpleType("t7"); + SimpleType t8 = new SimpleType("t8"); + SimpleType t9 = new SimpleType("t9"); + + SimpleType ta = new SimpleType("a", t1, t2, t3); + SimpleType taa = new SimpleType("a", t4, t5, t6); + SimpleType tb = new SimpleType("b", t3, t1, t2); + SimpleType tbb = new SimpleType("b", t7, t8, t9); + + + pairs.add(new MPair(ta, tb, PairOperator.SMALLER)); + FiniteClosure fc = new FiniteClosure(pairs); + + IRuleSet rules = new RuleSet(fc); + + MPair test = new MPair(taa, tbb, PairOperator.SMALLERDOT); + + Optional> res = rules.reduce1(test); + + System.out.println(res); + } + + +} From c08a8fd347ed5ab742af10f04b83cae3b6ef336e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 11:41:06 +0100 Subject: [PATCH 10/47] reduceExt --- .../syntaxtree/factory/UnifyTypeFactory.java | 8 +-- .../typeinference/unifynew/RuleSet.java | 65 +++++++++++++++---- .../typinference/unify/model/ExtendsType.java | 13 +++- .../typinference/unify/model/SuperType.java | 5 ++ 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 428c08e2..6bbd023f 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -1,15 +1,13 @@ package de.dhbwstuttgart.syntaxtree.factory; -import de.dhbwstuttgart.syntaxtree.type.Type; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; -import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ObjectType; 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.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.Menge; -import de.dhbwstuttgart.typeinference.Pair; -import de.dhbwstuttgart.typeinference.Pair.PairOperator; public class UnifyTypeFactory { diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index fca0e120..cc4c7dbf 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -84,8 +84,34 @@ public class RuleSet implements IRuleSet{ else if(lhsType instanceof ExtendsType) lhsSType = (SimpleType) ((ExtendsType) lhsType).GetExtendedType(); else + return Optional.empty(); - return null; + if(lhsSType.getTypeParams().empty()) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + + if(!(rhsType instanceof ExtendsType)) + return Optional.empty(); + + SimpleType rhsSType = (SimpleType) ((ExtendsType) rhsType).GetExtendedType(); + + if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + return Optional.empty(); + + int[] pi = pi(lhsSType, rhsType); + + if(pi.length == 0) + return Optional.empty(); + + Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Set result = new HashSet<>(); + + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) + result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); + + return Optional.of(result); } @Override @@ -116,7 +142,7 @@ public class RuleSet implements IRuleSet{ SimpleType lhsSType = (SimpleType) lhsType; SimpleType rhsSType = (SimpleType) rhsType; - if(lhsSType.getTypeParams().empty()|| rhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) + if(lhsSType.getTypeParams().empty() || rhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) return Optional.empty(); int[] pi = pi(lhsSType, rhsSType); @@ -129,7 +155,7 @@ public class RuleSet implements IRuleSet{ Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOT)); + result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -165,12 +191,13 @@ public class RuleSet implements IRuleSet{ rhsSType = (SimpleType) ((SuperType) rhsType).GetSuperedType(); else return Optional.empty(); - - if(rhsSType.getTypeParams().empty()) + + if(!rhsSType.getName().equals(lhsSType.getName())) return Optional.empty(); - if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) - return Optional.empty(); + Assert.assertEquals(lhsSType.getTypeParams().size(), rhsSType.getTypeParams().size()); + //if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + // return Optional.empty(); Set result = new HashSet<>(); @@ -261,17 +288,31 @@ public class RuleSet implements IRuleSet{ * @return An array containing the values of pi for every type argument of C or an empty array if the search failed. */ private int[] pi(Type C, Type D) { - Type dFromFc = finiteClosure.getType(D.getName()); - if(dFromFc == null) + Type cFromFc = finiteClosure.getType(C.getName()); + if(cFromFc == null) return new int[0]; - Set smallerRhs = finiteClosure.smaller(dFromFc); - Optional opt = smallerRhs.stream().filter(x -> x.getName().equals(C.getName())).findAny(); + Optional opt = Optional.empty(); + if(D instanceof ExtendsType) { + SimpleType dSType = (SimpleType) ((ExtendsType) D).GetExtendedType(); + opt = finiteClosure.grArg(cFromFc).stream() + .filter(x -> x instanceof ExtendsType) + .filter(x -> ((ExtendsType) x).GetExtendedType().equals(dSType.getName())).findAny(); + } + else if(D instanceof SuperType) { + SimpleType dSType = (SimpleType) ((SuperType) D).GetSuperedType(); + opt = finiteClosure.grArg(cFromFc).stream() + .filter(x -> x instanceof SuperType) + .filter(x -> ((SuperType) x).GetSuperedType().equals(dSType.getName())).findAny(); + } + else if (D instanceof SimpleType) + opt = finiteClosure.greater(cFromFc).stream() + .filter(x -> x.getName().equals(D.getName())).findAny(); if(!opt.isPresent()) return new int[0]; - Type cFromFc = opt.get(); + Type dFromFc = opt.get(); Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); Assert.assertTrue(dFromFc.getTypeParams().size() > 0); diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index ca7f5c32..7b26ca17 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -1,9 +1,18 @@ package de.dhbwstuttgart.typinference.unify.model; public class ExtendsType extends Type { + private Type extendedType; + + public ExtendsType(Type extendedType) { + this.extendedType = extendedType; + } public Type GetExtendedType() { - return null; - // TODO + return extendedType; + } + + @Override + public TypeParams getTypeParams() { + return extendedType.getTypeParams(); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index a5377bb8..a62fd9f3 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -16,4 +16,9 @@ public class SuperType extends Type { public String toString() { return "? super " + superedType; } + + @Override + public TypeParams getTypeParams() { + return superedType.getTypeParams(); + } } From b93f1dd3763fda3053f8743313216d4f69bad52f Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 11:47:54 +0100 Subject: [PATCH 11/47] fixed greater() --- .../dhbwstuttgart/typinference/unify/model/FiniteClosure.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 4ca7b250..712b99a6 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -70,10 +70,10 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - if(!inheritanceGraph.containsKey(type)) + if(!inheritanceGraph.containsKey(type.getName())) return new HashSet<>(); - return inheritanceGraph.get(type).getContentOfPredecessors(); + return inheritanceGraph.get(type.getName()).getContentOfPredecessors(); } @Override From 6b709f0198a2082ed674a5d2adefd2f4105318f9 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 13:57:54 +0100 Subject: [PATCH 12/47] fc smaller greater tests --- .../unify/interfaces/IFiniteClosure.java | 2 -- .../unify/model/FiniteClosure.java | 26 ++++++++++++++----- .../typinference/unify/model/Node.java | 5 ++++ .../unify/model/PlaceholderType.java | 5 +++- .../typinference/unify/model/Type.java | 4 +++ 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 7c020817..83f17ca9 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -29,7 +29,5 @@ public interface IFiniteClosure { public boolean isInSmArg(Type smArgT, Type t); - public Set smaller(String typeName); - public Type getType(String typeName); } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 712b99a6..1d969043 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -36,6 +36,7 @@ public class FiniteClosure implements IFiniteClosure { // Add edges to build the transitive closure parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode)); + childNode.getDescendants().stream().forEach(x -> x.AddPredecessor(parentNode)); } } @@ -48,8 +49,7 @@ public class FiniteClosure implements IFiniteClosure { return smaller(type.getName()); } - @Override - public Set smaller(String typeName) { + private Set smaller(String typeName) { if(!inheritanceGraph.containsKey(typeName)) return new HashSet<>(); @@ -70,20 +70,34 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - if(!inheritanceGraph.containsKey(type.getName())) + return greater(type.typeName); + } + + private Set greater(String typeName) { + if(!inheritanceGraph.containsKey(typeName)) return new HashSet<>(); - return inheritanceGraph.get(type.getName()).getContentOfPredecessors(); + return inheritanceGraph.get(typeName).getContentOfPredecessors(); } @Override public Set grArg(Type type) { - throw new NotImplementedException(); + return grArg(type.getName()); + } + + private Set grArg(String typeName) { + // TODO Auto-generated method stub + return null; } @Override public Set smArg(Type type) { - throw new NotImplementedException(); + return smArg(type.getName()); + } + + private Set smArg(String typeName) { + // TODO Auto-generated method stub + return null; } @Override diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Node.java b/src/de/dhbwstuttgart/typinference/unify/model/Node.java index f0eaa635..e42a2608 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Node.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Node.java @@ -49,4 +49,9 @@ public class Node { public Set getContentOfPredecessors() { return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet()); } + + @Override + public String toString() { + return "Node(" + content.toString() + ")"; + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index 7ef1f38b..03e66c80 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.typinference.unify.model; public class PlaceholderType extends Type{ - + + public PlaceholderType(String name) { + typeName = name; + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index ed317e73..52c58868 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -7,6 +7,10 @@ public abstract class Type { protected String typeName = ""; protected TypeParams typeParams; + public Type() { + typeParams = new TypeParams(); + } + public String getName() { return typeName; } From 28e0e8e94d38966ff773083bceba96b7b5f35238 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 14:35:54 +0100 Subject: [PATCH 13/47] visitor pattern for grarg smarg --- .../unify/interfaces/IFiniteClosure.java | 18 +++- .../typinference/unify/model/ExtendsType.java | 19 ++++ .../unify/model/FiniteClosure.java | 95 +++++++++++++------ .../unify/model/PlaceholderType.java | 14 +++ .../typinference/unify/model/SimpleType.java | 14 +++ .../typinference/unify/model/SuperType.java | 14 +++ .../typinference/unify/model/Type.java | 7 ++ 7 files changed, 145 insertions(+), 36 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 83f17ca9..ae3384ed 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -1,6 +1,11 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; import java.util.Set; + +import de.dhbwstuttgart.typinference.unify.model.ExtendsType; +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 interface IFiniteClosure { @@ -18,16 +23,19 @@ public interface IFiniteClosure { public Set greater(Type type); public Set grArg(Type type); - public Set smArg(Type type); - public boolean isSubtype(Type subT, Type superT); + public Set grArg(SimpleType type); + public Set smArg(SimpleType type); - public boolean isSupertype(Type superT, Type subT); + public Set grArg(ExtendsType type); + public Set smArg(ExtendsType type); - public boolean isInGrArg(Type grArgT, Type t); + public Set grArg(SuperType type); + public Set smArg(SuperType type); - public boolean isInSmArg(Type smArgT, Type t); + public Set grArg(PlaceholderType type); + public Set smArg(PlaceholderType type); public Type getType(String typeName); } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index 7b26ca17..ff5b5b79 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -1,5 +1,9 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + public class ExtendsType extends Type { private Type extendedType; @@ -15,4 +19,19 @@ public class ExtendsType extends Type { public TypeParams getTypeParams() { return extendedType.getTypeParams(); } + + @Override + public String toString() { + return "? extends " + extendedType; + } + + @Override + public Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + public Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 1d969043..ff1c5106 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -46,14 +46,12 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - return smaller(type.getName()); - } - - private Set smaller(String typeName) { - if(!inheritanceGraph.containsKey(typeName)) + if(!inheritanceGraph.containsKey(type.getName())) return new HashSet<>(); - return inheritanceGraph.get(typeName).getContentOfDescendants(); + Set result = inheritanceGraph.get(type.getName()).getContentOfDescendants(); + result.add(type); + return result; } @Override @@ -70,53 +68,88 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - return greater(type.typeName); - } - - private Set greater(String typeName) { - if(!inheritanceGraph.containsKey(typeName)) + if(!inheritanceGraph.containsKey(type.getName())) return new HashSet<>(); - return inheritanceGraph.get(typeName).getContentOfPredecessors(); + Set result = inheritanceGraph.get(type.getName()).getContentOfPredecessors(); + result.add(type); + return result; } + @Override public Set grArg(Type type) { - return grArg(type.getName()); + return type.grArg(this); + } + + @Override + public Set grArg(SimpleType type) { + if(!inheritanceGraph.containsKey(type.getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getName()).getContent(); + + result.add(t); + smaller(type).forEach(x -> result.add(new SuperType(x))); + greater(type).forEach(x -> result.add(new ExtendsType(x))); + + return result; } - private Set grArg(String typeName) { + @Override + public Set grArg(ExtendsType type) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set grArg(SuperType type) { // TODO Auto-generated method stub return null; } + @Override + public Set grArg(PlaceholderType type) { + // TODO Auto-generated method stub + return null; + } + @Override public Set smArg(Type type) { - return smArg(type.getName()); + return type.smArg(this); } - private Set smArg(String typeName) { - // TODO Auto-generated method stub + @Override + public Set smArg(SimpleType type) { + if(!inheritanceGraph.containsKey(type.getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getName()).getContent(); + + result.add(t); + smaller(type).forEach(x -> result.add(new ExtendsType(x))); + greater(type).forEach(x -> result.add(new ExtendsType(x))); + + return result; + } + + public Set smArg(ExtendsType type) { return null; } - @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); + public Set smArg(SuperType type) { + // TODO Auto-generated method stub + return null; } - @Override - public boolean isInSmArg(Type smArgT, Type t) { - return smArg(smArgT).contains(t); + public Set smArg(PlaceholderType type) { + // TODO Auto-generated method stub + return null; } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index 03e66c80..0c9aacd1 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -1,8 +1,22 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + public class PlaceholderType extends Type{ public PlaceholderType(String name) { typeName = name; } + + @Override + public Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + public Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 8104202d..8f1ceaae 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -1,8 +1,22 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + public class SimpleType extends Type { public SimpleType(String name, Type... typeParams) { this.typeName = name; this.typeParams = new TypeParams(typeParams); } + + @Override + public Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + public Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index a62fd9f3..d9116f08 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -1,5 +1,9 @@ package de.dhbwstuttgart.typinference.unify.model; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + public class SuperType extends Type { private Type superedType; @@ -21,4 +25,14 @@ public class SuperType extends Type { public TypeParams getTypeParams() { return superedType.getTypeParams(); } + + @Override + public Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + public Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index 52c58868..676bb574 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -1,6 +1,9 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Arrays; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; public abstract class Type { @@ -34,6 +37,10 @@ public abstract class Type { return other.getTypeParams().equals(typeParams); } + public abstract Set smArg(IFiniteClosure fc); + + public abstract Set grArg(IFiniteClosure fc); + @Override public int hashCode() { From e49c2a35de785c602fbe0a83d7b65853c731fc1c Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 14:53:23 +0100 Subject: [PATCH 14/47] implemented grArg and smArg --- .../unify/interfaces/IFiniteClosure.java | 11 ++++ .../typeinference/unifynew/RuleSet.java | 30 ++++----- .../typinference/unify/model/ExtendsType.java | 2 +- .../unify/model/FiniteClosure.java | 65 +++++++++++++++---- .../typinference/unify/model/SuperType.java | 2 +- 5 files changed, 79 insertions(+), 31 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index ae3384ed..fb620046 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -22,7 +22,18 @@ public interface IFiniteClosure { */ public Set greater(Type type); + /** + * Wo passt Type rein? + * @param type + * @return + */ public Set grArg(Type type); + + /** + * Was passt in Type rein? + * @param type + * @return + */ public Set smArg(Type type); public Set grArg(SimpleType type); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index cc4c7dbf..2b642f43 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -36,7 +36,7 @@ public class RuleSet implements IRuleSet{ if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) return Optional.empty(); - return Optional.of(new MPair(lhsType, ((SuperType) rhsType).GetSuperedType(), PairOperator.SMALLERDOT)); + return Optional.of(new MPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT)); } @Override @@ -52,7 +52,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) return Optional.empty(); - return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(), rhsType, PairOperator.SMALLERDOT)); + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT)); } @Override @@ -68,7 +68,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SuperType)) return Optional.empty(); - return Optional.of(new MPair(((ExtendsType) lhsType).GetExtendedType(),((SuperType) rhsType).GetSuperedType(), PairOperator.SMALLERDOT)); + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT)); } @Override @@ -82,7 +82,7 @@ public class RuleSet implements IRuleSet{ if(lhsType instanceof SimpleType) lhsSType = (SimpleType) lhsType; else if(lhsType instanceof ExtendsType) - lhsSType = (SimpleType) ((ExtendsType) lhsType).GetExtendedType(); + lhsSType = (SimpleType) ((ExtendsType) lhsType).getExtendedType(); else return Optional.empty(); @@ -94,7 +94,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof ExtendsType)) return Optional.empty(); - SimpleType rhsSType = (SimpleType) ((ExtendsType) rhsType).GetExtendedType(); + SimpleType rhsSType = (SimpleType) ((ExtendsType) rhsType).getExtendedType(); if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) return Optional.empty(); @@ -171,9 +171,9 @@ public class RuleSet implements IRuleSet{ if(lhsType instanceof SimpleType) lhsSType = (SimpleType) lhsType; else if(lhsType instanceof ExtendsType) - lhsSType = (SimpleType) ((ExtendsType) lhsType).GetExtendedType(); + lhsSType = (SimpleType) ((ExtendsType) lhsType).getExtendedType(); else if(lhsType instanceof SuperType) - lhsSType = (SimpleType) ((SuperType) lhsType).GetSuperedType(); + lhsSType = (SimpleType) ((SuperType) lhsType).getSuperedType(); else return Optional.empty(); @@ -186,9 +186,9 @@ public class RuleSet implements IRuleSet{ if(rhsType instanceof SimpleType) rhsSType = (SimpleType) rhsType; else if(rhsType instanceof ExtendsType) - rhsSType = (SimpleType) ((ExtendsType) rhsType).GetExtendedType(); + rhsSType = (SimpleType) ((ExtendsType) rhsType).getExtendedType(); else if(rhsType instanceof SuperType) - rhsSType = (SimpleType) ((SuperType) rhsType).GetSuperedType(); + rhsSType = (SimpleType) ((SuperType) rhsType).getSuperedType(); else return Optional.empty(); @@ -222,7 +222,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) return false; - return finiteClosure.isSubtype(lhsType, rhsType); + return finiteClosure.smaller(lhsType).contains(rhsType); } @Override @@ -238,7 +238,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof ExtendsType)) return false; - return finiteClosure.isInGrArg(lhsType, ((ExtendsType) rhsType).GetExtendedType()); + return finiteClosure.grArg(lhsType).contains(((ExtendsType) rhsType).getExtendedType()); } @Override @@ -294,16 +294,16 @@ public class RuleSet implements IRuleSet{ Optional opt = Optional.empty(); if(D instanceof ExtendsType) { - SimpleType dSType = (SimpleType) ((ExtendsType) D).GetExtendedType(); + SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof ExtendsType) - .filter(x -> ((ExtendsType) x).GetExtendedType().equals(dSType.getName())).findAny(); + .filter(x -> ((ExtendsType) x).getExtendedType().equals(dSType.getName())).findAny(); } else if(D instanceof SuperType) { - SimpleType dSType = (SimpleType) ((SuperType) D).GetSuperedType(); + SimpleType dSType = (SimpleType) ((SuperType) D).getSuperedType(); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof SuperType) - .filter(x -> ((SuperType) x).GetSuperedType().equals(dSType.getName())).findAny(); + .filter(x -> ((SuperType) x).getSuperedType().equals(dSType.getName())).findAny(); } else if (D instanceof SimpleType) opt = finiteClosure.greater(cFromFc).stream() diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index ff5b5b79..7a65fc30 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -11,7 +11,7 @@ public class ExtendsType extends Type { this.extendedType = extendedType; } - public Type GetExtendedType() { + public Type getExtendedType() { return extendedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index ff1c5106..0b1ee461 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Set; -import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; @@ -18,7 +17,6 @@ public class FiniteClosure implements IFiniteClosure { // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { - // TODO smaller oder smallerExtends? if(pair.getPairOp() != PairOperator.SMALLER) continue; @@ -100,20 +98,35 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(ExtendsType type) { - // TODO Auto-generated method stub - return null; + if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + + greater(t).forEach(x -> result.add(new ExtendsType(x))); + + return result; } @Override public Set grArg(SuperType type) { - // TODO Auto-generated method stub - return null; + if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + + smaller(t).forEach(x -> result.add(new SuperType(x))); + + return result; } @Override public Set grArg(PlaceholderType type) { - // TODO Auto-generated method stub - return null; + return new HashSet<>(); } @Override @@ -132,24 +145,48 @@ public class FiniteClosure implements IFiniteClosure { result.add(t); smaller(type).forEach(x -> result.add(new ExtendsType(x))); - greater(type).forEach(x -> result.add(new ExtendsType(x))); return result; } public Set smArg(ExtendsType type) { - return null; + if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + + result.add(t); + smaller(t).forEach(x -> { + result.add(new ExtendsType(x)); + result.add(x); + }); + + return result; } @Override public Set smArg(SuperType type) { - // TODO Auto-generated method stub - return null; + if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + return new HashSet(); + + Set result = new HashSet(); + + Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + + result.add(t); + greater(t).forEach(x -> { + result.add(new SuperType(x)); + result.add(x); + }); + + return result; } + @Override public Set smArg(PlaceholderType type) { - // TODO Auto-generated method stub - return null; + return new HashSet<>(); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index d9116f08..d7f0f38a 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -12,7 +12,7 @@ public class SuperType extends Type { this.superedType = superedType; } - public Type GetSuperedType() { + public Type getSuperedType() { return superedType; } From 4765c2afe0d1b49c84cc9b95b074ecf1b60fbfe7 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 16:21:17 +0100 Subject: [PATCH 15/47] smarg and grarg tests --- test/unify/FiniteClosureBuilder.java | 60 ++++++++++++++++++++++++++++ test/unify/FiniteClosureTest.java | 53 ++++++++++++++++++++++++ test/unify/TypeFactory.java | 37 +++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 test/unify/FiniteClosureBuilder.java create mode 100644 test/unify/FiniteClosureTest.java create mode 100644 test/unify/TypeFactory.java diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java new file mode 100644 index 00000000..acce7b5b --- /dev/null +++ b/test/unify/FiniteClosureBuilder.java @@ -0,0 +1,60 @@ +package unify; + +import java.util.HashSet; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; +import de.dhbwstuttgart.typinference.unify.model.Type; + +public class FiniteClosureBuilder { + + private Set pairs = new HashSet<>(); + + public void add(Type sub, Type sup) { + pairs.add(new MPair(sub, sup, PairOperator.SMALLER)); + } + + public IFiniteClosure getFiniteClosure() { + FiniteClosure fc = new FiniteClosure(pairs); + pairs = new HashSet<>(); + return fc; + } + + public IFiniteClosure getCollectionExample() { + TypeFactory tf = new TypeFactory(); + + Type collection = tf.getSimpleType("Collection"); + Type set = tf.getSimpleType("Set", "T"); + Type sortedSet = tf.getSimpleType("Set", "K"); + Type TreeSet = tf.getSimpleType("TreeSet", "T"); + Type hashSet = tf.getSimpleType("HashSet", "Z"); + Type linkedHashSet = tf.getSimpleType("LinkedHashSet", "T"); + Type queue = tf.getSimpleType("Queue", "U"); + Type deque = tf.getSimpleType("Deque", "U"); + Type linkedList = tf.getSimpleType("LinkedList", "U"); + Type list = tf.getSimpleType("List", "T"); + Type vector = tf.getSimpleType("Vector", "T"); + Type stack = tf.getSimpleType("Stack", "T"); + Type arrayList = tf.getSimpleType("ArrayList", "T"); + + add(set, collection); + add(sortedSet, set); + add(TreeSet, sortedSet); + add(hashSet, set); + add(linkedHashSet, set); + + add(queue, collection); + add(deque, queue); + add(linkedList, deque); + add(list, collection); + add(linkedList, list); + add(vector, list); + add(arrayList, list); + add(stack, vector); + + return getFiniteClosure(); + } +} diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java new file mode 100644 index 00000000..15fdf2c3 --- /dev/null +++ b/test/unify/FiniteClosureTest.java @@ -0,0 +1,53 @@ +package unify; + +import org.junit.Test; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.Type; + +public class FiniteClosureTest { + + @Test + public void testGreater() { + IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); + TypeFactory tf = new TypeFactory(); + + System.out.println("\n\n----- Greater Test -----"); + System.out.println("Greater(LinkedList) = " + fc.greater(tf.getSimpleType("LinkedList", "T"))); + System.out.println("Greater(TreeSet) = " + fc.greater(tf.getSimpleType("TreeSet", "T"))); + System.out.println("Greater(Collection) = " + fc.greater(tf.getSimpleType("Collection"))); + } + + @Test + public void testGrArg() { + IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); + TypeFactory tf = new TypeFactory(); + + System.out.println("\n\n----- GrArg Test -----"); + System.out.println("GrArg(List) = " + fc.grArg(tf.getSimpleType("List", "T"))); + System.out.println("GrArg(? extends List) = " + fc.grArg(tf.getExtendsType(tf.getSimpleType("List", "T")))); + System.out.println("GrArg(? super List) = " + fc.grArg(tf.getSuperType(tf.getSimpleType("List", "T")))); + } + + @Test + public void testSmaller() { + IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); + TypeFactory tf = new TypeFactory(); + + System.out.println("\n\n----- Smaller Test -----"); + System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", "T"))); + System.out.println("Smaller(TreeSet) = " + fc.smaller(tf.getSimpleType("TreeSet", "T"))); + System.out.println("Smaller(Collection) = " + fc.smaller(tf.getSimpleType("Collection"))); + } + + @Test + public void testSmArg() { + IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); + TypeFactory tf = new TypeFactory(); + + System.out.println("\n\n----- SmArg Test -----"); + System.out.println("SmArg(List) = " + fc.smArg(tf.getSimpleType("List", "T"))); + System.out.println("SmArg(? extends List) = " + fc.smArg(tf.getExtendsType(tf.getSimpleType("List", "T")))); + System.out.println("SmArg(? super List) = " + fc.smArg(tf.getSuperType(tf.getSimpleType("List", "T")))); + } +} diff --git a/test/unify/TypeFactory.java b/test/unify/TypeFactory.java new file mode 100644 index 00000000..46b6f7bf --- /dev/null +++ b/test/unify/TypeFactory.java @@ -0,0 +1,37 @@ +package unify; + +import java.util.Arrays; +import java.util.stream.Collectors; + +import de.dhbwstuttgart.typinference.unify.model.ExtendsType; +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 TypeFactory { + + public ExtendsType getExtendsType(Type extendedType) { + return new ExtendsType(extendedType); + } + + public SuperType getSuperType(Type superedType) { + return new SuperType(superedType); + } + + public SimpleType getSimpleType(String name) { + return new SimpleType(name); + } + + public SimpleType getSimpleType(String name, Type... typeParams) { + return new SimpleType(name, typeParams); + } + + public SimpleType getSimpleType(String name, String... typeParams) { + return new SimpleType(name, Arrays.stream(typeParams).map(x -> getPlaceholderType(x)).collect(Collectors.toList()).toArray(new Type[0])); + } + + public PlaceholderType getPlaceholderType(String name) { + return new PlaceholderType(name); + } +} From a263ba5fd493167f78d06f6c98911b326233429b Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 16:49:20 +0100 Subject: [PATCH 16/47] reduceSup --- notizen/stf/Notes | 3 + .../typeinference/unifynew/RuleSet.java | 72 +++++++++++++-- test/unify/RuleSetTest.java | 91 +++++++++++++++++++ 3 files changed, 160 insertions(+), 6 deletions(-) diff --git a/notizen/stf/Notes b/notizen/stf/Notes index ddca19be..14e847e5 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -36,6 +36,9 @@ Gilt reduce f - Typen sind anhand ihres identifiers durchgängig identifizierbar +- ReduceEq nur auf SimpleTypes oder auf alles anwenden? (Momentan alles) +- ReduceEq Permutation? + EED UP - Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...) - Erase vor Reduce diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 2b642f43..608f5584 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -116,14 +116,72 @@ public class RuleSet implements IRuleSet{ @Override public Optional> reduceSup(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + SimpleType lhsSType; + + if(lhsType instanceof SimpleType) + lhsSType = (SimpleType) lhsType; + else if(lhsType instanceof SuperType) + lhsSType = (SimpleType) ((SuperType) lhsType).getSuperedType(); + else + return Optional.empty(); + + if(lhsSType.getTypeParams().empty()) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + + if(!(rhsType instanceof SuperType)) + return Optional.empty(); + + SimpleType rhsSType = (SimpleType) ((SuperType) rhsType).getSuperedType(); + + if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + return Optional.empty(); + + int[] pi = pi(lhsSType, rhsType); + + if(pi.length == 0) + return Optional.empty(); + + Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Set result = new HashSet<>(); + + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) + result.add(new MPair(lhsTypeParams[rhsIdx], rhsTypeParams[pi[rhsIdx]], PairOperator.SMALLERDOTWC)); + + return Optional.of(result); } @Override public Optional> reduceEq(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(lhsType instanceof PlaceholderType || lhsType.getTypeParams().empty()) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(rhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) + return Optional.empty(); + + if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) + return Optional.empty(); + + // TODO Permutation? + Set result = new HashSet<>(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + + for(int i = 0; i < lhsTypeParams.length; i++) + result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.EQUALSDOT)); + + return Optional.of(result); } @Override @@ -295,15 +353,17 @@ public class RuleSet implements IRuleSet{ Optional opt = Optional.empty(); if(D instanceof ExtendsType) { SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); + + Set t = finiteClosure.grArg(cFromFc); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof ExtendsType) - .filter(x -> ((ExtendsType) x).getExtendedType().equals(dSType.getName())).findAny(); + .filter(x -> ((ExtendsType) x).getExtendedType().getName().equals(dSType.getName())).findAny(); } else if(D instanceof SuperType) { SimpleType dSType = (SimpleType) ((SuperType) D).getSuperedType(); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof SuperType) - .filter(x -> ((SuperType) x).getSuperedType().equals(dSType.getName())).findAny(); + .filter(x -> ((SuperType) x).getSuperedType().getName().equals(dSType.getName())).findAny(); } else if (D instanceof SimpleType) opt = finiteClosure.greater(cFromFc).stream() diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 5a8ee772..e561dfee 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -9,6 +9,7 @@ import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unifynew.RuleSet; +import de.dhbwstuttgart.typinference.unify.model.ExtendsType; import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; @@ -42,6 +43,16 @@ public class RuleSetTest { System.out.println(res); } + @Test + public void testReduceLow() { + + } + + @Test + public void testReduceUpLow() { + + } + @Test public void testReduce1() { Set pairs = new HashSet(); @@ -74,5 +85,85 @@ public class RuleSetTest { System.out.println(res); } + @Test + public void testReduce2() { + + } + @Test + public void testReduceExt() { + Set pairs = new HashSet(); + + SimpleType t1 = new SimpleType("t1"); + SimpleType t2 = new SimpleType("t2"); + SimpleType t3 = new SimpleType("t3"); + SimpleType t4 = new SimpleType("t4"); + SimpleType t5 = new SimpleType("t5"); + SimpleType t6 = new SimpleType("t6"); + SimpleType t7 = new SimpleType("t7"); + SimpleType t8 = new SimpleType("t8"); + SimpleType t9 = new SimpleType("t9"); + + SimpleType ta = new SimpleType("a", t1, t2, t3); + SimpleType taa = new SimpleType("a", t4, t5, t6); + SimpleType tb = new SimpleType("b", t3, t1, t2); + SimpleType tbb = new SimpleType("b", t7, t8, t9); + + + pairs.add(new MPair(ta, tb, PairOperator.SMALLER)); + FiniteClosure fc = new FiniteClosure(pairs); + + IRuleSet rules = new RuleSet(fc); + + MPair test = new MPair(taa, new ExtendsType(tbb), PairOperator.SMALLERDOTWC); + + Optional> res = rules.reduceExt(test); + + System.out.println(res); + } + + @Test + public void testReduceSup() { + + } + + @Test + public void testReduceEq() { + + } + + @Test + public void testErase1() { + + } + + @Test + public void testErase2() { + + } + + @Test + public void testErase3() { + + } + + @Test + public void testSwap() { + + } + + @Test + public void testAdapt() { + + } + + @Test + public void testAdaptExt() { + + } + + @Test + public void testAdaptSup() { + + } } From 84641d4abf99080d8a46aaf1967e1f2d9ec74681 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 18:03:21 +0100 Subject: [PATCH 17/47] application of the rules --- .../typeinference/unifynew/Unify.java | 109 +++++++++++------- 1 file changed, 69 insertions(+), 40 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 75427372..9cfc16c4 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -1,14 +1,20 @@ package de.dhbwstuttgart.typeinference.unifynew; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.PlaceholderType; /** * Implementierung des Unifikationsalgorithmus. @@ -26,16 +32,15 @@ public class Unify { /* * Step 1: Repeated application of reduce, adapt, erase, swap */ - Set eq1 = applyTypeUnificationRules(eq0, fc); + eq0 = applyTypeUnificationRules(eq0, fc); /* - * Step 2: Create subset of pairs where both sides are TPH - */ - - /* - * Step 3: Create subset of pairs that where not included in Step 2 + * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs */ + Set eq1s = new HashSet<>(); + Set eq2s = new HashSet<>(); + splitEq(eq0, eq1s, eq2s); /* * Step 4: Magic @@ -57,60 +62,84 @@ public class Unify { throw new NotImplementedException(); } - private LinkedHashSet applyTypeUnificationRules(Set eq, IFiniteClosure fc) { + private void splitEq(Set eq, Set eq1s, Set eq2s) { + for(MPair pair : eq) + if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) + eq1s.add(pair); + else + eq2s.add(pair); + } + + private Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { /* - * Strategy for better performance + * Rule Application Strategy: * - * 1. Erase all erasable rules + * 1. Swap all pairs and erase all erasable pairs * 2. Apply all possible rules to a single pair, then move it to the result set. - * Iterating over pairs first, then iterating over rules prevents the algorithm - * from trying to apply rules to a "finished" pair over and over. + * Iterating over pairs first, then iterating over rules prevents the application + * of rules to a "finished" pair over and over. * 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. - * - * 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. */ LinkedHashSet targetSet = new LinkedHashSet(); - - ArrayList eqQueue = new ArrayList<>(); + LinkedList eqQueue = new LinkedList<>(); + IRuleSet rules = new RuleSet(fc); /* - * Erase all erasable pairs or add them to the queue for further processing + * Swap all pairs and erase all erasable pairs */ - for(MPair pair : eq) - if(!(erase1(pair) || erase2(pair) || erase3(pair))) - eqQueue.add(pair); + eq.forEach(x -> swapAddOrErase(x, rules, eqQueue)); - while(!eq.isEmpty()) { - boolean ruleWasApplied = true; + /* + * Apply rules until the queue is empty + */ + while(!eqQueue.isEmpty()) { + MPair pair = eqQueue.getFirst(); + + // ReduceUp, ReduceLow, ReduceUpLow + Optional opt = rules.reduceUp(pair); + opt = opt.isPresent() ? opt : rules.reduceLow(pair); + opt = opt.isPresent() ? opt : rules.reduceUpLow(pair); - MPair pair = eqQueue.get(0); - - while(ruleWasApplied) { - ruleWasApplied = false; - - + // One of the rules has been applied + if(opt.isPresent()) { + swapAddOrErase(opt.get(), rules, eqQueue); + continue; } + + // Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq + Optional> optSet = rules.reduce1(pair); + optSet = optSet.isPresent() ? optSet : rules.reduce2(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceSup(pair); + optSet = optSet.isPresent() ? optSet : rules.reduceEq(pair); + + // One of the rules has been applied + if(optSet.isPresent()) { + optSet.get().forEach(x -> swapAddOrErase(x, rules, eqQueue)); + continue; + } + + // TODO adapt Rules + + // None of the rules has been applied + targetSet.add(pair); } - throw new NotImplementedException(); + return targetSet; } - private boolean erase1(MPair pair) { - return true; - } - - private boolean erase2(MPair pair) { - return true; - } - - private boolean erase3(MPair pair) { - return true; + private void swapAddOrErase(MPair pair, IRuleSet rules, Collection collection) { + Optional opt = rules.swap(pair); + MPair pair2 = opt.isPresent() ? opt.get() : pair; + + if(rules.erase1(pair2) || rules.erase3(pair2) || rules.erase2(pair2)) + return; + + collection.add(pair2); } } From 1b1fae6b13f76a524852cf23ffc037ae5c361c1b Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 7 Nov 2015 20:37:29 +0100 Subject: [PATCH 18/47] swap rule test --- .../typeinference/unifynew/Unify.java | 6 ++-- .../typinference/unify/model/TypeParams.java | 17 +++++++++ test/unify/FiniteClosureTest.java | 6 +++- test/unify/RuleSetTest.java | 36 +++++++++++++++++++ .../{UnifyTest.java => UnifyOldTest.java} | 2 +- 5 files changed, 62 insertions(+), 5 deletions(-) rename test/unify/{UnifyTest.java => UnifyOldTest.java} (96%) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 9cfc16c4..c347dd81 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -62,7 +62,7 @@ public class Unify { throw new NotImplementedException(); } - private void splitEq(Set eq, Set eq1s, Set eq2s) { + protected void splitEq(Set eq, Set eq1s, Set eq2s) { for(MPair pair : eq) if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) eq1s.add(pair); @@ -70,7 +70,7 @@ public class Unify { eq2s.add(pair); } - private Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { + protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { /* * Rule Application Strategy: @@ -133,7 +133,7 @@ public class Unify { return targetSet; } - private void swapAddOrErase(MPair pair, IRuleSet rules, Collection collection) { + protected void swapAddOrErase(MPair pair, IRuleSet rules, Collection collection) { Optional opt = rules.swap(pair); MPair pair2 = opt.isPresent() ? opt.get() : pair; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index bf2bdde9..c89b207d 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -34,4 +34,21 @@ public class TypeParams implements Iterable{ public Iterator iterator() { return Arrays.stream(typeParams).iterator(); } + + @Override + public int hashCode() { + return Arrays.hashCode(typeParams); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof TypeParams)) + return false; + + TypeParams other = (TypeParams) obj; + + // TODO + return other.size() == this.size(); + } } + diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 15fdf2c3..d3744abe 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -1,8 +1,12 @@ package unify; +import java.util.HashSet; +import java.util.Set; + import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.Type; public class FiniteClosureTest { @@ -11,7 +15,7 @@ public class FiniteClosureTest { public void testGreater() { IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); TypeFactory tf = new TypeFactory(); - + System.out.println("\n\n----- Greater Test -----"); System.out.println("Greater(LinkedList) = " + fc.greater(tf.getSimpleType("LinkedList", "T"))); System.out.println("Greater(TreeSet) = " + fc.greater(tf.getSimpleType("TreeSet", "T"))); diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index e561dfee..833cd392 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -5,6 +5,8 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; +import junit.framework.Assert; + import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; @@ -149,7 +151,41 @@ public class RuleSetTest { @Test public void testSwap() { + TypeFactory tf = new TypeFactory(); + RuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + /* + * Positive Tests + */ + MPair swap1 = new MPair(tf.getExtendsType(tf.getSimpleType("MyClass")), tf.getPlaceholderType("P"), PairOperator.EQUALSDOT); + MPair swap2 = new MPair(tf.getSimpleType("MyClass"), tf.getPlaceholderType("X"), PairOperator.EQUALSDOT); + + MPair expected1 = new MPair(tf.getPlaceholderType("P"), tf.getExtendsType(tf.getSimpleType("MyClass")), PairOperator.EQUALSDOT); + MPair expected2 = new MPair(tf.getPlaceholderType("X"), tf.getSimpleType("MyClass"), PairOperator.EQUALSDOT); + + Optional opt1 = rules.swap(swap1); + Optional opt2 = rules.swap(swap2); + + Assert.assertEquals(opt1.get(), expected1); + Assert.assertEquals(opt2.get(), expected2); + + /* + * Negative Tests + */ + MPair noswap1 = new MPair(tf.getPlaceholderType("Z"), tf.getPlaceholderType("X"), PairOperator.EQUALSDOT); + MPair noswap2 = new MPair(tf.getSimpleType("MyClass"), tf.getExtendsType(tf.getPlaceholderType("X")), PairOperator.EQUALSDOT); + MPair noswap3 = new MPair( tf.getPlaceholderType("X"), tf.getSimpleType("MyClass"), PairOperator.EQUALSDOT); + MPair noswap4 = new MPair(tf.getSimpleType("MyClass"), tf.getPlaceholderType("X"), PairOperator.SMALLERDOT); + + opt1 = rules.swap(noswap1); + opt2 = rules.swap(noswap2); + Optional opt3 = rules.swap(noswap3); + Optional opt4 = rules.swap(noswap4); + + Assert.assertFalse(opt1.isPresent()); + Assert.assertFalse(opt2.isPresent()); + Assert.assertFalse(opt3.isPresent()); + Assert.assertFalse(opt4.isPresent()); } @Test diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyOldTest.java similarity index 96% rename from test/unify/UnifyTest.java rename to test/unify/UnifyOldTest.java index 93f0d9c0..85f5ffd5 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyOldTest.java @@ -14,7 +14,7 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.Pair.PairOperator; import de.dhbwstuttgart.typeinference.unify.Unify; -public class UnifyTest { +public class UnifyOldTest { @Test public void unifyTestSimpleTypes() { From 2eb11748ca000d65f38778b1b12c6c27edd1f902 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 16:29:40 +0100 Subject: [PATCH 19/47] erase1 and erase2 tests --- .../typeinference/unifynew/RuleSet.java | 11 +--- .../typinference/unify/model/ExtendsType.java | 14 +++++ .../unify/model/PlaceholderType.java | 13 +++++ .../typinference/unify/model/SimpleType.java | 18 ++++++ .../typinference/unify/model/SuperType.java | 14 +++++ .../typinference/unify/model/Type.java | 21 ------- test/unify/RuleSetTest.java | 56 +++++++++++++++++++ 7 files changed, 118 insertions(+), 29 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 608f5584..c391bd02 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -280,7 +280,7 @@ public class RuleSet implements IRuleSet{ if(!(rhsType instanceof SimpleType) && !(rhsType instanceof PlaceholderType)) return false; - return finiteClosure.smaller(lhsType).contains(rhsType); + return finiteClosure.greater(lhsType).contains(rhsType); } @Override @@ -288,15 +288,10 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return false; - Type lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof PlaceholderType)) - return false; - + Type lhsType = pair.getLhsType(); Type rhsType = pair.getRhsType(); - if(!(rhsType instanceof ExtendsType)) - return false; - return finiteClosure.grArg(lhsType).contains(((ExtendsType) rhsType).getExtendedType()); + return finiteClosure.grArg(lhsType).contains(rhsType); } @Override diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index 7a65fc30..c01ff5d4 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -34,4 +34,18 @@ public class ExtendsType extends Type { public Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + + @Override + public int hashCode() { + return extendedType.hashCode() + 17; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof ExtendsType)) + return false; + + ExtendsType other = (ExtendsType) obj; + return other.getExtendedType().equals(extendedType); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index 0c9aacd1..48cf2e6f 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -19,4 +19,17 @@ public class PlaceholderType extends Type{ public Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof PlaceholderType)) + return false; + + return ((PlaceholderType) obj).getName().equals(typeName); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 8f1ceaae..199c6518 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -19,4 +19,22 @@ public class SimpleType extends Type { public Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof SimpleType)) + return false; + + SimpleType other = (SimpleType) obj; + + if(!other.getName().equals(typeName)) + return false; + + return other.getTypeParams().equals(typeParams); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index d7f0f38a..5a734621 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -35,4 +35,18 @@ public class SuperType extends Type { public Set grArg(IFiniteClosure fc) { return fc.grArg(this); } + + @Override + public int hashCode() { + return superedType.hashCode() + 17; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof SuperType)) + return false; + + SuperType other = (SuperType) obj; + return other.getSuperedType().equals(superedType); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index 676bb574..dc5a9d91 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -21,31 +21,10 @@ public abstract class Type { public TypeParams getTypeParams() { return typeParams; } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof Type)) - return false; - if(obj.hashCode() != hashCode()) - return false; - - Type other = (Type) obj; - - if(!other.getName().equals(typeName)) - return false; - - return other.getTypeParams().equals(typeParams); - } public abstract Set smArg(IFiniteClosure fc); public abstract Set grArg(IFiniteClosure fc); - - - @Override - public int hashCode() { - return typeName.hashCode(); - } @Override public String toString() { diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 833cd392..dc52c9ec 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -136,12 +136,65 @@ public class RuleSetTest { @Test public void testErase1() { + TypeFactory tf = new TypeFactory(); + RuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); + /* + * Positive Tests + */ + MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); + MPair erase2 = new MPair(tf.getSimpleType("HashSet", "W"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); + MPair erase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); + + Assert.assertTrue(rules.erase1(erase1)); + Assert.assertTrue(rules.erase1(erase2)); + Assert.assertTrue(rules.erase1(erase3)); + + /* + * Negative Tests + */ + MPair noerase1 = new MPair(tf.getSimpleType("Collection"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); + MPair noerase2 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.EQUALSDOT); + MPair noerase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOTWC); + + Assert.assertFalse(rules.erase1(noerase1)); + Assert.assertFalse(rules.erase1(noerase2)); + Assert.assertFalse(rules.erase1(noerase3)); } @Test public void testErase2() { + TypeFactory tf = new TypeFactory(); + RuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); + /* + * Positive Tests + */ + MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getExtendsType(tf.getSimpleType("Collection")), PairOperator.SMALLERDOTWC); + MPair erase2 = new MPair(tf.getSimpleType("Collection"), tf.getSuperType(tf.getSimpleType("HashSet", "T")), PairOperator.SMALLERDOTWC); + MPair erase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOTWC); + MPair erase4 = new MPair(tf.getExtendsType(tf.getSimpleType("LinkedList", "T")), tf.getExtendsType(tf.getSimpleType("List", "T")), PairOperator.SMALLERDOTWC); + MPair erase5 = new MPair(tf.getSuperType(tf.getSimpleType("List", "T")), tf.getSuperType(tf.getSimpleType("Stack", "T")), PairOperator.SMALLERDOTWC); + + + Assert.assertTrue(rules.erase2(erase1)); + Assert.assertTrue(rules.erase2(erase2)); + Assert.assertTrue(rules.erase2(erase3)); + Assert.assertTrue(rules.erase2(erase4)); + Assert.assertTrue(rules.erase2(erase5)); + + /* + * Negative Tests + */ + MPair noerase1 = new MPair(tf.getSimpleType("Collection"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOTWC); + MPair noerase2 = new MPair(tf.getSuperType(tf.getSimpleType("List", "T")), tf.getSimpleType("ArrayList", "T"), PairOperator.SMALLERDOTWC); + MPair noerase3 = new MPair(tf.getExtendsType(tf.getSimpleType("List", "T")), tf.getSuperType(tf.getSimpleType("List", "T")), PairOperator.SMALLERDOTWC); + MPair noerase4 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); + + Assert.assertFalse(rules.erase2(noerase1)); + Assert.assertFalse(rules.erase2(noerase2)); + Assert.assertFalse(rules.erase2(noerase3)); + Assert.assertFalse(rules.erase2(noerase4)); } @Test @@ -166,7 +219,10 @@ public class RuleSetTest { Optional opt1 = rules.swap(swap1); Optional opt2 = rules.swap(swap2); + // swap((? extends MyClass =. P)) = (P =. MyClass) Assert.assertEquals(opt1.get(), expected1); + + // swap((MyClass =. X)) = (X =. MyClass) Assert.assertEquals(opt2.get(), expected2); /* From 4c6c77929fac8ab2080f9af6f7d184dbbe53bbd8 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 16:42:57 +0100 Subject: [PATCH 20/47] erase3 test --- test/unify/RuleSetTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index dc52c9ec..b43f396c 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -199,7 +199,26 @@ public class RuleSetTest { @Test public void testErase3() { + TypeFactory tf = new TypeFactory(); + RuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + /* + * Positive Tests + */ + MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.EQUALSDOT); + MPair erase2 = new MPair(tf.getPlaceholderType("W"), tf.getPlaceholderType("W"), PairOperator.EQUALSDOT); + + Assert.assertTrue(rules.erase3(erase1)); + Assert.assertTrue(rules.erase3(erase2)); + + /* + * Negative Tests + */ + MPair noerase1 = new MPair(tf.getSimpleType("Collection"), tf.getSimpleType("List", "T"), PairOperator.EQUALSDOT); + MPair noerase2 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); + + Assert.assertFalse(rules.erase3(noerase1)); + Assert.assertFalse(rules.erase3(noerase2)); } @Test From b3514a83759dc4fb7fe28b4612df131618c2f496 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 17:02:25 +0100 Subject: [PATCH 21/47] reduceUp and reduceLow tests --- .../typeinference/unifynew/Unify.java | 4 +- .../typinference/unify/model/MPair.java | 4 +- test/unify/RuleSetTest.java | 83 ++++++++++++++----- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index c347dd81..2047b150 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -101,9 +101,9 @@ public class Unify { MPair pair = eqQueue.getFirst(); // ReduceUp, ReduceLow, ReduceUpLow - Optional opt = rules.reduceUp(pair); + Optional opt = rules.reduceUpLow(pair); opt = opt.isPresent() ? opt : rules.reduceLow(pair); - opt = opt.isPresent() ? opt : rules.reduceUpLow(pair); + opt = opt.isPresent() ? opt : rules.reduceUp(pair); // One of the rules has been applied if(opt.isPresent()) { diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index 4a811940..0088d02a 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -58,9 +58,7 @@ public class MPair { public boolean equals(Object obj) { if(!(obj instanceof MPair)) return false; - if(obj.hashCode() != hashCode()) - return false; - + MPair other = (MPair) obj; return other.getPairOp() == pairOp diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index b43f396c..d76546a0 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -23,31 +23,76 @@ public class RuleSetTest { @Test public void testReduceUp() { - Set pairs = new HashSet(); + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + TypeFactory tf = new TypeFactory(); + + /* + * Positive Tests + */ - SimpleType t1 = new SimpleType("Set"); - SimpleType t2 = new SimpleType("HashSet"); - SimpleType t3 = new SimpleType("Something"); + MPair reduce1 = new MPair(tf.getSimpleType("type"), tf.getSuperType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair reduce2 = new MPair(tf.getPlaceholderType("T"), tf.getSuperType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + + MPair expected1 = new MPair(tf.getSimpleType("type"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair expected2 = new MPair(tf.getPlaceholderType("T"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); - SuperType s = new SuperType(t2); + Optional opt1 = rules.reduceUp(reduce1); + Optional opt2 = rules.reduceUp(reduce2); - pairs.add(new MPair(t1, t2, PairOperator.SMALLER)); + Assert.assertTrue(opt1.isPresent()); + Assert.assertTrue(opt2.isPresent()); + Assert.assertEquals(opt1.get(), expected1); + Assert.assertEquals(opt2.get(), expected2); + + /* + * Negative Tests + */ - FiniteClosure fc = new FiniteClosure(pairs); + MPair noreduce1 = new MPair(tf.getSuperType(tf.getSimpleType("type")), tf.getSuperType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair noreduce2 = new MPair(tf.getPlaceholderType("T"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair noreduce3 = new MPair(tf.getPlaceholderType("T"), tf.getExtendsType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair noreduce4 = new MPair(tf.getPlaceholderType("T"), tf.getSuperType(tf.getSimpleType("type")), PairOperator.EQUALSDOT); - IRuleSet rules = new RuleSet(fc); - - MPair test = new MPair(t3, s, PairOperator.SMALLERDOT); - - - Optional res = rules.reduceUp(test); - - System.out.println(res); + Assert.assertFalse(rules.reduceUp(noreduce1).isPresent()); + Assert.assertFalse(rules.reduceUp(noreduce2).isPresent()); + Assert.assertFalse(rules.reduceUp(noreduce3).isPresent()); + Assert.assertFalse(rules.reduceUp(noreduce4).isPresent()); } @Test public void testReduceLow() { + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + TypeFactory tf = new TypeFactory(); + + /* + * Positive Tests + */ + MPair reduce1 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair reduce2 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getPlaceholderType("T"), PairOperator.SMALLERDOT); + + MPair expected1 = new MPair(tf.getSimpleType("type"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair expected2 = new MPair(tf.getSimpleType("type"), tf.getPlaceholderType("T"), PairOperator.SMALLERDOT); + Optional opt1 = rules.reduceLow(reduce1); + Optional opt2 = rules.reduceLow(reduce2); + + Assert.assertTrue(opt1.isPresent()); + Assert.assertTrue(opt2.isPresent()); + Assert.assertEquals(opt1.get(), expected1); + Assert.assertEquals(opt2.get(), expected2); + + /* + * Negative Tests + */ + MPair noreduce1 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getExtendsType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair noreduce2 = new MPair(tf.getPlaceholderType("T"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair noreduce3 = new MPair(tf.getSuperType(tf.getPlaceholderType("T")), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair noreduce4 = new MPair(tf.getExtendsType(tf.getPlaceholderType("T")), tf.getSimpleType("type"), PairOperator.EQUALSDOT); + + Assert.assertFalse(rules.reduceLow(noreduce1).isPresent()); + Assert.assertFalse(rules.reduceLow(noreduce2).isPresent()); + Assert.assertFalse(rules.reduceLow(noreduce3).isPresent()); + Assert.assertFalse(rules.reduceLow(noreduce4).isPresent()); } @Test @@ -137,7 +182,7 @@ public class RuleSetTest { @Test public void testErase1() { TypeFactory tf = new TypeFactory(); - RuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); /* * Positive Tests @@ -165,7 +210,7 @@ public class RuleSetTest { @Test public void testErase2() { TypeFactory tf = new TypeFactory(); - RuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getCollectionExample()); /* * Positive Tests @@ -200,7 +245,7 @@ public class RuleSetTest { @Test public void testErase3() { TypeFactory tf = new TypeFactory(); - RuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); /* * Positive Tests @@ -224,7 +269,7 @@ public class RuleSetTest { @Test public void testSwap() { TypeFactory tf = new TypeFactory(); - RuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); /* * Positive Tests From e6954292622e047cf2fc4aa2fd3a281a8b36e5cb Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 17:05:35 +0100 Subject: [PATCH 22/47] reduceUpLow test --- test/unify/RuleSetTest.java | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index d76546a0..65fdb19f 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -16,7 +16,6 @@ import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typinference.unify.model.SimpleType; -import de.dhbwstuttgart.typinference.unify.model.SuperType; public class RuleSetTest { @@ -97,7 +96,38 @@ public class RuleSetTest { @Test public void testReduceUpLow() { + IRuleSet rules = new RuleSet(new FiniteClosureBuilder().getFiniteClosure()); + TypeFactory tf = new TypeFactory(); + + /* + * Positive Tests + */ + MPair reduce1 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getSuperType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair reduce2 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getSuperType(tf.getPlaceholderType("T")), PairOperator.SMALLERDOT); + + MPair expected1 = new MPair(tf.getSimpleType("type"), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair expected2 = new MPair(tf.getSimpleType("type"), tf.getPlaceholderType("T"), PairOperator.SMALLERDOT); + Optional opt1 = rules.reduceUpLow(reduce1); + Optional opt2 = rules.reduceUpLow(reduce2); + + Assert.assertTrue(opt1.isPresent()); + Assert.assertTrue(opt2.isPresent()); + Assert.assertEquals(opt1.get(), expected1); + Assert.assertEquals(opt2.get(), expected2); + + /* + * Negative Tests + */ + MPair noreduce1 = new MPair(tf.getExtendsType(tf.getSimpleType("type")), tf.getExtendsType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair noreduce2 = new MPair(tf.getSuperType(tf.getPlaceholderType("T")), tf.getExtendsType(tf.getSimpleType("type")), PairOperator.SMALLERDOT); + MPair noreduce3 = new MPair(tf.getSuperType(tf.getPlaceholderType("T")), tf.getSimpleType("type"), PairOperator.SMALLERDOT); + MPair noreduce4 = new MPair(tf.getExtendsType(tf.getPlaceholderType("T")), tf.getSimpleType("type"), PairOperator.EQUALSDOT); + + Assert.assertFalse(rules.reduceUpLow(noreduce1).isPresent()); + Assert.assertFalse(rules.reduceUpLow(noreduce2).isPresent()); + Assert.assertFalse(rules.reduceUpLow(noreduce3).isPresent()); + Assert.assertFalse(rules.reduceUpLow(noreduce4).isPresent()); } @Test From 777a9b5beb6dbfe27f396a80cfcca5b13a61d4ed Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 21:23:20 +0100 Subject: [PATCH 23/47] reduce1 and reduceEq Tests --- .../typeinference/unifynew/RuleSet.java | 4 + test/unify/FiniteClosureBuilder.java | 10 +- test/unify/RuleSetTest.java | 95 ++++++++++++++----- 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index c391bd02..00ee34db 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -167,6 +167,10 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type rhsType = pair.getRhsType(); + + if(!rhsType.getName().equals(lhsType.getName())) + return Optional.empty(); + if(rhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) return Optional.empty(); diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index acce7b5b..f35ce0e4 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -18,9 +18,11 @@ public class FiniteClosureBuilder { } public IFiniteClosure getFiniteClosure() { - FiniteClosure fc = new FiniteClosure(pairs); + return new FiniteClosure(pairs); + } + + public void clear() { pairs = new HashSet<>(); - return fc; } public IFiniteClosure getCollectionExample() { @@ -55,6 +57,8 @@ public class FiniteClosureBuilder { add(arrayList, list); add(stack, vector); - return getFiniteClosure(); + IFiniteClosure fc = getFiniteClosure(); + clear(); + return fc; } } diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 65fdb19f..0776b2b1 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -132,34 +132,56 @@ public class RuleSetTest { @Test public void testReduce1() { - Set pairs = new HashSet(); + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - SimpleType t1 = new SimpleType("t1"); - SimpleType t2 = new SimpleType("t2"); - SimpleType t3 = new SimpleType("t3"); - SimpleType t4 = new SimpleType("t4"); - SimpleType t5 = new SimpleType("t5"); - SimpleType t6 = new SimpleType("t6"); - SimpleType t7 = new SimpleType("t7"); - SimpleType t8 = new SimpleType("t8"); - SimpleType t9 = new SimpleType("t9"); + /* + * Positive Tests + */ - SimpleType ta = new SimpleType("a", t1, t2, t3); - SimpleType taa = new SimpleType("a", t4, t5, t6); - SimpleType tb = new SimpleType("b", t3, t1, t2); - SimpleType tbb = new SimpleType("b", t7, t8, t9); + // C + SimpleType c1 = tf.getSimpleType("C", "T1", "T2", "T3", "T4"); + // D + SimpleType d1 = tf.getSimpleType("D", "T4", "T1", "T2", "T3"); + SimpleType buffer = tf.getSimpleType("Buffer"); + //C + SimpleType c2 = tf.getSimpleType("C", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + //D, Number, Double, N> + SimpleType d2 = tf.getSimpleType("D", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N")); - pairs.add(new MPair(ta, tb, PairOperator.SMALLER)); - FiniteClosure fc = new FiniteClosure(pairs); + // C<...> < buffer < D<...> + fcb.add(c1, buffer); + fcb.add(buffer, d1); - IRuleSet rules = new RuleSet(fc); - - MPair test = new MPair(taa, tbb, PairOperator.SMALLERDOT); - - Optional> res = rules.reduce1(test); + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + MPair pair = new MPair(c2, d2, PairOperator.SMALLERDOT); + System.out.println("------ Reduce1 ------"); + Optional> res = rules.reduce1(pair); System.out.println(res); + + pair = new MPair(c2, c2, PairOperator.SMALLERDOT); + res = rules.reduce1(pair); + System.out.println(res); + + /* + * Negative Tests + */ + + // Case 1: D <. C and C <* D + pair = new MPair(d2, c2, PairOperator.SMALLERDOT); + Assert.assertFalse(rules.reduce1(pair).isPresent()); + + // Case 2: D =. C + pair = new MPair(c2, d2, PairOperator.EQUALSDOT); + Assert.assertFalse(rules.reduce1(pair).isPresent()); + + // Case 3: C <. D and !(C <* D) + fcb.clear(); + rules = new RuleSet(fcb.getFiniteClosure()); + pair = new MPair(c1, d1, PairOperator.SMALLERDOT); + Assert.assertFalse(rules.reduce1(pair).isPresent()); } @Test @@ -196,7 +218,7 @@ public class RuleSetTest { Optional> res = rules.reduceExt(test); - System.out.println(res); + //System.out.println(res); } @Test @@ -206,7 +228,36 @@ public class RuleSetTest { @Test public void testReduceEq() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + /* + * Positive Tests + */ + System.out.println("----- ReduceEq ------"); + + // C + SimpleType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); + // D + SimpleType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + + MPair pair = new MPair(c1, c2, PairOperator.SMALLERDOTWC); + Optional> res = rules.reduceEq(pair); + System.out.println(res); + + /* + * Negative Tests + */ + + // Case 1: D <.? C + SimpleType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + pair = new MPair(d1, c1, PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceEq(pair).isPresent()); + + // Case 2: C <. C + pair = new MPair(c1, c2, PairOperator.SMALLERDOT); + Assert.assertFalse(rules.reduceEq(pair).isPresent()); } @Test From 176ec7b7070eadc314f9ee6cbc7c15c66140b701 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 21:30:17 +0100 Subject: [PATCH 24/47] subst rule interface --- .../typeinference/unify/interfaces/IRuleSet.java | 2 ++ .../typeinference/unify/interfaces/IUnifier.java | 9 +++++++++ src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java | 7 +++++++ 3 files changed, 18 insertions(+) create mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index 88f98ac7..ad0655ef 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -25,4 +25,6 @@ public interface IRuleSet { public MPair adapt(MPair pair); public MPair adaptExt(MPair pair); public MPair adaptSup(MPair pair); + + public Optional subst(MPair pair); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java new file mode 100644 index 00000000..ca0d6ce2 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.typeinference.unify.interfaces; + +import java.util.Optional; + +import de.dhbwstuttgart.typinference.unify.model.MPair; + +public interface IUnifier { + public Optional apply(MPair pair); +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 00ee34db..9424ba2b 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -7,6 +7,7 @@ import java.util.Set; import junit.framework.Assert; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; +import de.dhbwstuttgart.typeinference.unify.interfaces.IUnifier; import de.dhbwstuttgart.typinference.unify.model.ExtendsType; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; @@ -396,5 +397,11 @@ public class RuleSet implements IRuleSet{ if(succ) return permutation; return new int[0]; } + + @Override + public Optional subst(MPair pair) { + // TODO Auto-generated method stub + return null; + } } From 7ada9cbd4740fbad247054f040aca795863fd591 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 21:41:24 +0100 Subject: [PATCH 25/47] reduce 2 Test --- test/unify/RuleSetTest.java | 44 ++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 0776b2b1..26aefa59 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -16,6 +16,7 @@ import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typinference.unify.model.SimpleType; +import de.dhbwstuttgart.typinference.unify.model.SuperType; public class RuleSetTest { @@ -186,7 +187,48 @@ public class RuleSetTest { @Test public void testReduce2() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + /* + * Positive Tests + */ + System.out.println("----- Reduce2 ------"); + + // C + SimpleType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); + // C + SimpleType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + + MPair pair1 = new MPair(c1, c2, PairOperator.EQUALSDOT); + MPair pair2 = new MPair(tf.getExtendsType(c1), tf.getExtendsType(c2), PairOperator.EQUALSDOT); + MPair pair3 = new MPair(tf.getSuperType(c1), tf.getSuperType(c2), PairOperator.EQUALSDOT); + + Optional> opt1 = rules.reduce2(pair1); + System.out.println(opt1); + + Optional> opt2 = rules.reduce2(pair2); + System.out.println(opt2); + + Optional> opt3 = rules.reduce2(pair3); + System.out.println(opt3); + + + /* + * Negative Tests + */ + + SimpleType d1 = tf.getSimpleType("D", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); + pair1 = new MPair(d1, c1, PairOperator.EQUALSDOT); // Case 1: D =. C + pair2 = new MPair(tf.getExtendsType(c1), c2, PairOperator.EQUALSDOT); // Case 2: ? extends C =. C + pair3 = new MPair(tf.getExtendsType(c1), tf.getSuperType(c2), PairOperator.EQUALSDOT); // Case 3: ? extends C =. ? super C + MPair pair4 = new MPair(c1, c2, PairOperator.SMALLERDOT); // Case 4: C <. C + + Assert.assertFalse(rules.reduceEq(pair1).isPresent()); + Assert.assertFalse(rules.reduceEq(pair2).isPresent()); + Assert.assertFalse(rules.reduceEq(pair3).isPresent()); + Assert.assertFalse(rules.reduceEq(pair4).isPresent()); } @Test @@ -239,7 +281,7 @@ public class RuleSetTest { // C SimpleType c1 = tf.getSimpleType("C", tf.getPlaceholderType("T1"), tf.getSimpleType("SType1"), tf.getExtendsType(tf.getSimpleType("SType1"))); - // D + // C SimpleType c2 = tf.getSimpleType("C", tf.getPlaceholderType("T2"), tf.getSimpleType("SType2"), tf.getExtendsType(tf.getSimpleType("SType2"))); MPair pair = new MPair(c1, c2, PairOperator.SMALLERDOTWC); From eeba9fb73402f03a4e7d760e4bd38c0492cee4f2 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 22:21:28 +0100 Subject: [PATCH 26/47] reduceSup Test --- .../typeinference/unifynew/RuleSet.java | 61 +++++++------------ test/unify/RuleSetTest.java | 57 +++++++++++++++++ 2 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 9424ba2b..43e33640 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -78,35 +78,25 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type lhsType = pair.getLhsType(); - SimpleType lhsSType; - if(lhsType instanceof SimpleType) - lhsSType = (SimpleType) lhsType; - else if(lhsType instanceof ExtendsType) - lhsSType = (SimpleType) ((ExtendsType) lhsType).getExtendedType(); - else - return Optional.empty(); - - if(lhsSType.getTypeParams().empty()) + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof ExtendsType)) return Optional.empty(); - - SimpleType rhsSType = (SimpleType) ((ExtendsType) rhsType).getExtendedType(); - - if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + + if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsSType, rhsType); + int[] pi = pi(lhsType, rhsType); if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) @@ -121,39 +111,29 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); Type lhsType = pair.getLhsType(); - SimpleType lhsSType; - if(lhsType instanceof SimpleType) - lhsSType = (SimpleType) lhsType; - else if(lhsType instanceof SuperType) - lhsSType = (SimpleType) ((SuperType) lhsType).getSuperedType(); - else - return Optional.empty(); - - if(lhsSType.getTypeParams().empty()) + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType)) return Optional.empty(); Type rhsType = pair.getRhsType(); if(!(rhsType instanceof SuperType)) return Optional.empty(); - - SimpleType rhsSType = (SimpleType) ((SuperType) rhsType).getSuperedType(); - - if(rhsSType.getTypeParams().size() != lhsSType.getTypeParams().size()) + + if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsSType, rhsType); + int[] pi = pi(lhsType, rhsType); if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); + Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[rhsIdx], rhsTypeParams[pi[rhsIdx]], PairOperator.SMALLERDOTWC)); + result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -205,7 +185,7 @@ public class RuleSet implements IRuleSet{ SimpleType lhsSType = (SimpleType) lhsType; SimpleType rhsSType = (SimpleType) rhsType; - if(lhsSType.getTypeParams().empty() || rhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) + if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) return Optional.empty(); int[] pi = pi(lhsSType, rhsSType); @@ -267,7 +247,7 @@ public class RuleSet implements IRuleSet{ Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); for(int i = 0; i < rhsTypeParams.length; i++) - result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.SMALLERDOT)); + result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.EQUALSDOT)); return Optional.of(result); } @@ -346,15 +326,20 @@ public class RuleSet implements IRuleSet{ * @return An array containing the values of pi for every type argument of C or an empty array if the search failed. */ private int[] pi(Type C, Type D) { - Type cFromFc = finiteClosure.getType(C.getName()); + Type cFromFc = null; + if(C instanceof SimpleType) + cFromFc = finiteClosure.getType(C.getName()); + else if(C instanceof ExtendsType) + cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType().getName())); + else if(C instanceof SuperType) + cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType().getName())); + if(cFromFc == null) return new int[0]; Optional opt = Optional.empty(); if(D instanceof ExtendsType) { SimpleType dSType = (SimpleType) ((ExtendsType) D).getExtendedType(); - - Set t = finiteClosure.grArg(cFromFc); opt = finiteClosure.grArg(cFromFc).stream() .filter(x -> x instanceof ExtendsType) .filter(x -> ((ExtendsType) x).getExtendedType().getName().equals(dSType.getName())).findAny(); diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 26aefa59..754e3a25 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -265,7 +265,64 @@ public class RuleSetTest { @Test public void testReduceSup() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + /* + * Positive Tests + */ + + // X + SimpleType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); + // Y + SimpleType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); + SimpleType buffer = tf.getSimpleType("Buffer"); + + //X + SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + //? extends Y, Number, Double, N> + SuperType supY1 = tf.getSuperType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); + + // Y<...> < buffer < X<...> + fcb.add(y1, buffer); + fcb.add(buffer, x1); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + MPair pair1 = new MPair(x2, supY1, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(tf.getSuperType(x2), supY1, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(supY1, supY1, PairOperator.SMALLERDOTWC); + + System.out.println("------ ReduceSup ------"); + Optional> opt1 = rules.reduceSup(pair1); + System.out.println(opt1); + + Optional> opt2 = rules.reduceSup(pair2); + System.out.println(opt2); + + Optional> opt3 = rules.reduceSup(pair3); + System.out.println(opt3); + + /* + * Negative Tests + */ + + // Case 1: X <.? Y + pair1 = new MPair(x2, supY1.getSuperedType(), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair1).isPresent()); + + // Case 2: X =. ? super Y + pair2 = new MPair(x2, supY1, PairOperator.EQUALSDOT); + Assert.assertFalse(rules.reduceSup(pair2).isPresent()); + + // Case 3: ? super Y <.? ? super X + pair3 = new MPair(supY1, tf.getSuperType(x2), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair3).isPresent()); + + // Case 4: X <. ? super Y and ? super Y not in grArg(X) + fcb.clear(); + rules = new RuleSet(fcb.getFiniteClosure()); + pair1 = new MPair(x2, supY1, PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceSup(pair1).isPresent()); } @Test From c1e4fce67fa2b84a4674c59d87e76912b627188e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 22:25:23 +0100 Subject: [PATCH 27/47] reduce Ext Tests --- test/unify/RuleSetTest.java | 72 ++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 754e3a25..b44e62ce 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -233,34 +233,64 @@ public class RuleSetTest { @Test public void testReduceExt() { - Set pairs = new HashSet(); + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - SimpleType t1 = new SimpleType("t1"); - SimpleType t2 = new SimpleType("t2"); - SimpleType t3 = new SimpleType("t3"); - SimpleType t4 = new SimpleType("t4"); - SimpleType t5 = new SimpleType("t5"); - SimpleType t6 = new SimpleType("t6"); - SimpleType t7 = new SimpleType("t7"); - SimpleType t8 = new SimpleType("t8"); - SimpleType t9 = new SimpleType("t9"); + /* + * Positive Tests + */ - SimpleType ta = new SimpleType("a", t1, t2, t3); - SimpleType taa = new SimpleType("a", t4, t5, t6); - SimpleType tb = new SimpleType("b", t3, t1, t2); - SimpleType tbb = new SimpleType("b", t7, t8, t9); + // X + SimpleType x1 = tf.getSimpleType("X", "T1", "T2", "T3", "T4"); + // Y + SimpleType y1 = tf.getSimpleType("Y", "T4", "T1", "T2", "T3"); + SimpleType buffer = tf.getSimpleType("Buffer"); + //X + SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); + //? extends Y, Number, Double, N> + ExtendsType extY1 = tf.getExtendsType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); - pairs.add(new MPair(ta, tb, PairOperator.SMALLER)); - FiniteClosure fc = new FiniteClosure(pairs); + // Y<...> < buffer < X<...> + fcb.add(x1, buffer); + fcb.add(buffer, y1); - IRuleSet rules = new RuleSet(fc); + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + MPair pair1 = new MPair(x2, extY1, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(tf.getExtendsType(x2), extY1, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(extY1, extY1, PairOperator.SMALLERDOTWC); - MPair test = new MPair(taa, new ExtendsType(tbb), PairOperator.SMALLERDOTWC); + System.out.println("------ ReduceExt ------"); + Optional> opt1 = rules.reduceExt(pair1); + System.out.println(opt1); - Optional> res = rules.reduceExt(test); + Optional> opt2 = rules.reduceExt(pair2); + System.out.println(opt2); - //System.out.println(res); + Optional> opt3 = rules.reduceExt(pair3); + System.out.println(opt3); + + /* + * Negative Tests + */ + + // Case 1: X <.? Y + pair1 = new MPair(x2, extY1.getExtendedType(), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceExt(pair1).isPresent()); + + // Case 2: X =. ? super Y + pair2 = new MPair(x2, extY1, PairOperator.EQUALSDOT); + Assert.assertFalse(rules.reduceExt(pair2).isPresent()); + + // Case 3: ? extends Y <.? ? extends X + pair3 = new MPair(extY1, tf.getExtendsType(x2), PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceExt(pair3).isPresent()); + + // Case 4: X <. ? extends Y and ? extends Y not in grArg(X) + fcb.clear(); + rules = new RuleSet(fcb.getFiniteClosure()); + pair1 = new MPair(x2, extY1, PairOperator.SMALLERDOTWC); + Assert.assertFalse(rules.reduceExt(pair1).isPresent()); } @Test @@ -280,7 +310,7 @@ public class RuleSetTest { //X SimpleType x2 = tf.getSimpleType("X", tf.getSimpleType("Int"), tf.getExtendsType(tf.getSimpleType("Double")), tf.getPlaceholderType("M"), tf.getPlaceholderType("N")); - //? extends Y, Number, Double, N> + //? super Y, Number, Double, N> SuperType supY1 = tf.getSuperType(tf.getSimpleType("Y", tf.getSuperType(tf.getSimpleType("HashSet", "Int")), tf.getSimpleType("Number"), tf.getSimpleType("Double"), tf.getPlaceholderType("N"))); // Y<...> < buffer < X<...> From 01ef0e9385f6f7e5c29a82a44ea0753ff29aa587 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 8 Nov 2015 22:25:58 +0100 Subject: [PATCH 28/47] organize imports --- test/unify/RuleSetTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index b44e62ce..f9cdce8c 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -1,7 +1,6 @@ package unify; -import java.util.HashSet; import java.util.Optional; import java.util.Set; @@ -12,7 +11,6 @@ import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unifynew.RuleSet; import de.dhbwstuttgart.typinference.unify.model.ExtendsType; -import de.dhbwstuttgart.typinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typinference.unify.model.SimpleType; From c83697dedbb097118b6990ad5b13e8d087545923 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 9 Nov 2015 14:39:26 +0100 Subject: [PATCH 29/47] Unfifier --- .../unify/interfaces/IUnifier.java | 6 +++--- .../typeinference/unifynew/Unify.java | 10 ++++++++++ .../typinference/unify/model/MPair.java | 17 +++++++++++++++++ test/unify/UnifyTest.java | 7 +++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/unify/UnifyTest.java diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java index ca0d6ce2..da18fa8f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java @@ -1,9 +1,9 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; -import java.util.Optional; +import java.util.function.Function; import de.dhbwstuttgart.typinference.unify.model.MPair; -public interface IUnifier { - public Optional apply(MPair pair); +public interface IUnifier extends Function{ + } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 2047b150..1313b6fa 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -13,8 +13,11 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; +import de.dhbwstuttgart.typeinference.unify.interfaces.IUnifier; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.PlaceholderType; +import de.dhbwstuttgart.typinference.unify.model.SimpleType; +import de.dhbwstuttgart.typinference.unify.model.Type; /** * Implementierung des Unifikationsalgorithmus. @@ -142,4 +145,11 @@ public class Unify { collection.add(pair2); } + + private void test() { + Type t = new PlaceholderType("T"); + Type subst = new SimpleType("Subst"); + + IUnifier u = x -> x.substitute(t, subst); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java index 0088d02a..9a76f2a9 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/MPair.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/MPair.java @@ -66,6 +66,23 @@ public class MPair { && other.getRhsType().equals(rhs); } + /** + * Substitutes the occurrences of Type t on the left or right side of the pair with the Type subst. + * @param t Type to be replaced. + * @param subst The type replacing t. + * @return A pair where occurrences of t are replaced by subst. + */ + public MPair substitute(Type t, Type subst) { + Type newlhs = lhs; + if(lhs.equals(t)) newlhs = subst; + + Type newrhs = rhs; + if(rhs.equals(t)) newrhs = subst; + + if(newlhs == lhs && newrhs == rhs) return this; + return new MPair(newlhs, newrhs, pairOp); + } + @Override public int hashCode() { return 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java new file mode 100644 index 00000000..747374b2 --- /dev/null +++ b/test/unify/UnifyTest.java @@ -0,0 +1,7 @@ +package unify; + +import de.dhbwstuttgart.typeinference.unifynew.Unify; + +public class UnifyTest extends Unify { + +} From 9f37139ab35cc63a2940ee6b67692632867c8da7 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 13 Nov 2015 22:45:13 +0100 Subject: [PATCH 30/47] real immutability --- .../typinference/unify/model/ExtendsType.java | 3 ++- .../unify/model/PlaceholderType.java | 4 ++-- .../typinference/unify/model/SimpleType.java | 5 ++--- .../typinference/unify/model/SuperType.java | 3 ++- .../typinference/unify/model/Type.java | 15 ++++++++----- .../typinference/unify/model/TypeParams.java | 22 +++++++++++++++---- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index c01ff5d4..d648c249 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -4,10 +4,11 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class ExtendsType extends Type { +public final class ExtendsType extends Type { private Type extendedType; public ExtendsType(Type extendedType) { + super("? extends " + extendedType.getTypeParams(), extendedType.getTypeParams()); this.extendedType = extendedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index 48cf2e6f..dd40ab23 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -4,10 +4,10 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class PlaceholderType extends Type{ +public final class PlaceholderType extends Type{ public PlaceholderType(String name) { - typeName = name; + super(name); } @Override diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 199c6518..29228977 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -4,10 +4,9 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class SimpleType extends Type { +public final class SimpleType extends Type { public SimpleType(String name, Type... typeParams) { - this.typeName = name; - this.typeParams = new TypeParams(typeParams); + super(name, new TypeParams(typeParams)); } @Override diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index 5a734621..2148e0df 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -4,11 +4,12 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -public class SuperType extends Type { +public final class SuperType extends Type { private Type superedType; public SuperType(Type superedType) { + super("? extends " + superedType.getName(), superedType.getTypeParams()); this.superedType = superedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index dc5a9d91..3da9dbcd 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -1,17 +1,22 @@ package de.dhbwstuttgart.typinference.unify.model; -import java.util.Arrays; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; public abstract class Type { - protected String typeName = ""; - protected TypeParams typeParams; + protected final String typeName; + protected final TypeParams typeParams; - public Type() { - typeParams = new TypeParams(); + protected Type(String name, Type... typeParams) { + typeName = name; + this.typeParams = new TypeParams(typeParams); + } + + protected Type(String name, TypeParams p) { + typeName = name; + typeParams = p; } public String getName() { diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index c89b207d..c6e3ee00 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -3,8 +3,10 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Arrays; import java.util.Iterator; -public class TypeParams implements Iterable{ - private Type[] typeParams; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; + +public final class TypeParams implements Iterable{ + private final Type[] typeParams; public TypeParams(Type... types) { typeParams = types; @@ -26,8 +28,20 @@ public class TypeParams implements Iterable{ return typeParams.length == 0; } - public Type[] asArray() { - return typeParams; + public void apply(Unifier u) { + for(int i = 0; i < typeParams.length; i++) + typeParams[i] = u.apply(typeParams[i]); + } + + public boolean contains(Type t) { + for(Type t1 : typeParams) + if(t1.equals(t1)) + return true; + return false; + } + + public Type get(int i) { + return typeParams[i]; } @Override From fb82d8c3ebe60dba44a8b0dcfd2546cded7c7672 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 13 Nov 2015 22:45:30 +0100 Subject: [PATCH 31/47] changed typeplaceholders --- test/unify/FiniteClosureBuilder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index f35ce0e4..815d637d 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -30,13 +30,13 @@ public class FiniteClosureBuilder { Type collection = tf.getSimpleType("Collection"); Type set = tf.getSimpleType("Set", "T"); - Type sortedSet = tf.getSimpleType("Set", "K"); + Type sortedSet = tf.getSimpleType("Set", "T"); Type TreeSet = tf.getSimpleType("TreeSet", "T"); - Type hashSet = tf.getSimpleType("HashSet", "Z"); + Type hashSet = tf.getSimpleType("HashSet", "T"); Type linkedHashSet = tf.getSimpleType("LinkedHashSet", "T"); - Type queue = tf.getSimpleType("Queue", "U"); - Type deque = tf.getSimpleType("Deque", "U"); - Type linkedList = tf.getSimpleType("LinkedList", "U"); + Type queue = tf.getSimpleType("Queue", "T"); + Type deque = tf.getSimpleType("Deque", "T"); + Type linkedList = tf.getSimpleType("LinkedList", "T"); Type list = tf.getSimpleType("List", "T"); Type vector = tf.getSimpleType("Vector", "T"); Type stack = tf.getSimpleType("Stack", "T"); From fd5902f6ddb978bbc33201c4beec0df9b2b12926 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 13 Nov 2015 22:49:26 +0100 Subject: [PATCH 32/47] stricter equality condition for typeParams --- .../typinference/unify/model/ExtendsType.java | 2 +- .../typinference/unify/model/TypeParams.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index d648c249..e9dbc7c0 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -8,7 +8,7 @@ public final class ExtendsType extends Type { private Type extendedType; public ExtendsType(Type extendedType) { - super("? extends " + extendedType.getTypeParams(), extendedType.getTypeParams()); + super("? extends " + extendedType.getName(), extendedType.getTypeParams()); this.extendedType = extendedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index c6e3ee00..fe8dff83 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -61,8 +61,14 @@ public final class TypeParams implements Iterable{ TypeParams other = (TypeParams) obj; - // TODO - return other.size() == this.size(); + if(other.size() != this.size()) + return false; + + for(int i = 0; i < this.size(); i++) + if(!(this.get(i).equals(other.get(i)))) + return false; + + return true; } } From 8a40acb73e626f92b26882d6db78d2dae9d404e6 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 13 Nov 2015 23:17:14 +0100 Subject: [PATCH 33/47] application of unifiers --- .../typinference/unify/model/ExtendsType.java | 6 ++++++ .../typinference/unify/model/PlaceholderType.java | 6 ++++++ .../typinference/unify/model/SimpleType.java | 10 ++++++++++ .../typinference/unify/model/SuperType.java | 6 ++++++ .../dhbwstuttgart/typinference/unify/model/Type.java | 3 +++ .../typinference/unify/model/TypeParams.java | 6 ++++-- 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index e9dbc7c0..763f3107 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class ExtendsType extends Type { private Type extendedType; @@ -49,4 +50,9 @@ public final class ExtendsType extends Type { ExtendsType other = (ExtendsType) obj; return other.getExtendedType().equals(extendedType); } + + @Override + public Type applyToTypeParams(Unifier unif) { + return new ExtendsType(extendedType.applyToTypeParams(unif)); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index dd40ab23..53d5eab3 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class PlaceholderType extends Type{ @@ -32,4 +33,9 @@ public final class PlaceholderType extends Type{ return ((PlaceholderType) obj).getName().equals(typeName); } + + @Override + public Type applyToTypeParams(Unifier unif) { + return this; + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 29228977..370f472b 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -3,11 +3,16 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class SimpleType extends Type { public SimpleType(String name, Type... typeParams) { super(name, new TypeParams(typeParams)); } + + private SimpleType(String name, TypeParams params) { + super(name, params); + } @Override public Set smArg(IFiniteClosure fc) { @@ -36,4 +41,9 @@ public final class SimpleType extends Type { return other.getTypeParams().equals(typeParams); } + + @Override + public Type applyToTypeParams(Unifier unif) { + return new SimpleType(typeName, typeParams.apply(unif)); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index 2148e0df..6e55a9f3 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class SuperType extends Type { @@ -50,4 +51,9 @@ public final class SuperType extends Type { SuperType other = (SuperType) obj; return other.getSuperedType().equals(superedType); } + + @Override + public Type applyToTypeParams(Unifier unif) { + return new SuperType(superedType.applyToTypeParams(unif)); + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index 3da9dbcd..b929d3c1 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; public abstract class Type { @@ -31,6 +32,8 @@ public abstract class Type { public abstract Set grArg(IFiniteClosure fc); + public abstract Type applyToTypeParams(Unifier unif); + @Override public String toString() { String params = ""; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index fe8dff83..fb8fcb53 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -28,9 +28,11 @@ public final class TypeParams implements Iterable{ return typeParams.length == 0; } - public void apply(Unifier u) { + public TypeParams apply(Unifier unif) { + Type[] newParams = new Type[typeParams.length]; for(int i = 0; i < typeParams.length; i++) - typeParams[i] = u.apply(typeParams[i]); + newParams[i] = typeParams[i].applyToTypeParams(unif); + return new TypeParams(newParams); } public boolean contains(Type t) { From 82c0736feea0c464f85e7113e1b76af86d2e3082 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Fri, 13 Nov 2015 23:24:22 +0100 Subject: [PATCH 34/47] adapt Rule --- notizen/stf/Notes | 7 +- .../unify/interfaces/IRuleSet.java | 9 +- .../unify/interfaces/IUnifier.java | 9 -- .../typeinference/unifynew/RuleSet.java | 110 ++++++++++++------ .../typeinference/unifynew/Unify.java | 11 -- 5 files changed, 84 insertions(+), 62 deletions(-) delete mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java diff --git a/notizen/stf/Notes b/notizen/stf/Notes index 14e847e5..35b14871 100644 --- a/notizen/stf/Notes +++ b/notizen/stf/Notes @@ -34,6 +34,10 @@ Gilt reduce f +++++++++++++++++++++++++++++++++++++++++++++++ +HashCode implementierungen testen (type paramerte mit einbeziehen, hashcodes cachen -> da immutable) + + ++++++++++++++++++++++++++++++++++++++++++++++++ - Typen sind anhand ihres identifiers durchgängig identifizierbar - ReduceEq nur auf SimpleTypes oder auf alles anwenden? (Momentan alles) @@ -42,4 +46,5 @@ Gilt reduce f EED UP - Anwendungsreihenfolge der Regeln (wahrscheinlichste zuerst, evtl ist nach regel 1 regel 2 nie möglich etc...) - Erase vor Reduce - - Rechenarm vor rechenintensiv \ No newline at end of file + - Rechenarm vor rechenintensiv + diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index ad0655ef..a3f279f6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; import java.util.Optional; import java.util.Set; +import de.dhbwstuttgart.typeinference.unifynew.Unifier; import de.dhbwstuttgart.typinference.unify.model.MPair; public interface IRuleSet { @@ -22,9 +23,9 @@ public interface IRuleSet { public Optional swap(MPair pair); - public MPair adapt(MPair pair); - public MPair adaptExt(MPair pair); - public MPair adaptSup(MPair pair); + public Optional adapt(MPair pair); + public Optional adaptExt(MPair pair); + public Optional adaptSup(MPair pair); - public Optional subst(MPair pair); + public Optional subst(MPair pair); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java deleted file mode 100644 index da18fa8f..00000000 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnifier.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.dhbwstuttgart.typeinference.unify.interfaces; - -import java.util.function.Function; - -import de.dhbwstuttgart.typinference.unify.model.MPair; - -public interface IUnifier extends Function{ - -} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 43e33640..203bbee0 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -1,13 +1,14 @@ package de.dhbwstuttgart.typeinference.unifynew; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; import junit.framework.Assert; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; -import de.dhbwstuttgart.typeinference.unify.interfaces.IUnifier; import de.dhbwstuttgart.typinference.unify.model.ExtendsType; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; @@ -15,6 +16,7 @@ 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; +import de.dhbwstuttgart.typinference.unify.model.TypeParams; public class RuleSet implements IRuleSet{ @@ -95,12 +97,12 @@ public class RuleSet implements IRuleSet{ if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); + TypeParams rhsTypeParams = rhsType.getTypeParams(); + TypeParams lhsTypeParams = lhsType.getTypeParams(); Set result = new HashSet<>(); - for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) + result.add(new MPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -128,12 +130,12 @@ public class RuleSet implements IRuleSet{ if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); + TypeParams rhsTypeParams = rhsType.getTypeParams(); + TypeParams lhsTypeParams = lhsType.getTypeParams(); Set result = new HashSet<>(); - for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) + result.add(new MPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -160,11 +162,11 @@ public class RuleSet implements IRuleSet{ // TODO Permutation? Set result = new HashSet<>(); - Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); - Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); + TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams rhsTypeParams = rhsType.getTypeParams(); - for(int i = 0; i < lhsTypeParams.length; i++) - result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.EQUALSDOT)); + for(int i = 0; i < lhsTypeParams.size(); i++) + result.add(new MPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT)); return Optional.of(result); } @@ -193,12 +195,12 @@ public class RuleSet implements IRuleSet{ if(pi.length == 0) return Optional.empty(); - Type[] rhsTypeParams = rhsType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsType.getTypeParams().asArray(); + TypeParams rhsTypeParams = rhsType.getTypeParams(); + TypeParams lhsTypeParams = lhsType.getTypeParams(); Set result = new HashSet<>(); - for(int rhsIdx = 0; rhsIdx < rhsTypeParams.length; rhsIdx++) - result.add(new MPair(lhsTypeParams[pi[rhsIdx]], rhsTypeParams[rhsIdx], PairOperator.SMALLERDOTWC)); + for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) + result.add(new MPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC)); return Optional.of(result); } @@ -244,10 +246,10 @@ public class RuleSet implements IRuleSet{ Set result = new HashSet<>(); - Type[] rhsTypeParams = rhsSType.getTypeParams().asArray(); - Type[] lhsTypeParams = lhsSType.getTypeParams().asArray(); - for(int i = 0; i < rhsTypeParams.length; i++) - result.add(new MPair(lhsTypeParams[i], rhsTypeParams[i], PairOperator.EQUALSDOT)); + TypeParams rhsTypeParams = rhsSType.getTypeParams(); + TypeParams lhsTypeParams = lhsSType.getTypeParams(); + for(int i = 0; i < rhsTypeParams.size(); i++) + result.add(new MPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT)); return Optional.of(result); } @@ -302,19 +304,53 @@ public class RuleSet implements IRuleSet{ } @Override - public MPair adapt(MPair pair) { + public Optional adapt(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(!(lhsType instanceof SimpleType)) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(!(rhsType instanceof SimpleType)) + return Optional.empty(); + + if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + return Optional.empty(); + + Type lhsFromFc = finiteClosure.getType(lhsType.getName()); + + if(lhsFromFc == null) + return Optional.empty(); + + Set greater = finiteClosure.greater(lhsFromFc); + + Optional opt = greater.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + + if(!opt.isPresent()) + return Optional.empty(); + + Type newLhs = opt.get(); + + TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + + Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); + for(int i = 0; i < lhsTypeParams.size(); i++) + unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + + return Optional.of(new MPair(newLhs.applyToTypeParams(unif), rhsType, PairOperator.SMALLERDOT)); + } + + @Override + public Optional adaptExt(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) { + public Optional adaptSup(MPair pair) { // TODO Auto-generated method stub return null; } @@ -362,17 +398,17 @@ public class RuleSet implements IRuleSet{ Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); Assert.assertTrue(dFromFc.getTypeParams().size() > 0); - Type[] cArgs = cFromFc.getTypeParams().asArray(); - Type[] dArgs = dFromFc.getTypeParams().asArray(); + TypeParams cArgs = cFromFc.getTypeParams(); + TypeParams dArgs = dFromFc.getTypeParams(); - int[] permutation = new int[dArgs.length]; + int[] permutation = new int[dArgs.size()]; boolean succ = true; - for (int dArgIdx = 0; dArgIdx < dArgs.length && succ; dArgIdx++) { - Type dArg = dArgs[dArgIdx]; + for (int dArgIdx = 0; dArgIdx < dArgs.size() && succ; dArgIdx++) { + Type dArg = dArgs.get(dArgIdx); succ = false; - for (int pi = 0; pi < cArgs.length; pi++) - if (cArgs[pi].getName().equals(dArg.getName())) { + for (int pi = 0; pi < cArgs.size(); pi++) + if (cArgs.get(pi).getName().equals(dArg.getName())) { permutation[dArgIdx] = pi; succ = true; break; @@ -384,7 +420,7 @@ public class RuleSet implements IRuleSet{ } @Override - public Optional subst(MPair pair) { + public Optional subst(MPair pair) { // TODO Auto-generated method stub return null; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 1313b6fa..4f88ccd2 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -1,6 +1,5 @@ package de.dhbwstuttgart.typeinference.unifynew; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; @@ -13,11 +12,8 @@ import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; -import de.dhbwstuttgart.typeinference.unify.interfaces.IUnifier; import de.dhbwstuttgart.typinference.unify.model.MPair; import de.dhbwstuttgart.typinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typinference.unify.model.SimpleType; -import de.dhbwstuttgart.typinference.unify.model.Type; /** * Implementierung des Unifikationsalgorithmus. @@ -145,11 +141,4 @@ public class Unify { collection.add(pair2); } - - private void test() { - Type t = new PlaceholderType("T"); - Type subst = new SimpleType("Subst"); - - IUnifier u = x -> x.substitute(t, subst); - } } From 3739747eca38ecf48d3db4c72a3db3b9eaf2cc21 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 14 Nov 2015 18:51:46 +0100 Subject: [PATCH 35/47] adapt --- .../typeinference/unifynew/RuleSet.java | 2 +- .../typinference/unify/model/ExtendsType.java | 4 ++-- .../unify/model/PlaceholderType.java | 5 ++++- .../typinference/unify/model/SimpleType.java | 5 ++++- .../typinference/unify/model/SuperType.java | 4 ++-- .../typinference/unify/model/Type.java | 2 +- .../typinference/unify/model/TypeParams.java | 2 +- test/unify/RuleSetTest.java | 21 +++++++++++++++++++ 8 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 203bbee0..6b450672 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -340,7 +340,7 @@ public class RuleSet implements IRuleSet{ for(int i = 0; i < lhsTypeParams.size(); i++) unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); - return Optional.of(new MPair(newLhs.applyToTypeParams(unif), rhsType, PairOperator.SMALLERDOT)); + return Optional.of(new MPair(newLhs.apply(unif), rhsType, PairOperator.SMALLERDOT)); } @Override diff --git a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java index 763f3107..2b0facaf 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/ExtendsType.java @@ -52,7 +52,7 @@ public final class ExtendsType extends Type { } @Override - public Type applyToTypeParams(Unifier unif) { - return new ExtendsType(extendedType.applyToTypeParams(unif)); + public Type apply(Unifier unif) { + return new ExtendsType(extendedType.apply(unif)); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java index 53d5eab3..7b7503ee 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/PlaceholderType.java @@ -35,7 +35,10 @@ public final class PlaceholderType extends Type{ } @Override - public Type applyToTypeParams(Unifier unif) { + public Type apply(Unifier unif) { + if(this.equals(unif.getSource())) + return unif.getTarget(); + return this; } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java index 370f472b..8e9e8a3f 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SimpleType.java @@ -43,7 +43,10 @@ public final class SimpleType extends Type { } @Override - public Type applyToTypeParams(Unifier unif) { + public Type apply(Unifier unif) { + if(this.equals(unif.getSource())) + return unif.getTarget(); + return new SimpleType(typeName, typeParams.apply(unif)); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index 6e55a9f3..6a243e34 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -53,7 +53,7 @@ public final class SuperType extends Type { } @Override - public Type applyToTypeParams(Unifier unif) { - return new SuperType(superedType.applyToTypeParams(unif)); + public Type apply(Unifier unif) { + return new SuperType(superedType.apply(unif)); } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/Type.java b/src/de/dhbwstuttgart/typinference/unify/model/Type.java index b929d3c1..a9e94862 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/Type.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/Type.java @@ -32,7 +32,7 @@ public abstract class Type { public abstract Set grArg(IFiniteClosure fc); - public abstract Type applyToTypeParams(Unifier unif); + public abstract Type apply(Unifier unif); @Override public String toString() { diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index fb8fcb53..0d48e814 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -31,7 +31,7 @@ public final class TypeParams implements Iterable{ public TypeParams apply(Unifier unif) { Type[] newParams = new Type[typeParams.length]; for(int i = 0; i < typeParams.length; i++) - newParams[i] = typeParams[i].applyToTypeParams(unif); + newParams[i] = typeParams[i].apply(unif); return new TypeParams(newParams); } diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index f9cdce8c..729e2ea5 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -518,6 +518,27 @@ public class RuleSetTest { @Test public void testAdapt() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + + SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); + SimpleType t2 = tf.getSimpleType("Type2", "T"); + SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + + fcb.add(t1, t2); + fcb.add(t2, t3); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + + SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); + SimpleType c2 = tf.getSimpleType("Type2", "Object"); + SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + + MPair pair1 = new MPair(c1, c2, PairOperator.SMALLERDOT); + MPair pair2 = new MPair(c1, c3, PairOperator.SMALLERDOT); + System.out.println("------ Adapt ------"); + System.out.println(rules.adapt(pair1)); + System.out.println(rules.adapt(pair2)); // Not working yet } From e447e1cd46f5332d6c001783290a27a38f61ef6b Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 14:39:08 +0100 Subject: [PATCH 36/47] adapt + tests --- src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java | 5 ++++- test/unify/RuleSetTest.java | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 6b450672..be456354 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -319,6 +319,9 @@ public class RuleSet implements IRuleSet{ if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) return Optional.empty(); + if(lhsType.getName().equals(rhsType.getName())) + return Optional.empty(); + Type lhsFromFc = finiteClosure.getType(lhsType.getName()); if(lhsFromFc == null) @@ -337,7 +340,7 @@ public class RuleSet implements IRuleSet{ TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); - for(int i = 0; i < lhsTypeParams.size(); i++) + for(int i = 1; i < lhsTypeParams.size(); i++) unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); return Optional.of(new MPair(newLhs.apply(unif), rhsType, PairOperator.SMALLERDOT)); diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 729e2ea5..fd8dcba2 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -538,8 +538,15 @@ public class RuleSetTest { MPair pair2 = new MPair(c1, c3, PairOperator.SMALLERDOT); System.out.println("------ Adapt ------"); System.out.println(rules.adapt(pair1)); - System.out.println(rules.adapt(pair2)); // Not working yet + System.out.println(rules.adapt(pair2)); + MPair noAdapt1 = new MPair(c2, c1, PairOperator.SMALLERDOT); + MPair noAdapt2 = new MPair(c1, c1, PairOperator.SMALLERDOT); + MPair noAdapt3 = new MPair(c1, c2, PairOperator.SMALLERDOTWC); + + Assert.assertFalse(rules.adapt(noAdapt1).isPresent()); + Assert.assertFalse(rules.adapt(noAdapt2).isPresent()); + Assert.assertFalse(rules.adapt(noAdapt3).isPresent()); } @Test From 480c7dca61e75b5525193f4620cdc8670a42cfa5 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 15:06:34 +0100 Subject: [PATCH 37/47] adaptExt + tests --- .../typeinference/unifynew/RuleSet.java | 42 +++++++++++- test/unify/RuleSetTest.java | 67 ++++++++++++++++++- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index be456354..5eb2c90b 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -348,8 +348,46 @@ public class RuleSet implements IRuleSet{ @Override public Optional adaptExt(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(!(rhsType instanceof ExtendsType)) + return Optional.empty(); + + if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + return Optional.empty(); + + Type lhsFromFc; + if(lhsType instanceof SimpleType) + lhsFromFc = finiteClosure.getType(lhsType.getName()); + else + lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType().getName())); + + if(lhsFromFc == null) + return Optional.empty(); + + Set grArg = finiteClosure.grArg(lhsFromFc); + + Optional opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + + if(!opt.isPresent()) + return Optional.empty(); + + Type newLhs = ((ExtendsType) opt.get()).getExtendedType(); + + TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + + Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); + for(int i = 1; i < lhsTypeParams.size(); i++) + unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + + return Optional.of(new MPair(newLhs.apply(unif), rhsType, PairOperator.SMALLERDOTWC)); } @Override diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index fd8dcba2..818aa47a 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -530,15 +530,26 @@ public class RuleSetTest { IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + /* + * Positive Tests + */ + SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); SimpleType c2 = tf.getSimpleType("Type2", "Object"); SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); MPair pair1 = new MPair(c1, c2, PairOperator.SMALLERDOT); - MPair pair2 = new MPair(c1, c3, PairOperator.SMALLERDOT); + MPair pair2 = new MPair(c2, c3, PairOperator.SMALLERDOT); + MPair pair3 = new MPair(c1, c3, PairOperator.SMALLERDOT); + System.out.println("------ Adapt ------"); System.out.println(rules.adapt(pair1)); System.out.println(rules.adapt(pair2)); + System.out.println(rules.adapt(pair3)); + + /* + * Negative Tests + */ MPair noAdapt1 = new MPair(c2, c1, PairOperator.SMALLERDOT); MPair noAdapt2 = new MPair(c1, c1, PairOperator.SMALLERDOT); @@ -551,7 +562,61 @@ public class RuleSetTest { @Test public void testAdaptExt() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); + SimpleType t2 = tf.getSimpleType("Type2", "T"); + SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + + fcb.add(t1, t2); + fcb.add(t2, t3); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + + /* + * Positive Tests + */ + + SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); + SimpleType c2 = tf.getSimpleType("Type2", "Object"); + SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + ExtendsType extc1 = new ExtendsType(c1); + ExtendsType extc2 = new ExtendsType(c2); + ExtendsType extc3 = new ExtendsType(c3); + + MPair pair1 = new MPair(c1, extc2, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(c2, extc3, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(c1, extc3, PairOperator.SMALLERDOTWC); + MPair pair4 = new MPair(extc1, extc2, PairOperator.SMALLERDOTWC); + MPair pair5 = new MPair(extc2, extc3, PairOperator.SMALLERDOTWC); + MPair pair6 = new MPair(extc1, extc3, PairOperator.SMALLERDOTWC); + MPair pair7 = new MPair(extc1, extc1, PairOperator.SMALLERDOTWC); + + System.out.println("------ AdaptExt ------"); + System.out.println(rules.adaptExt(pair1)); + System.out.println(rules.adaptExt(pair2)); + System.out.println(rules.adaptExt(pair3)); + System.out.println(rules.adaptExt(pair4)); + System.out.println(rules.adaptExt(pair5)); + System.out.println(rules.adaptExt(pair6)); + System.out.println(rules.adaptExt(pair7)); + + /* + * Negative Tests + */ + + MPair noAdapt1 = new MPair(extc2, extc1, PairOperator.SMALLERDOTWC); + MPair noAdapt2 = new MPair(extc1, c2, PairOperator.SMALLERDOTWC); + MPair noAdapt3 = new MPair(tf.getSuperType(c1), extc2, PairOperator.SMALLERDOTWC); + MPair noAdapt4 = new MPair(extc3, extc1, PairOperator.SMALLERDOTWC); + MPair noAdapt5 = new MPair(c1, extc2, PairOperator.SMALLERDOT); + + Assert.assertFalse(rules.adaptExt(noAdapt1).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt2).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt3).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt4).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt5).isPresent()); } @Test From ae37dd625596bc2ffb2d2b285a3f5cd9188fb327 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 18:08:46 +0100 Subject: [PATCH 38/47] fc identifier from string to type --- .../unify/interfaces/IFiniteClosure.java | 2 +- .../typeinference/unifynew/RuleSet.java | 59 +++++++++++-- .../unify/model/FiniteClosure.java | 83 ++++++++++++------- .../typinference/unify/model/SuperType.java | 2 +- .../typinference/unify/model/TypeParams.java | 9 +- test/unify/RuleSetTest.java | 59 ++++++++++++- 6 files changed, 171 insertions(+), 43 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index fb620046..796a2706 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -48,5 +48,5 @@ public interface IFiniteClosure { public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); - public Type getType(String typeName); + public Type getType(Type type); } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 5eb2c90b..ad9afc7d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -322,7 +322,7 @@ public class RuleSet implements IRuleSet{ if(lhsType.getName().equals(rhsType.getName())) return Optional.empty(); - Type lhsFromFc = finiteClosure.getType(lhsType.getName()); + Type lhsFromFc = finiteClosure.getType(lhsType); if(lhsFromFc == null) return Optional.empty(); @@ -364,9 +364,9 @@ public class RuleSet implements IRuleSet{ Type lhsFromFc; if(lhsType instanceof SimpleType) - lhsFromFc = finiteClosure.getType(lhsType.getName()); + lhsFromFc = finiteClosure.getType(lhsType); else - lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType().getName())); + lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType())); if(lhsFromFc == null) return Optional.empty(); @@ -392,8 +392,51 @@ public class RuleSet implements IRuleSet{ @Override public Optional adaptSup(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType)) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if(!(rhsType instanceof SuperType)) + return Optional.empty(); + + if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + return Optional.empty(); + + Type lhsFromFc; + Type newRhs; + if(lhsType instanceof SimpleType) { + lhsFromFc = finiteClosure.getType(lhsType); + newRhs = new ExtendsType(lhsType); + } + else { + lhsFromFc = new ExtendsType(finiteClosure.getType(((SuperType) lhsType).getSuperedType())); + newRhs = new ExtendsType(((SuperType) lhsType).getSuperedType()); + } + + if(lhsFromFc == null) + return Optional.empty(); + + Set grArg = finiteClosure.grArg(lhsFromFc); + + Optional opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + + if(!opt.isPresent()) + return Optional.empty(); + + Type newLhs = opt.get(); + + TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + + Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); + for(int i = 1; i < lhsTypeParams.size(); i++) + unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + + return Optional.of(new MPair(newLhs.apply(unif), newRhs, PairOperator.SMALLERDOTWC)); } /** @@ -405,11 +448,11 @@ public class RuleSet implements IRuleSet{ private int[] pi(Type C, Type D) { Type cFromFc = null; if(C instanceof SimpleType) - cFromFc = finiteClosure.getType(C.getName()); + cFromFc = finiteClosure.getType(C); else if(C instanceof ExtendsType) - cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType().getName())); + cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType())); else if(C instanceof SuperType) - cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType().getName())); + cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType())); if(cFromFc == null) return new int[0]; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 0b1ee461..b8910e17 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -9,11 +9,12 @@ import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; public class FiniteClosure implements IFiniteClosure { - private HashMap> inheritanceGraph; + private HashMap> inheritanceGraph; + private HashMap>> strInheritanceGraph; public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { @@ -21,13 +22,13 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType().getName())) - inheritanceGraph.put(pair.getLhsType().getName(), new Node(pair.getLhsType())); - if(!inheritanceGraph.containsKey(pair.getRhsType().getName())) - inheritanceGraph.put(pair.getRhsType().getName(), new Node(pair.getRhsType())); + if(!inheritanceGraph.containsKey(pair.getLhsType())) + inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); + if(!inheritanceGraph.containsKey(pair.getRhsType())) + inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); - Node childNode = inheritanceGraph.get(pair.getLhsType().getName()); - Node parentNode = inheritanceGraph.get(pair.getRhsType().getName()); + Node childNode = inheritanceGraph.get(pair.getLhsType()); + Node parentNode = inheritanceGraph.get(pair.getRhsType()); // Add edge parentNode.AddDescendant(childNode); @@ -36,6 +37,16 @@ public class FiniteClosure implements IFiniteClosure { parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode)); childNode.getDescendants().stream().forEach(x -> x.AddPredecessor(parentNode)); } + + // Build the alternative representation with strings as keys + + strInheritanceGraph = new HashMap<>(); + for(Type key : inheritanceGraph.keySet()) { + if(!strInheritanceGraph.containsKey(key.getName())) + strInheritanceGraph.put(key.getName(), new HashSet<>()); + + strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key)); + } } /** @@ -44,21 +55,15 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); - Set result = inheritanceGraph.get(type.getName()).getContentOfDescendants(); + Set result = inheritanceGraph.get(type).getContentOfDescendants(); result.add(type); + return result; } - @Override - public Type getType(String typeName) { - if(!inheritanceGraph.containsKey(typeName)) - return null; - - return inheritanceGraph.get(typeName).getContent(); - } /** * Returns all types of the finite closure that are supertypes of the argument. @@ -66,10 +71,10 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set greater(Type type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet<>(); - Set result = inheritanceGraph.get(type.getName()).getContentOfPredecessors(); + Set result = inheritanceGraph.get(type).getContentOfPredecessors(); result.add(type); return result; } @@ -82,12 +87,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getName()).getContent(); + Type t = inheritanceGraph.get(type).getContent(); result.add(t); smaller(type).forEach(x -> result.add(new SuperType(x))); @@ -98,12 +103,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + if(!inheritanceGraph.containsKey(type.getExtendedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); greater(t).forEach(x -> result.add(new ExtendsType(x))); @@ -112,12 +117,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + if(!inheritanceGraph.containsKey(type.getSuperedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); smaller(t).forEach(x -> result.add(new SuperType(x))); @@ -136,12 +141,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type.getName())) + if(!inheritanceGraph.containsKey(type)) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getName()).getContent(); + Type t = inheritanceGraph.get(type).getContent(); result.add(t); smaller(type).forEach(x -> result.add(new ExtendsType(x))); @@ -150,12 +155,12 @@ public class FiniteClosure implements IFiniteClosure { } public Set smArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType().getName())) + if(!inheritanceGraph.containsKey(type.getExtendedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); result.add(t); smaller(t).forEach(x -> { @@ -169,12 +174,12 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType().getName())) + if(!inheritanceGraph.containsKey(type.getSuperedType())) return new HashSet(); Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent(); + Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); result.add(t); greater(t).forEach(x -> { @@ -189,4 +194,20 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { return new HashSet<>(); } + + @Override + public Type getType(Type type) { + if(!strInheritanceGraph.containsKey(type.getName())) + return null; + + HashSet> candidates = strInheritanceGraph.get(type.getName()); + + for(Node node : candidates) { + Type candidate = node.getContent(); + if(candidate.getTypeParams().arePlaceholders()) + return candidate; + } + + return null; + } } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java index 6a243e34..15c432d2 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/SuperType.java @@ -10,7 +10,7 @@ public final class SuperType extends Type { private Type superedType; public SuperType(Type superedType) { - super("? extends " + superedType.getName(), superedType.getTypeParams()); + super("? super " + superedType.getName(), superedType.getTypeParams()); this.superedType = superedType; } diff --git a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java index 0d48e814..d723395d 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/TypeParams.java @@ -7,11 +7,18 @@ import de.dhbwstuttgart.typeinference.unifynew.Unifier; public final class TypeParams implements Iterable{ private final Type[] typeParams; - + public TypeParams(Type... types) { typeParams = types; } + public boolean arePlaceholders() { + for(Type t : typeParams) + if(!(t instanceof PlaceholderType)) + return false; + return true; + } + @Override public String toString() { String res = ""; diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index 818aa47a..da8b8544 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -396,7 +396,7 @@ public class RuleSetTest { * Positive Tests */ MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); - MPair erase2 = new MPair(tf.getSimpleType("HashSet", "W"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); + MPair erase2 = new MPair(tf.getSimpleType("HashSet", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT); MPair erase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT); Assert.assertTrue(rules.erase1(erase1)); @@ -568,9 +568,12 @@ public class RuleSetTest { SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); SimpleType t2 = tf.getSimpleType("Type2", "T"); SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + SimpleType t32 = tf.getSimpleType("Type3", "T", "U"); + SimpleType t4 = tf.getSimpleType("Object"); fcb.add(t1, t2); fcb.add(t2, t3); + fcb.add(t32, t4); IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); @@ -621,6 +624,60 @@ public class RuleSetTest { @Test public void testAdaptSup() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); + SimpleType t2 = tf.getSimpleType("Type2", "T"); + SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + + fcb.add(t1, t2); + fcb.add(t2, t3); + + IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); + + /* + * Positive Tests + */ + + SimpleType c1 = tf.getSimpleType("Type1", "String", "Double"); + SimpleType c2 = tf.getSimpleType("Type2", "Object"); + SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number"); + SuperType supc1 = new SuperType(c1); + SuperType supc2 = new SuperType(c2); + SuperType supc3 = new SuperType(c3); + + MPair pair1 = new MPair(c2, supc1, PairOperator.SMALLERDOTWC); + MPair pair2 = new MPair(c3, supc2, PairOperator.SMALLERDOTWC); + MPair pair3 = new MPair(c3, supc1, PairOperator.SMALLERDOTWC); + MPair pair4 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC); + MPair pair5 = new MPair(supc3, supc2, PairOperator.SMALLERDOTWC); + MPair pair6 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC); + MPair pair7 = new MPair(supc1, supc1, PairOperator.SMALLERDOTWC); + + System.out.println("------ AdaptSup ------"); + System.out.println(rules.adaptSup(pair1)); + System.out.println(rules.adaptSup(pair2)); + System.out.println(rules.adaptSup(pair3)); + System.out.println(rules.adaptSup(pair4)); + System.out.println(rules.adaptSup(pair5)); + System.out.println(rules.adaptSup(pair6)); + System.out.println(rules.adaptSup(pair7)); + + /* + * Negative Tests + */ + + MPair noAdapt1 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC); + MPair noAdapt2 = new MPair(supc1, c2, PairOperator.SMALLERDOTWC); + MPair noAdapt3 = new MPair(tf.getExtendsType(c1), supc2, PairOperator.SMALLERDOTWC); + MPair noAdapt4 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC); + MPair noAdapt5 = new MPair(c1, supc2, PairOperator.SMALLERDOT); + + Assert.assertFalse(rules.adaptExt(noAdapt1).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt2).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt3).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt4).isPresent()); + Assert.assertFalse(rules.adaptExt(noAdapt5).isPresent()); } } From c45c4260117d8f762c841230049f519961e8145f Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 18:09:21 +0100 Subject: [PATCH 39/47] unifier --- .../typeinference/unifynew/Unifier.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java new file mode 100644 index 00000000..ecd56cf1 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java @@ -0,0 +1,29 @@ +package de.dhbwstuttgart.typeinference.unifynew; + +import java.util.function.Function; + +import de.dhbwstuttgart.typinference.unify.model.Type; +import de.dhbwstuttgart.typinference.unify.model.TypeParams; + +public class Unifier implements Function { + private Type source; + private Type target; + + public Unifier(Type source, Type target) { + this.source = source; + this.target = target; + } + + @Override + public Type apply(Type t) { + return t.apply(this); + } + + public Type getSource() { + return source; + } + + public Type getTarget() { + return target; + } +} From be6a719433de21336d38c3ac5f033a80135c499c Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 15 Nov 2015 18:39:22 +0100 Subject: [PATCH 40/47] adaptSup + tests --- .../typeinference/unifynew/RuleSet.java | 11 +++++++---- .../typinference/unify/model/FiniteClosure.java | 16 ++++++---------- test/unify/RuleSetTest.java | 3 +++ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index ad9afc7d..f2fd7bc4 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -413,16 +413,18 @@ public class RuleSet implements IRuleSet{ newRhs = new ExtendsType(lhsType); } else { - lhsFromFc = new ExtendsType(finiteClosure.getType(((SuperType) lhsType).getSuperedType())); + lhsFromFc = new SuperType(finiteClosure.getType(((SuperType) lhsType).getSuperedType())); newRhs = new ExtendsType(((SuperType) lhsType).getSuperedType()); } - if(lhsFromFc == null) + Type rhsFromFc = finiteClosure.getType(((SuperType) rhsType).getSuperedType()); + + if(lhsFromFc == null || rhsFromFc == null) return Optional.empty(); - Set grArg = finiteClosure.grArg(lhsFromFc); + Set smArg = finiteClosure.smArg(new SuperType(rhsFromFc)); - Optional opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + Optional opt = smArg.stream().filter(x -> x.getName().equals(lhsType.getName())).findAny(); if(!opt.isPresent()) return Optional.empty(); @@ -437,6 +439,7 @@ public class RuleSet implements IRuleSet{ unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); return Optional.of(new MPair(newLhs.apply(unif), newRhs, PairOperator.SMALLERDOTWC)); + } /** diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index b8910e17..92d04518 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -92,9 +92,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type).getContent(); - - result.add(t); + result.add(type); smaller(type).forEach(x -> result.add(new SuperType(x))); greater(type).forEach(x -> result.add(new ExtendsType(x))); @@ -108,7 +106,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); + Type t = type.getExtendedType(); greater(t).forEach(x -> result.add(new ExtendsType(x))); @@ -122,7 +120,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); + Type t = type.getSuperedType(); smaller(t).forEach(x -> result.add(new SuperType(x))); @@ -146,9 +144,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type).getContent(); - - result.add(t); + result.add(type); smaller(type).forEach(x -> result.add(new ExtendsType(x))); return result; @@ -160,7 +156,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getExtendedType()).getContent(); + Type t = type.getExtendedType(); result.add(t); smaller(t).forEach(x -> { @@ -179,7 +175,7 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); - Type t = inheritanceGraph.get(type.getSuperedType()).getContent(); + Type t = type.getSuperedType(); result.add(t); greater(t).forEach(x -> { diff --git a/test/unify/RuleSetTest.java b/test/unify/RuleSetTest.java index da8b8544..fa08b1e7 100644 --- a/test/unify/RuleSetTest.java +++ b/test/unify/RuleSetTest.java @@ -630,9 +630,12 @@ public class RuleSetTest { SimpleType t1 = tf.getSimpleType("Type1", "T", "U"); SimpleType t2 = tf.getSimpleType("Type2", "T"); SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer")); + SimpleType t32 = tf.getSimpleType("Type3", "T", "U"); + SimpleType t4 = tf.getSimpleType("Object"); fcb.add(t1, t2); fcb.add(t2, t3); + fcb.add(t32, t4); IRuleSet rules = new RuleSet(fcb.getFiniteClosure()); From 3f4f2cd27b51fe2a8c1ce8b814514a401b8cb555 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 22 Nov 2015 15:26:17 +0100 Subject: [PATCH 41/47] adapt revisit --- .../unify/interfaces/IFiniteClosure.java | 3 +- .../typeinference/unifynew/RuleSet.java | 51 +++++++++++-------- .../unify/model/FiniteClosure.java | 15 +++--- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 796a2706..e469f41a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.typeinference.unify.interfaces; +import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typinference.unify.model.ExtendsType; @@ -48,5 +49,5 @@ public interface IFiniteClosure { public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); - public Type getType(Type type); + public Optional getGenericType(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index f2fd7bc4..0d36131b 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -308,42 +308,45 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOT) return Optional.empty(); - Type lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType)) + Type typeD = pair.getLhsType(); + if(!(typeD instanceof SimpleType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); - if(!(rhsType instanceof SimpleType)) + Type typeDs = pair.getRhsType(); + if(!(typeDs instanceof SimpleType)) return Optional.empty(); - if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + if(typeD.getTypeParams().size() == 0 || typeDs.getTypeParams().size() == 0) return Optional.empty(); - if(lhsType.getName().equals(rhsType.getName())) + if(typeD.getName().equals(typeDs.getName())) return Optional.empty(); - Type lhsFromFc = finiteClosure.getType(lhsType); + Optional opt = finiteClosure.getGenericType(typeD.getName()); - if(lhsFromFc == null) + if(!opt.isPresent()) return Optional.empty(); - Set greater = finiteClosure.greater(lhsFromFc); - - Optional opt = greater.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + // The generic Version of Type D (D) + Type typeDgen = opt.get(); + + // Actually greater+ because the types are ensured to have different names + Set greater = finiteClosure.greater(typeDgen); + opt = greater.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) return Optional.empty(); Type newLhs = opt.get(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); - TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + TypeParams typeDParams = typeD.getTypeParams(); + TypeParams typeDgenParams = typeDgen.getTypeParams(); - Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); - for(int i = 1; i < lhsTypeParams.size(); i++) - unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + Unifier unif = new Unifier(typeDgenParams.get(0), typeDParams.get(0)); + for(int i = 1; i < typeDParams.size(); i++) + unif.andThen(new Unifier(typeDgenParams.get(i), typeDParams.get(i))); - return Optional.of(new MPair(newLhs.apply(unif), rhsType, PairOperator.SMALLERDOT)); + return Optional.of(new MPair(newLhs.apply(unif), typeDs, PairOperator.SMALLERDOT)); } @Override @@ -451,11 +454,15 @@ public class RuleSet implements IRuleSet{ private int[] pi(Type C, Type D) { Type cFromFc = null; if(C instanceof SimpleType) - cFromFc = finiteClosure.getType(C); - else if(C instanceof ExtendsType) - cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType())); - else if(C instanceof SuperType) - cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType())); + cFromFc = finiteClosure.getGenericType(C.getName()).orElse(null); + else if(C instanceof ExtendsType) { + Optional opt = finiteClosure.getGenericType(((ExtendsType) C).getExtendedType().getName()); + if(opt.isPresent()) cFromFc = new ExtendsType(opt.get()); + } + else if(C instanceof SuperType) { + Optional opt = finiteClosure.getGenericType(((SuperType) C).getSuperedType().getName()); + if(opt.isPresent()) cFromFc = new SuperType(opt.get()); + } if(cFromFc == null) return new int[0]; diff --git a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java index 92d04518..ae36f465 100644 --- a/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typinference/unify/model/FiniteClosure.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.typinference.unify.model; import java.util.HashMap; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; @@ -64,7 +65,6 @@ public class FiniteClosure implements IFiniteClosure { return result; } - /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. @@ -79,7 +79,6 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override public Set grArg(Type type) { return type.grArg(this); @@ -192,18 +191,18 @@ public class FiniteClosure implements IFiniteClosure { } @Override - public Type getType(Type type) { - if(!strInheritanceGraph.containsKey(type.getName())) - return null; + public Optional getGenericType(String typeName) { + if(!strInheritanceGraph.containsKey(typeName)) + return Optional.empty(); - HashSet> candidates = strInheritanceGraph.get(type.getName()); + HashSet> candidates = strInheritanceGraph.get(typeName); for(Node node : candidates) { Type candidate = node.getContent(); if(candidate.getTypeParams().arePlaceholders()) - return candidate; + return Optional.of(candidate); } - return null; + return Optional.empty(); } } From 9552831d4e1795f1e23555a24d8e51b7aef2e5f5 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 22 Nov 2015 15:54:18 +0100 Subject: [PATCH 42/47] AdaptExt and Sup revisit --- .../typeinference/unifynew/RuleSet.java | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 0d36131b..ddf365be 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -354,43 +354,45 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - Type lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) + Type typeD = pair.getLhsType(); + if(!(typeD instanceof SimpleType) && !(typeD instanceof ExtendsType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); - if(!(rhsType instanceof ExtendsType)) + Type typeExtDs = pair.getRhsType(); + if(!(typeExtDs instanceof ExtendsType)) return Optional.empty(); - if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + if(typeD.getTypeParams().size() == 0 || typeExtDs.getTypeParams().size() == 0) return Optional.empty(); - Type lhsFromFc; - if(lhsType instanceof SimpleType) - lhsFromFc = finiteClosure.getType(lhsType); - else - lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType())); - - if(lhsFromFc == null) + Type typeDgen; + if(typeD instanceof SimpleType) + typeDgen = finiteClosure.getGenericType(typeD.getName()).orElse(null); + else { + Optional opt = finiteClosure.getGenericType(((ExtendsType) typeD).getExtendedType().getName()); + typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null; + } + + if(typeDgen == null) return Optional.empty(); - Set grArg = finiteClosure.grArg(lhsFromFc); + Set grArg = finiteClosure.grArg(typeDgen); - Optional opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny(); + Optional opt = grArg.stream().filter(x -> x.getName().equals(typeExtDs.getName())).findAny(); if(!opt.isPresent()) return Optional.empty(); Type newLhs = ((ExtendsType) opt.get()).getExtendedType(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); - TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); + TypeParams typeDParams = typeD.getTypeParams(); + TypeParams typeDgenParams = typeDgen.getTypeParams(); - Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); - for(int i = 1; i < lhsTypeParams.size(); i++) - unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + Unifier unif = new Unifier(typeDgenParams.get(0), typeDParams.get(0)); + for(int i = 1; i < typeDParams.size(); i++) + unif.andThen(new Unifier(typeDgenParams.get(i), typeDParams.get(i))); - return Optional.of(new MPair(newLhs.apply(unif), rhsType, PairOperator.SMALLERDOTWC)); + return Optional.of(new MPair(newLhs.apply(unif), typeExtDs, PairOperator.SMALLERDOTWC)); } @Override @@ -398,51 +400,51 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - Type lhsType = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType)) + Type typeDs = pair.getLhsType(); + if(!(typeDs instanceof SimpleType) && !(typeDs instanceof SuperType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); - if(!(rhsType instanceof SuperType)) + Type typeSupD = pair.getRhsType(); + if(!(typeSupD instanceof SuperType)) return Optional.empty(); - if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0) + if(typeDs.getTypeParams().size() == 0 || typeSupD.getTypeParams().size() == 0) return Optional.empty(); - Type lhsFromFc; - Type newRhs; - if(lhsType instanceof SimpleType) { - lhsFromFc = finiteClosure.getType(lhsType); - newRhs = new ExtendsType(lhsType); - } - else { - lhsFromFc = new SuperType(finiteClosure.getType(((SuperType) lhsType).getSuperedType())); - newRhs = new ExtendsType(((SuperType) lhsType).getSuperedType()); - } - Type rhsFromFc = finiteClosure.getType(((SuperType) rhsType).getSuperedType()); + Optional opt = finiteClosure.getGenericType(((SuperType) typeDs).getSuperedType().getName()); - if(lhsFromFc == null || rhsFromFc == null) + if(!opt.isPresent()) return Optional.empty(); - Set smArg = finiteClosure.smArg(new SuperType(rhsFromFc)); - - Optional opt = smArg.stream().filter(x -> x.getName().equals(lhsType.getName())).findAny(); + Type typeDsgen = opt.get(); + Type typeSupDsgen = new SuperType(typeDsgen); + + // Use of smArg instead of grArg because + // a in grArg(b) => b in smArg(a) + Set smArg = finiteClosure.smArg(typeSupDsgen); + opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) return Optional.empty(); + // New RHS + Type newRhs = null; + if(typeDs instanceof SimpleType) + newRhs = new ExtendsType(typeDs); + else + newRhs = new ExtendsType(((SuperType) typeDs).getSuperedType()); + + // New LHS Type newLhs = opt.get(); + TypeParams typeDParams = typeSupD.getTypeParams(); + TypeParams typeSupDsgenParams = typeSupDsgen.getTypeParams(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); - TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams(); - - Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0)); - for(int i = 1; i < lhsTypeParams.size(); i++) - unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i))); + Unifier unif = new Unifier(typeSupDsgenParams.get(0), typeDParams.get(0)); + for(int i = 1; i < typeDParams.size(); i++) + unif.andThen(new Unifier(typeSupDsgenParams.get(i), typeDParams.get(i))); return Optional.of(new MPair(newLhs.apply(unif), newRhs, PairOperator.SMALLERDOTWC)); - } /** From 6fd382580a1132119f67dd74a0b60cefc1bbbb48 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 22 Nov 2015 15:58:10 +0100 Subject: [PATCH 43/47] Fixed AdaptSup --- .../dhbwstuttgart/typeinference/unifynew/RuleSet.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index ddf365be..41741d8e 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -412,17 +412,17 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); - Optional opt = finiteClosure.getGenericType(((SuperType) typeDs).getSuperedType().getName()); + Optional opt = finiteClosure.getGenericType(((SuperType) typeSupD).getSuperedType().getName()); if(!opt.isPresent()) return Optional.empty(); - Type typeDsgen = opt.get(); - Type typeSupDsgen = new SuperType(typeDsgen); + Type typeDgen = opt.get(); + Type typeSupDgen = new SuperType(typeDgen); // Use of smArg instead of grArg because // a in grArg(b) => b in smArg(a) - Set smArg = finiteClosure.smArg(typeSupDsgen); + Set smArg = finiteClosure.smArg(typeSupDgen); opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) @@ -438,7 +438,7 @@ public class RuleSet implements IRuleSet{ // New LHS Type newLhs = opt.get(); TypeParams typeDParams = typeSupD.getTypeParams(); - TypeParams typeSupDsgenParams = typeSupDsgen.getTypeParams(); + TypeParams typeSupDsgenParams = typeSupDgen.getTypeParams(); Unifier unif = new Unifier(typeSupDsgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) From e2ba4490b138c0e7dbc0cfc05fbfc8462dccdc4e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sun, 22 Nov 2015 21:57:16 +0100 Subject: [PATCH 44/47] =?UTF-8?q?step=204=20grundger=C3=BCst?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unify/interfaces/IRuleSet.java | 2 +- .../unify/interfaces/ISetOperations.java | 8 ++++ .../unifynew/GuavaSetOperations.java | 17 ++++++++ .../typeinference/unifynew/RuleSet.java | 2 +- .../typeinference/unifynew/Unify.java | 42 +++++++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/de/dhbwstuttgart/typeinference/unify/interfaces/ISetOperations.java create mode 100644 src/de/dhbwstuttgart/typeinference/unifynew/GuavaSetOperations.java diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index a3f279f6..02611fd9 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -27,5 +27,5 @@ public interface IRuleSet { public Optional adaptExt(MPair pair); public Optional adaptSup(MPair pair); - public Optional subst(MPair pair); + public Set subst(Set pair); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/ISetOperations.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/ISetOperations.java new file mode 100644 index 00000000..caed79e4 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/ISetOperations.java @@ -0,0 +1,8 @@ +package de.dhbwstuttgart.typeinference.unify.interfaces; + +import java.util.List; +import java.util.Set; + +public interface ISetOperations { + Set> cartesianProduct(List> sets); +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/GuavaSetOperations.java b/src/de/dhbwstuttgart/typeinference/unifynew/GuavaSetOperations.java new file mode 100644 index 00000000..cc4e907c --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/GuavaSetOperations.java @@ -0,0 +1,17 @@ +package de.dhbwstuttgart.typeinference.unifynew; + +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Sets; + +import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; + +public class GuavaSetOperations implements ISetOperations { + + @Override + public Set> cartesianProduct(List> sets) { + return Sets.cartesianProduct(sets); + } + +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 41741d8e..3dff9384 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -516,7 +516,7 @@ public class RuleSet implements IRuleSet{ } @Override - public Optional subst(MPair pair) { + public Set subst(Set pair) { // TODO Auto-generated method stub return null; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 4f88ccd2..b87cd2b6 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -1,20 +1,26 @@ package de.dhbwstuttgart.typeinference.unifynew; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; +import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; +import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; import de.dhbwstuttgart.typinference.unify.model.PlaceholderType; + /** * Implementierung des Unifikationsalgorithmus. * @author Florian Steurer @@ -25,18 +31,21 @@ public class Unify { /* * Preparations: Create Mapping */ + Set eq0 = null; /* * Step 1: Repeated application of reduce, adapt, erase, swap */ + eq0 = applyTypeUnificationRules(eq0, fc); /* * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs */ + Set eq1s = new HashSet<>(); Set eq2s = new HashSet<>(); splitEq(eq0, eq1s, eq2s); @@ -45,10 +54,39 @@ public class Unify { * Step 4: Magic */ + // Sets that originate from pair pattern matching + // Sets of the "second level" + Set>> pairSets = new HashSet>>(); + for(MPair pair : eq2s) + pairSets.add(calculateSets(pair)); + + // The sets of the "first level" + Set> sets = new HashSet>(); + + // Add Eq1' + sets.add(eq1s); + + // Add the set of [a =. Theta | (a=. Theta) in Eq2'] + sets.add(eq2s.stream() + .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) + .collect(Collectors.toSet())); + + /* + * Around here, filters for pairs and sets can be applied + */ + + ISetOperations setOps = new GuavaSetOperations(); + for(List> pairSet : pairSets) + setOps.cartesianProduct(pairSet).forEach(x -> sets.add(new HashSet(x))); + // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte + + Set> eqsSet = setOps.cartesianProduct(new ArrayList<>(sets)); + /* * Step 5: Repeated substitution */ + /* * Step 6: a) Restart for pairs where subst was applied * b) Union over everything @@ -61,6 +99,10 @@ public class Unify { throw new NotImplementedException(); } + protected List> calculateSets(MPair pair) { + return null; + } + protected void splitEq(Set eq, Set eq1s, Set eq2s) { for(MPair pair : eq) if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) From 4576efe3ec8dc0520a893b59c99c9a053fb551e6 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 23 Nov 2015 00:12:08 +0100 Subject: [PATCH 45/47] implemented step 4 (some cases still missing) --- .../unify/interfaces/IFiniteClosure.java | 2 +- .../typeinference/unifynew/Unify.java | 135 +++++++++++++----- 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index e469f41a..0601d70f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -22,7 +22,7 @@ public interface IFiniteClosure { * @return The set of supertypes of the argument. */ public Set greater(Type type); - + /** * Wo passt Type rein? * @param type diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index b87cd2b6..cb8ff602 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -16,30 +16,26 @@ import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations; +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.SuperType; +import de.dhbwstuttgart.typinference.unify.model.Type; /** - * Implementierung des Unifikationsalgorithmus. + * Implementation of the type unification algorithm * @author Florian Steurer */ public class Unify { - public Menge> unify(Menge eq, IFiniteClosure fc) { - /* - * Preparations: Create Mapping - */ - - Set eq0 = null; - - + public Menge> unify(Menge eq, IFiniteClosure fc) { /* * Step 1: Repeated application of reduce, adapt, erase, swap */ - eq0 = applyTypeUnificationRules(eq0, fc); + Set eq0 = applyTypeUnificationRules(eq, fc); /* @@ -51,35 +47,34 @@ public class Unify { splitEq(eq0, eq1s, eq2s); /* - * Step 4: Magic + * Step 4: Create possible typings */ // Sets that originate from pair pattern matching // Sets of the "second level" - Set>> pairSets = new HashSet>>(); - for(MPair pair : eq2s) - pairSets.add(calculateSets(pair)); - + List>> pairSets = calculatePairSets(eq2s, fc); + // The sets of the "first level" Set> sets = new HashSet>(); - - // Add Eq1' - sets.add(eq1s); + sets.add(eq1s); // Add Eq1' // Add the set of [a =. Theta | (a=. Theta) in Eq2'] sets.add(eq2s.stream() .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) .collect(Collectors.toSet())); - /* - * Around here, filters for pairs and sets can be applied - */ + /* Up to here, no cartesian products are calculated. + * Around here, filters for pairs and sets can be applied */ ISetOperations setOps = new GuavaSetOperations(); - for(List> pairSet : pairSets) - setOps.cartesianProduct(pairSet).forEach(x -> sets.add(new HashSet(x))); - // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte + // Calculate the inner cartesian products + // Cartesian products of the second level + for(List> pairSet : pairSets) // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte + setOps.cartesianProduct(pairSet).forEach(x -> sets.add(new HashSet(x))); + + // Calculate the outer cartesian products + // Cartesian products of the first level Set> eqsSet = setOps.cartesianProduct(new ArrayList<>(sets)); /* @@ -99,18 +94,6 @@ public class Unify { throw new NotImplementedException(); } - protected List> calculateSets(MPair pair) { - return null; - } - - protected void splitEq(Set eq, Set eq1s, Set eq2s) { - for(MPair pair : eq) - if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) - eq1s.add(pair); - else - eq2s.add(pair); - } - protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { /* @@ -183,4 +166,84 @@ public class Unify { collection.add(pair2); } + + protected void splitEq(Set eq, Set eq1s, Set eq2s) { + for(MPair pair : eq) + if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) + eq1s.add(pair); + else + eq2s.add(pair); + } + + + protected List>> calculatePairSets(Set eq2s, IFiniteClosure fc) { + List>> result = new ArrayList>>(); + for(int i = 0; i < 8; i++) + result.add(new ArrayList>()); + + + for(MPair pair : eq2s) { + + PairOperator pairOp = pair.getPairOp(); + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + + // Case 1: (a <. Theta') + if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) { + // TODO + } + + // Case 2: (a <.? ? ext Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType){ + // TODO + } + + // Case 3: (a <.? ? sup Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType) { + Set set = new HashSet<>(); + for(Type theta : fc.smArg(rhsType)) + set.add(new MPair(lhsType, theta, PairOperator.EQUALSDOT)); + + result.get(2).add(set); + } + + // Case 4: (a <.? Theta') + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType) { + Set set = new HashSet<>(); + set.add(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT)); + result.get(3).add(set); + } + + // Case 5: (Theta <. a) + else if(pairOp == PairOperator.SMALLERDOT && rhsType instanceof PlaceholderType) { + Set set = new HashSet<>(); + for(Type thetaS : fc.greater(lhsType)) + set.add(new MPair(rhsType, thetaS, PairOperator.EQUALSDOT)); + result.get(4).add(set); + } + + // Case 6: (? ext Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof ExtendsType && rhsType instanceof PlaceholderType) { + Set set = new HashSet<>(); + for(Type thetaS : fc.grArg(lhsType)) + set.add(new MPair(rhsType, thetaS, PairOperator.EQUALSDOT)); + result.get(5).add(set); + } + + // Case 7: (? sup Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof SuperType && rhsType instanceof PlaceholderType) { + // TODO + } + + // Case 8: (Theta <.? a) + else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType) { + Set set = new HashSet<>(); + for(Type thetaS : fc.grArg(lhsType)) + set.add(new MPair(rhsType, thetaS, PairOperator.EQUALSDOT)); + result.get(7).add(set); + } + } + + return result.stream().filter(x -> !x.isEmpty()).collect(Collectors.toList()); + } } From 7ff9554d7851d39b326bb57a0eec054e6bb80a7e Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 23 Nov 2015 00:15:12 +0100 Subject: [PATCH 46/47] application of adaptRules --- .../dhbwstuttgart/typeinference/unifynew/Unify.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index cb8ff602..480e9a5e 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -148,7 +148,16 @@ public class Unify { continue; } - // TODO adapt Rules + // Adapt, AdaptExt, AdaptSup + opt = rules.adapt(pair); + opt = opt.isPresent() ? opt : rules.adaptExt(pair); + opt = opt.isPresent() ? opt : rules.adaptSup(pair); + + // One of the rules has been applied + if(opt.isPresent()) { + swapAddOrErase(opt.get(), rules, eqQueue); + continue; + } // None of the rules has been applied targetSet.add(pair); From 97e0e2fc727d002837864b5e0bd851df73e1c6bb Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 23 Nov 2015 01:03:01 +0100 Subject: [PATCH 47/47] unifyTest --- .../typeinference/unifynew/Unify.java | 13 +++--- test/unify/UnifyTest.java | 46 ++++++++++++++++++- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 480e9a5e..33943e85 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -30,14 +30,13 @@ import de.dhbwstuttgart.typinference.unify.model.Type; */ public class Unify { - public Menge> unify(Menge eq, IFiniteClosure fc) { + public Menge> unify(Set eq, IFiniteClosure fc) { /* * Step 1: Repeated application of reduce, adapt, erase, swap */ Set eq0 = applyTypeUnificationRules(eq, fc); - /* * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs */ @@ -52,7 +51,7 @@ public class Unify { // Sets that originate from pair pattern matching // Sets of the "second level" - List>> pairSets = calculatePairSets(eq2s, fc); + List>> pairSetsSet = calculatePairSets(eq2s, fc); // The sets of the "first level" Set> sets = new HashSet>(); @@ -70,15 +69,15 @@ public class Unify { // Calculate the inner cartesian products // Cartesian products of the second level - for(List> pairSet : pairSets) // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte - setOps.cartesianProduct(pairSet).forEach(x -> sets.add(new HashSet(x))); + for(List> pairSets : pairSetsSet) // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte + setOps.cartesianProduct(pairSets).forEach(x -> sets.add(new HashSet(x))); // Calculate the outer cartesian products // Cartesian products of the first level Set> eqsSet = setOps.cartesianProduct(new ArrayList<>(sets)); /* - * Step 5: Repeated substitution + * Step 5: Substitution */ @@ -122,7 +121,7 @@ public class Unify { * Apply rules until the queue is empty */ while(!eqQueue.isEmpty()) { - MPair pair = eqQueue.getFirst(); + MPair pair = eqQueue.pollFirst(); // ReduceUp, ReduceLow, ReduceUpLow Optional opt = rules.reduceUpLow(pair); diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 747374b2..65f94d96 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -1,7 +1,51 @@ package unify; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unifynew.Unify; +import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; public class UnifyTest extends Unify { - + + @Test + public void unifyTest() { + TypeFactory tf = new TypeFactory(); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + Set eq = new HashSet(); + + fcb.add(tf.getSimpleType("Number"), tf.getSimpleType("Object")); + fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); + fcb.add(tf.getSimpleType("Double"), tf.getSimpleType("Number")); + + IFiniteClosure fc = fcb.getCollectionExample(); + + // Vector <. Vector + // A <. Number + // Double <. B + // B <. Object + eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT)); + eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("Number"), 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.getPlaceholderType("B"), tf.getSimpleType("Object"), PairOperator.EQUALSDOT)); + + this.unify(eq, fc); + + } + + @Test + public void applyTypeUnificationRulesTest() { + + } + + @Test + public void calculatePairSetsTest() { + + } + }