From 0e524caae759156fc0e4569f68a5512d8ea9774c Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Tue, 22 Mar 2016 20:41:24 +0100 Subject: [PATCH 01/14] Added missing rules --- .../unify/interfaces/IRuleSet.java | 8 ++ .../typeinference/unifynew/RuleSet.java | 98 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index 840d7259..d86ebdd8 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -16,6 +16,14 @@ public interface IRuleSet { public Optional> reduce1(MPair pair); public Optional> reduce2(MPair pair); + public Optional reduceWildcardLow(MPair pair); + public Optional reduceWildcardLowRight(MPair pair); + public Optional reduceWildcardUp(MPair pair); + public Optional reduceWildcardUpRight(MPair pair); + public Optional reduceWildCardLowUp(MPair pair); + public Optional reduceWildcardUpLow(MPair pair); + public Optional reduceWildcardLeft(MPair pair); + public boolean erase1(MPair pair); public boolean erase2(MPair pair); public boolean erase3(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index e41525f5..11138a47 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -559,4 +559,102 @@ public class RuleSet implements IRuleSet{ return applied ? Optional.of(new HashSet<>(result)) : Optional.empty(); } + + @Override + public Optional reduceWildcardLow(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardLowRight(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if((lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardUp(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildcardUpRight(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if((lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOT)); + } + + @Override + public Optional reduceWildCardLowUp(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof SuperType)) + return Optional.empty(); + + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), ((SuperType) rhsType).getSuperedType(), PairOperator.EQUALSDOT)); + } + + @Override + public Optional reduceWildcardUpLow(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + if(!(lhsType instanceof SuperType) || !(rhsType instanceof ExtendsType)) + return Optional.empty(); + + return Optional.of(new MPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT)); + } + + @Override + public Optional reduceWildcardLeft(MPair pair) { + if(pair.getPairOp() != PairOperator.SMALLERDOTWC) + return Optional.empty(); + + Type rhsType = pair.getRhsType(); + if((rhsType instanceof SuperType) || (rhsType instanceof ExtendsType)) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + + if(lhsType instanceof SuperType) + return Optional.of(new MPair(((SuperType) lhsType).getSuperedType(), rhsType, PairOperator.EQUALSDOT)); + + if(lhsType instanceof ExtendsType) + return Optional.of(new MPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.EQUALSDOT)); + + return Optional.empty(); + } } From 14e00913e89e49288964f29ef46d8ccf6ce264a2 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Tue, 22 Mar 2016 20:47:39 +0100 Subject: [PATCH 02/14] application of new rules --- .../typeinference/unify/interfaces/IRuleSet.java | 2 +- src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java | 2 +- src/de/dhbwstuttgart/typeinference/unifynew/Unify.java | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index d86ebdd8..c4de888d 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 Optional reduceWildcardLowRight(MPair pair); public Optional reduceWildcardUp(MPair pair); public Optional reduceWildcardUpRight(MPair pair); - public Optional reduceWildCardLowUp(MPair pair); + public Optional reduceWildcardLowUp(MPair pair); public Optional reduceWildcardUpLow(MPair pair); public Optional reduceWildcardLeft(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 11138a47..52239af4 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -613,7 +613,7 @@ public class RuleSet implements IRuleSet{ } @Override - public Optional reduceWildCardLowUp(MPair pair) { + public Optional reduceWildcardLowUp(MPair pair) { if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index ae702fba..6e6fe376 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -178,6 +178,13 @@ public class Unify { Optional opt = rules.reduceUpLow(pair); opt = opt.isPresent() ? opt : rules.reduceLow(pair); opt = opt.isPresent() ? opt : rules.reduceUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLow(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLowRight(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair); + opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair); // One of the rules has been applied if(opt.isPresent()) { From 88726ccb7059078f3e1b972ef50e41339a883c98 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 23 Mar 2016 09:45:36 +0100 Subject: [PATCH 03/14] added funN --- .../unify/interfaces/IFiniteClosure.java | 4 +++ .../unify/model/FiniteClosure.java | 14 +++++++- .../typeinference/unify/model/FunNType.java | 34 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 3af29411..0bba681f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -4,6 +4,7 @@ import java.util.Optional; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; +import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.SimpleType; import de.dhbwstuttgart.typeinference.unify.model.SuperType; @@ -49,6 +50,9 @@ public interface IFiniteClosure { public Set grArg(PlaceholderType type); public Set smArg(PlaceholderType type); + public Set grArg(FunNType type); + public Set smArg(FunNType type); + public Optional getGenericType(String typeName); public Set getAllTypesByName(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 64fb6862..27827dbe 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; @@ -193,6 +194,11 @@ public class FiniteClosure implements IFiniteClosure { return result; } + @Override + public Set grArg(FunNType type) { + throw new NotImplementedException(); + } + @Override public Set grArg(ExtendsType type) { if(!inheritanceGraph.containsKey(type.getExtendedType())) @@ -249,7 +255,13 @@ public class FiniteClosure implements IFiniteClosure { return result; } - + + @Override + public Set smArg(FunNType type) { + throw new NotImplementedException(); + } + + @Override public Set smArg(ExtendsType type) { if(!inheritanceGraph.containsKey(type.getExtendedType())) return new HashSet(); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java new file mode 100644 index 00000000..a6068c84 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java @@ -0,0 +1,34 @@ +package de.dhbwstuttgart.typeinference.unify.model; + +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; + +public class FunNType extends Type { + + public FunNType(TypeParams p) { + super("FuN", p); + } + + @Override + public Type setTypeParams(TypeParams newTp) { + return new FunNType(newTp); + } + + @Override + Set smArg(IFiniteClosure fc) { + return fc.smArg(this); + } + + @Override + Set grArg(IFiniteClosure fc) { + return fc.grArg(this); + } + + @Override + Type apply(Unifier unif) { + // TODO Auto-generated method stub + return null; + } + +} From 11bcf5735a68b878090c31c266072a9f3ab0a86a Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 23 Mar 2016 10:59:41 +0100 Subject: [PATCH 04/14] freshPlaceholder Method // funN rules (not implemented yet) --- .../unify/interfaces/IRuleSet.java | 10 ++++++++ .../unify/model/PlaceholderType.java | 24 +++++++++++++++++++ .../typeinference/unify/model/TypeParams.java | 2 +- .../typeinference/unifynew/RuleSet.java | 18 ++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index c4de888d..23c444e0 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -16,6 +16,9 @@ public interface IRuleSet { public Optional> reduce1(MPair pair); public Optional> reduce2(MPair pair); + /* + * Missing Rules + */ public Optional reduceWildcardLow(MPair pair); public Optional reduceWildcardLowRight(MPair pair); public Optional reduceWildcardUp(MPair pair); @@ -24,6 +27,13 @@ public interface IRuleSet { public Optional reduceWildcardUpLow(MPair pair); public Optional reduceWildcardLeft(MPair pair); + /* + * FunN Rules + */ + public Optional> reduceFunN(MPair pair); + public Optional> greaterFunN(MPair pair); + public Optional> smallerFunN(MPair pair); + public boolean erase1(MPair pair); public boolean erase2(MPair pair); public boolean erase3(MPair pair); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index 5a3d5341..b5a0fe1e 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -1,13 +1,37 @@ package de.dhbwstuttgart.typeinference.unify.model; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; import java.util.Set; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; public final class PlaceholderType extends Type{ + protected static final HashSet EXISTING_PLACEHOLDERS = new HashSet(); + protected static String nextName = "gen_"; + public PlaceholderType(String name) { super(name); + EXISTING_PLACEHOLDERS.add(name); + } + + public static PlaceholderType freshPlaceholder() { + String name = nextName + randomChar(); + + while(EXISTING_PLACEHOLDERS.contains(name)); + nextName += randomChar(); + + return new PlaceholderType(name); + } + + /** + * Returns random char between 'a' and 'z' + * @return + */ + private static char randomChar() { + return (char) (new Random().nextInt(22) + 97); } @Override diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index 966a561b..a7393508 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -5,7 +5,7 @@ import java.util.Iterator; public final class TypeParams implements Iterable{ private final Type[] typeParams; - + public TypeParams(Type... types) { typeParams = types; } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 52239af4..4232a692 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -657,4 +657,22 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); } + + @Override + public Optional> reduceFunN(MPair pair) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Optional> greaterFunN(MPair pair) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Optional> smallerFunN(MPair pair) { + // TODO Auto-generated method stub + return null; + } } From a5b86dc84c5f9614f96e08fb58d4b60787eccffe Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 23 Mar 2016 11:44:31 +0100 Subject: [PATCH 05/14] freshPlaceholder / implemented funn rules --- .../typeinference/unify/model/FunNType.java | 10 +++ .../unify/model/PlaceholderType.java | 1 - .../typeinference/unifynew/RuleSet.java | 75 +++++++++++++++++-- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java index a6068c84..bb74d39e 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FunNType.java @@ -8,13 +8,21 @@ public class FunNType extends Type { public FunNType(TypeParams p) { super("FuN", p); + if(p.size() == 0) + throw new IllegalArgumentException("Function types need at least one type parameter"); } @Override public Type setTypeParams(TypeParams newTp) { + if(newTp.size() == 0) + throw new IllegalArgumentException("Function types need at least one type parameter"); return new FunNType(newTp); } + public int getN() { + return typeParams.size()-1; + } + @Override Set smArg(IFiniteClosure fc) { return fc.smArg(this); @@ -31,4 +39,6 @@ public class FunNType extends Type { return null; } + // TODO equals und hashcode + } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java index b5a0fe1e..8a7769de 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java @@ -28,7 +28,6 @@ public final class PlaceholderType extends Type{ /** * Returns random char between 'a' and 'z' - * @return */ private static char randomChar() { return (char) (new Random().nextInt(22) + 97); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 4232a692..f6b26ad9 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -14,6 +14,7 @@ import junit.framework.Assert; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; +import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.MPair; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.SimpleType; @@ -660,19 +661,81 @@ public class RuleSet implements IRuleSet{ @Override public Optional> reduceFunN(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + + if(!(lhsType instanceof FunNType) || !(rhsType instanceof FunNType)) + return Optional.empty(); + + FunNType funNLhsType = (FunNType) lhsType; + FunNType funNRhsType = (FunNType) rhsType; + + if(funNLhsType.getN() != funNRhsType.getN()) + return Optional.empty(); + + Set result = new HashSet(); + + result.add(new MPair(funNLhsType.getTypeParams().get(0), funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); + for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) + result.add(new MPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); + + return Optional.of(result); } @Override public Optional> greaterFunN(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + + if(!(lhsType instanceof FunNType) || !(rhsType instanceof PlaceholderType)) + return Optional.empty(); + + FunNType funNLhsType = (FunNType) lhsType; + + Set result = new HashSet(); + + Type[] freshPlaceholders = new Type[funNLhsType.getTypeParams().size()]; + for(int i = 0; i < freshPlaceholders.length; i++) + freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); + + result.add(new MPair(funNLhsType.getTypeParams().get(0), freshPlaceholders[0], PairOperator.SMALLERDOT)); + for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) + result.add(new MPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); + result.add(new MPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); + + return Optional.of(result); } @Override public Optional> smallerFunN(MPair pair) { - // TODO Auto-generated method stub - return null; + if(pair.getPairOp() != PairOperator.SMALLERDOT) + return Optional.empty(); + + Type lhsType = pair.getLhsType(); + Type rhsType = pair.getRhsType(); + + if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof FunNType)) + return Optional.empty(); + + FunNType funNRhsType = (FunNType) rhsType; + + Set result = new HashSet(); + + Type[] freshPlaceholders = new Type[funNRhsType.getTypeParams().size()]; + for(int i = 0; i < freshPlaceholders.length; i++) + freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); + + result.add(new MPair(freshPlaceholders[0], funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); + for(int i = 1; i < funNRhsType.getTypeParams().size(); i++) + result.add(new MPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT)); + result.add(new MPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT)); + + return Optional.of(result); } } From bbfd8699e885fbfd7408d79cc744b58fc2cf43ca Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 26 Mar 2016 00:03:26 +0100 Subject: [PATCH 06/14] smaller / smArg / grArg / TODO: greater --- .../unify/model/FiniteClosure.java | 103 ++++-------------- .../typeinference/unify/model/Unifier.java | 6 +- .../unifynew/MartelliMontanariUnify.java | 6 +- 3 files changed, 31 insertions(+), 84 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 27827dbe..a1b56472 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -24,11 +24,13 @@ public class FiniteClosure implements IFiniteClosure { } public FiniteClosure(Set pairs) { - inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { + if(!pair.getLhsType().getTypeParams().arePlaceholders()) + throw new IllegalArgumentException("The finite closure only has pairs of the form D <= C<...>"); + if(pair.getPairOp() != PairOperator.SMALLER) continue; @@ -66,14 +68,15 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - // - if(T < T') then T <=* T' - Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : new HashSet<>(); + Set result = new HashSet<>(); result.add(type); + // - if(T < T') then T <=* T' // if T1 <=* T2 then sigma1(T1) <=* sigma1(T2) // where foreach type var a in T2: // sigma1(T1) <=* sigma2(T2) - /*if(strInheritanceGraph.containsKey(type.getName())) { + //If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied) + if(strInheritanceGraph.containsKey(type.getName())) { IUnify unify = new MartelliMontanariUnify(); HashSet> candidateNodes = strInheritanceGraph.get(type.getName()); for(Node candidateNode : candidateNodes) { @@ -81,67 +84,27 @@ public class FiniteClosure implements IFiniteClosure { Optional sigma2 = unify.unify(theta2, type); if(!sigma2.isPresent()) continue; - for(Type sigma1theta1 : candidateNode.getContentOfDescendants()) { - Type theta1 = sigma2.get().apply(sigma1theta1); + Set theta1s = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : smaller(theta2); + for(Type theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + Type sigma1Theta1 = sigma2.get().apply(theta1); + + ArrayList> paramCandidates = new ArrayList<>(); + for(Type param : sigma1Theta1.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for(TypeParams newParams : permResult) + result.add(sigma1Theta1.setTypeParams(newParams)); } } - }*/ - - if(type.getTypeParams().size() == 0) - return result; - - ArrayList> paramCandidates = new ArrayList<>(); - for(Type param : type.getTypeParams()) { - if(param instanceof ExtendsType || param instanceof SuperType) { - Set pc = param.smArg(this); - paramCandidates.add(pc); - } else { - HashSet pc = new HashSet<>(); - pc.add(param); - paramCandidates.add(pc); - } } - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); - - for(TypeParams newParams : permResult) - result.add(type.setTypeParams(newParams)); - return result; } - /** - * @param t1 - * @param t2 - * @return - */ - protected Optional match(Type t1, Type t2) { - if(!t1.getName().equals(t2.getName())) - return Optional.empty(); - - TypeParams t1Params = t1.getTypeParams(); - TypeParams t2Params = t2.getTypeParams(); - - if(t1Params.size() != t2Params.size()) - return Optional.empty(); - - Unifier result = new Unifier(); - for(int i = 0; i < t1Params.size(); i++) { - Type t1i = t1Params.get(i); - Type t2i = t2Params.get(i); - - boolean equal = t1i.equals(t2i); - if(!equal && !(t2i instanceof PlaceholderType)) - return Optional.empty(); - - if(!equal && t2i instanceof PlaceholderType) - result.Add((PlaceholderType) t2i, t1i); - } - - return Optional.of(result); - } - /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. @@ -182,9 +145,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -201,9 +161,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -216,9 +173,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set grArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -245,13 +199,10 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SimpleType type) { - if(!inheritanceGraph.containsKey(type)) - return new HashSet(); - Set result = new HashSet(); result.add(type); - smaller(type).forEach(x -> result.add(new ExtendsType(x))); + // smaller(type).forEach(x -> result.add(new ExtendsType(x))); TODO inkorrekt? daher erstmal raus return result; } @@ -263,9 +214,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(ExtendsType type) { - if(!inheritanceGraph.containsKey(type.getExtendedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -283,9 +231,6 @@ public class FiniteClosure implements IFiniteClosure { @Override public Set smArg(SuperType type) { - if(!inheritanceGraph.containsKey(type.getSuperedType())) - return new HashSet(); - Set result = new HashSet(); result.add(type); @@ -304,8 +249,8 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - result.add(new SuperType(type)); - result.add(new ExtendsType(type)); + //result.add(new SuperType(type)); TODO inkorrekt, daher erstmal raus + //result.add(new ExtendsType(type)); return result; } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index add681e5..6c2eaa0f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -8,8 +8,6 @@ import java.util.function.Function; public class Unifier implements Function /*, Set*/ { // TODO set implementieren private HashMap substitutions = new HashMap<>(); - public static Unifier IDENTITY = new Unifier(); - public Unifier(PlaceholderType source, Type target) { substitutions.put(source, target); } @@ -21,6 +19,10 @@ public class Unifier implements Function /*, Set*/ { // TODO } + public static Unifier Identity() { + return new Unifier(); + } + public void Add(PlaceholderType source, Type target) { Unifier tempU = new Unifier(source, target); for(PlaceholderType pt : substitutions.keySet()) diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java index d15fefdd..6ae0acf6 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -26,7 +26,7 @@ public class MartelliMontanariUnify implements IUnify { @Override public Optional unify(Set terms) { if(terms.size() < 2) - return Optional.of(Unifier.IDENTITY); + return Optional.of(Unifier.Identity()); ArrayList termsQ = new ArrayList(); Iterator iter = terms.iterator(); @@ -37,7 +37,7 @@ public class MartelliMontanariUnify implements IUnify { prev = next; } - Unifier mgu = Unifier.IDENTITY; + Unifier mgu = Unifier.Identity(); int idx = 0; while(idx < termsQ.size()) { @@ -101,7 +101,7 @@ public class MartelliMontanariUnify implements IUnify { TypeParams rhsTypeParams = rhs.getTypeParams(); TypeParams lhsTypeParams = lhs.getTypeParams(); - if(!rhs.getName().equals(lhs.getName()) || rhsTypeParams.size() != lhsTypeParams.size()) + if(rhsTypeParams.size() != lhsTypeParams.size() || (!rhs.getName().equals(lhs.getName()) && rhsTypeParams.size() != 0)) return null; // conflict if(rhsTypeParams.size() == 0 || lhsTypeParams.size() == 0) From 5e184968470c813e0d804a5be6d8ccbedd87a5aa Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 26 Mar 2016 12:59:38 +0100 Subject: [PATCH 07/14] smaller and test cases --- .../unify/model/FiniteClosure.java | 60 ++--- test/unify/FiniteClosureTest.java | 227 +++++++++++++++--- 2 files changed, 224 insertions(+), 63 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index a1b56472..427122bf 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -19,10 +19,6 @@ public class FiniteClosure implements IFiniteClosure { private HashMap> inheritanceGraph; private HashMap>> strInheritanceGraph; - public FiniteClosure() { - - } - public FiniteClosure(Set pairs) { inheritanceGraph = new HashMap>(); @@ -76,32 +72,42 @@ public class FiniteClosure implements IFiniteClosure { // where foreach type var a in T2: // sigma1(T1) <=* sigma2(T2) //If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied) - if(strInheritanceGraph.containsKey(type.getName())) { - IUnify unify = new MartelliMontanariUnify(); - HashSet> candidateNodes = strInheritanceGraph.get(type.getName()); - for(Node candidateNode : candidateNodes) { - Type theta2 = candidateNode.getContent(); - Optional sigma2 = unify.unify(theta2, type); - if(!sigma2.isPresent()) - continue; - Set theta1s = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : smaller(theta2); - for(Type theta1 : theta1s) { - // Because only the most general type is calculated, sigma1 = sigma2 - Type sigma1Theta1 = sigma2.get().apply(theta1); + + IUnify unify = new MartelliMontanariUnify(); + HashSet candidates = new HashSet<>(); + if (strInheritanceGraph.containsKey(type.getName())) + strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); + else + candidates.add(type); + + for (Type theta2 : candidates) { + Optional sigma2 = unify.unify(theta2, type); + if (!sigma2.isPresent()) + continue; + Set theta1s = new HashSet<>(); + if(inheritanceGraph.containsKey(type)) + theta1s = inheritanceGraph.get(type).getContentOfDescendants(); + else if(theta2.equals(type)) + theta1s.add(type); + else + theta1s = smaller(theta2); + for (Type theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = + // sigma2 + Type sigma1Theta1 = sigma2.get().apply(theta1); - ArrayList> paramCandidates = new ArrayList<>(); - for(Type param : sigma1Theta1.getTypeParams()) - paramCandidates.add(smArg(param)); - - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); - - for(TypeParams newParams : permResult) - result.add(sigma1Theta1.setTypeParams(newParams)); - } + ArrayList> paramCandidates = new ArrayList<>(); + for (Type param : sigma1Theta1.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for (TypeParams newParams : permResult) + result.add(sigma1Theta1.setTypeParams(newParams)); } } - + return result; } diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 073b4a94..c35bfe66 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -1,49 +1,218 @@ package unify; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + import org.junit.Assert; import org.junit.Test; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; -import de.dhbwstuttgart.typeinference.unify.model.MPair; -import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator; -import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.Type; import de.dhbwstuttgart.typeinference.unifynew.TypeFactory; -public class FiniteClosureTest extends FiniteClosure { +public class FiniteClosureTest { @Test - public void testMatch() { + public void testSmaller() { TypeFactory tf = new TypeFactory(); - Type a = tf.getPlaceholderType("a"); - Type b = tf.getPlaceholderType("b"); - Type c = tf.getPlaceholderType("c"); + Type integer = tf.getSimpleType("Integer"); + Type number = tf.getSimpleType("Number"); - Type A = tf.getSimpleType("A"); - Type B = tf.getSimpleType("B"); - Type C1 = tf.getSimpleType("C", a, b, c); - Type C2 = tf.getSimpleType("C", a, A, b); - Type C3 = tf.getSimpleType("C", A, B, A); - Type D1 = tf.getSimpleType("D", C1, a, b, c); - Type D2 = tf.getSimpleType("D", C3, A, B, A); + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + fcb.add(integer, number); + fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer"))); + fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection")); + IFiniteClosure fc = fcb.getCollectionExample(); + + /* + * Test Case 1: + * + * smaller(Set) = { HashSet, Set, LinkedHashSet } + */ - System.out.println(match(C2, C1)); - System.out.println(match(C3, C1)); - System.out.println(match(D2, D1)); - Assert.assertFalse(match(C3, C2).isPresent()); - Assert.assertFalse(match(C1, C2).isPresent()); + Type setInt = tf.getSimpleType("Set", integer); + Type hashSetInt = tf.getSimpleType("HashSet", integer); + Type treeSetInt = tf.getSimpleType("TreeSet", integer); + Type linkedHashSetInt = tf.getSimpleType("LinkedHashSet", integer); + + Set expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setInt)); + + /* + * Test Case 2: + * + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + Type extInt = tf.getExtendsType(integer); + Type hashSetExtInt = tf.getSimpleType("HashSet", extInt); + Type treeSetExtInt = tf.getSimpleType("TreeSet", extInt); + Type linkedHashSetExtInt = tf.getSimpleType("LinkedHashSet", extInt); + Type setExtInt = tf.getSimpleType("Set", extInt); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + hashSetExtInt, treeSetExtInt, linkedHashSetExtInt, setExtInt, + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtInt)); + + /* + * Test Case 3: + * + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet + * HashSet } + */ + + Type hashSetNum = tf.getSimpleType("HashSet", number); + Type treeSetNum = tf.getSimpleType("TreeSet", number); + Type linkedHashSetNum = tf.getSimpleType("LinkedHashSet", number); + Type setNum = tf.getSimpleType("Set", number); + + Type extNum = tf.getExtendsType(number); + Type hashSetExtNum = tf.getSimpleType("HashSet", extNum); + Type treeSetExtNum = tf.getSimpleType("TreeSet", extNum); + Type linkedHashSetExtNum = tf.getSimpleType("LinkedHashSet", extNum); + Type setExtNum = tf.getSimpleType("Set", extNum); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + setNum, hashSetNum, linkedHashSetNum, treeSetNum, + setExtInt, hashSetExtInt, linkedHashSetExtInt, treeSetExtInt, + setExtNum, hashSetExtNum, linkedHashSetExtNum, treeSetExtNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtNum)); + + /* + * Test Case 4: + * TODO ist das ergebnis korrekt oder müssen die ? ext Ts raus weil der allgemeienste Typ T ausreicht? + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + Type t = tf.getPlaceholderType("T"); + Type setT = tf.getSimpleType("Set", t); + Type hashSetT = tf.getSimpleType("HashSet", t); + Type treeSetT = tf.getSimpleType("TreeSet", t); + Type linkedHashSetT = tf.getSimpleType("LinkedHashSet", t); + Type hashSetExtT = tf.getSimpleType("HashSet", t); + Type treeSetExtT = tf.getSimpleType("TreeSet", t); + Type linkedHashSetExtT = tf.getSimpleType("LinkedHashSet", t); + Type setExtT = tf.getSimpleType("Set", t); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setT, hashSetT, treeSetT, linkedHashSetT, + setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setT)); + + /* + * Test Case 5 + * + * smaller(Set = + * { Set, HashSet, TreeSet, LinkedHashSet, + * Set, HashSet, TreeSet, LinkedHashSet, + * Set, HashSet, TreeSet, LinkedHashSet } + */ + + Type superNum = tf.getSuperType(number); + Type superInt = tf.getSuperType(integer); + + Type setSupInt = tf.getSimpleType("Set", superInt); + Type hashSetSupInt = tf.getSimpleType("HashSet", superInt); + Type linkedHashSetSupInt = tf.getSimpleType("LinkedHashSet", superInt); + Type treeSetSupInt = tf.getSimpleType("TreeSet", superInt); + Type setSupNum = tf.getSimpleType("Set", superNum); + Type hashSetSupNum = tf.getSimpleType("HashSet", superNum); + Type linkedHashSetSupNum = tf.getSimpleType("LinkedHashSet", superNum); + Type treeSetSupNum = tf.getSimpleType("TreeSet", superNum); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setSupInt, hashSetSupInt, linkedHashSetSupInt, treeSetSupInt, + setSupNum, hashSetSupNum, linkedHashSetSupNum, treeSetSupNum, + setInt, hashSetInt, linkedHashSetInt, treeSetInt, + setNum, hashSetNum, linkedHashSetNum, treeSetNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setSupInt)); + + /* + * Test Case 6: + * + * smaller(Set, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + * + */ + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setT, hashSetT, treeSetT, linkedHashSetT, + setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setExtT)); + + /* + * Test Case 7: + * smaller(Set) = + * { HashSet, Set, TreeSet, LinkedHashSet, + * HashSet, Set, TreeSet, LinkedHashSet } + */ + + Type notInFc = tf.getSimpleType("notInFC"); + Type setNotInFc = tf.getSimpleType("Set", notInFc); + Type hashSetNotInFc = tf.getSimpleType("HashSet", notInFc); + Type treeSetNotInFc = tf.getSimpleType("TreeSet", notInFc); + Type linkedHashSetNotInFc = tf.getSimpleType("LinkedHashSet", notInFc); + Type hashSetExtNotInFc = tf.getSimpleType("HashSet", notInFc); + Type treeSetExtNotInFc = tf.getSimpleType("TreeSet", notInFc); + Type linkedHashSetExtNotInFc = tf.getSimpleType("LinkedHashSet", notInFc); + Type setExtNotInFc = tf.getSimpleType("Set", notInFc); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setNotInFc, hashSetNotInFc, treeSetNotInFc, linkedHashSetNotInFc, + setExtNotInFc, hashSetExtNotInFc, treeSetExtNotInFc, linkedHashSetExtNotInFc + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setNotInFc)); + + /* + * Test Case 8: + * + */ } @Test public void testGreater() { - IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample(); TypeFactory tf = new TypeFactory(); - + FiniteClosureBuilder fcb = new FiniteClosureBuilder(); + fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); + fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer"))); + fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection")); + IFiniteClosure fc = fcb.getCollectionExample(); + 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"))); + System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Integer")))); + System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Number")))); + System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getExtendsType(tf.getSimpleType("Integer"))))); + System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSuperType(tf.getSimpleType("Integer"))))); } @Test @@ -57,20 +226,6 @@ public class FiniteClosureTest extends FiniteClosure { System.out.println("GrArg(? super List) = " + fc.grArg(tf.getSuperType(tf.getSimpleType("List", "T")))); } - @Test - public void testSmaller() { - FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - TypeFactory tf = new TypeFactory(); - - fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); - IFiniteClosure fc = fcb.getCollectionExample(); - - System.out.println("\n\n----- Smaller Test -----"); - System.out.println("Smaller(List) = " + fc.smaller(tf.getSimpleType("List", tf.getExtendsType(tf.getSimpleType("Number"))))); - 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() { From 257edfc0b3c19bf43f71952d5066abf572445101 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 26 Mar 2016 14:09:45 +0100 Subject: [PATCH 08/14] fc smaller test --- test/unify/FiniteClosureBuilder.java | 18 +++++ test/unify/FiniteClosureTest.java | 107 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index d5b3b32b..5a639b38 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -29,6 +29,8 @@ public class FiniteClosureBuilder { public IFiniteClosure getCollectionExample() { TypeFactory tf = new TypeFactory(); + /* Collection */ + Type collection = tf.getSimpleType("Collection"); Type set = tf.getSimpleType("Set", "T"); Type sortedSet = tf.getSimpleType("Set", "T"); @@ -58,6 +60,22 @@ public class FiniteClosureBuilder { add(arrayList, list); add(stack, vector); + /* Map */ + Type map = tf.getSimpleType("Map", "K", "V"); + Type sortedMap = tf.getSimpleType("SortedMap", "K", "V"); + Type navigableMap = tf.getSimpleType("NavigableMap", "K", "V"); + Type treeMap = tf.getSimpleType("TreeMap", "K", "V"); + Type hashMap = tf.getSimpleType("HashMap", "K", "V"); + Type hashtable = tf.getSimpleType("Hashtable", "K", "V"); + Type linkedHashMap = tf.getSimpleType("LinkedHashSet", "K", "V"); + + add(sortedMap, map); + add(hashMap, map); + add(hashtable, map); + add(navigableMap, sortedMap); + add(treeMap, navigableMap); + add(linkedHashMap, hashMap); + IFiniteClosure fc = getFiniteClosure(); clear(); return fc; diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index c35bfe66..d3766e74 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -168,6 +168,7 @@ public class FiniteClosureTest { /* * Test Case 7: + * * smaller(Set) = * { HashSet, Set, TreeSet, LinkedHashSet, * HashSet, Set, TreeSet, LinkedHashSet } @@ -193,6 +194,112 @@ public class FiniteClosureTest { /* * Test Case 8: * + * smaller(Set) = + * { Set, HashSet, LinkedHashSet, TreeSet, + * Set, HashSet, LinkedHashSet, TreeSet } + */ + + Type superNotInFc = tf.getSuperType(notInFc); + Type setSuperNotInFc = tf.getSimpleType("Set", superNotInFc); + Type hashSetSuperNotInFc = tf.getSimpleType("HashSet", superNotInFc); + Type treeSetSuperNotInFc = tf.getSimpleType("TreeSet", superNotInFc); + Type linkedHashSetSuperNotInFc = tf.getSimpleType("LinkedHashSet", superNotInFc); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + setNotInFc, hashSetNotInFc, treeSetNotInFc, linkedHashSetNotInFc, + setSuperNotInFc, hashSetSuperNotInFc, treeSetSuperNotInFc, linkedHashSetSuperNotInFc + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(setSuperNotInFc)); + + /* + * Test Case 8: + * + * smaller(NotInFc) = + * { NotInFc, NotInFc, NotInFc, NotInFc } + */ + + Type notInFcExtNumber = tf.getSimpleType("NotInFc", extNum); + Type notInFcInteger = tf.getSimpleType("NotInFc", integer); + Type notInFcNumber = tf.getSimpleType("NotInFc", number); + Type notInFcExtInt = tf.getSimpleType("NotInFc", extInt); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + notInFcExtNumber, notInFcInteger, notInFcNumber, notInFcExtInt + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, fc.smaller(notInFcExtNumber)); + + /* + * Test Case 9: + * + * smaller(NotInFc = + * { NotInFc, NotInFc } + */ + + Type alsoNotInFc = tf.getSimpleType("AlsoNotInFc"); + Type notInFcAlsoNotInFc = tf.getSimpleType("NotInFc", alsoNotInFc); + Type notInFcSupAlsoNotInFc = tf.getSimpleType("NotInFc", tf.getSuperType(alsoNotInFc)); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + notInFcAlsoNotInFc, notInFcSupAlsoNotInFc + }).collect(Collectors.toSet())); + + Set actual = fc.smaller(notInFcSupAlsoNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 10: + * + * smaller(HashMap) = + * { HashMap, HashMap, HashMap, HashMap + * HashMap, HashMap, HashMap, HashMap, + * HashMap, HashMap, HashMap + * HashMap, HashMap, HashMap, HashMap } + */ + + /* + * Test Case 11: + * + * smaller(SortedMap) = { SortedMap, NavigableMap, TreeMap } + */ + + /* + * Test Case 12: + * + * MyMap> <* HashMap + * + * smaller(HashMap) = { HashMap>, MyMap> } + */ + + /* + * Test Case 13: + * + * MyMap> <* HashMap + * + * smaller(HashMap) = + * { HashMap, List>, + * HashMap>, + * MyMap> } + */ + + /* + * Test Case 14 + * + * MyMap> <* HashMap + * + * smaller(HashMap) = + */ + + /* + * Test Case 13: + * + * MyMap> <* HashMap +// * TODO sinnvoll ausformulieren + * smaller(HashMap) = + * { HashMap, List>, + * HashMap>, + * MyMap> } */ } From 26cc9b85efa4a2d7f8bec46874ce9b11fef76563 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 01:01:46 +0200 Subject: [PATCH 09/14] smalller und neue testcases --- .../unify/interfaces/IFiniteClosure.java | 2 +- .../unify/model/FiniteClosure.java | 145 +++++++++++------- .../unifynew/MartelliMontanariUnify.java | 8 +- .../typeinference/unifynew/RuleSet.java | 14 +- test/unify/FiniteClosureBuilder.java | 9 +- test/unify/FiniteClosureTest.java | 88 +++++++++-- 6 files changed, 185 insertions(+), 81 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 0bba681f..00c12f65 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -53,6 +53,6 @@ public interface IFiniteClosure { public Set grArg(FunNType type); public Set smArg(FunNType type); - public Optional getGenericType(String typeName); + public Optional findGenericParent(String typeName); public Set getAllTypesByName(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 427122bf..4a331353 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -18,15 +18,17 @@ public class FiniteClosure implements IFiniteClosure { private HashMap> inheritanceGraph; private HashMap>> strInheritanceGraph; + private Set pairs; + private Set basicTypes; + //TODO im konstruktor mitgeben um typenabzuhandeln die keine extends beziehung haben. (Damit die FC diese Typen auch kennt) + //(ALternative: immer die extends zu object beziehung einfügen) public FiniteClosure(Set pairs) { + this.pairs = new HashSet<>(pairs); inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(MPair pair : pairs) { - if(!pair.getLhsType().getTypeParams().arePlaceholders()) - throw new IllegalArgumentException("The finite closure only has pairs of the form D <= C<...>"); - if(pair.getPairOp() != PairOperator.SMALLER) continue; @@ -64,51 +66,68 @@ public class FiniteClosure implements IFiniteClosure { */ @Override public Set smaller(Type type) { - Set result = new HashSet<>(); - result.add(type); - - // - if(T < T') then T <=* T' - // if T1 <=* T2 then sigma1(T1) <=* sigma1(T2) - // where foreach type var a in T2: - // sigma1(T1) <=* sigma2(T2) - //If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied) - + if(inheritanceGraph.containsKey(type)) { + Set result = new HashSet<>(); + result.add(type); + result.addAll(inheritanceGraph.get(type).getContentOfDescendants()); + return result; + } + IUnify unify = new MartelliMontanariUnify(); - HashSet candidates = new HashSet<>(); - if (strInheritanceGraph.containsKey(type.getName())) - strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); - else - candidates.add(type); + Set result1 = new HashSet<>(); - for (Type theta2 : candidates) { - Optional sigma2 = unify.unify(theta2, type); - if (!sigma2.isPresent()) - continue; - Set theta1s = new HashSet<>(); - if(inheritanceGraph.containsKey(type)) - theta1s = inheritanceGraph.get(type).getContentOfDescendants(); - else if(theta2.equals(type)) - theta1s.add(type); - else - theta1s = smaller(theta2); - for (Type theta1 : theta1s) { - // Because only the most general type is calculated, sigma1 = - // sigma2 - Type sigma1Theta1 = sigma2.get().apply(theta1); - - ArrayList> paramCandidates = new ArrayList<>(); - for (Type param : sigma1Theta1.getTypeParams()) - paramCandidates.add(smArg(param)); - - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); - - for (TypeParams newParams : permResult) - result.add(sigma1Theta1.setTypeParams(newParams)); + // if T = T' then T <=* T' + result1.add(type); + + {ArrayList> paramCandidates = new ArrayList<>(); + for (Type param : type.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for (TypeParams newParams : permResult) + result1.add(type.setTypeParams(newParams));} + + Set result2 = new HashSet<>(); + if (strInheritanceGraph.containsKey(type.getName())) { + HashSet candidates = new HashSet<>(); + strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); + + for(Type typePrime : result1) { + for (Type theta2 : candidates) { + Optional sigma2 = unify.unify(typePrime, theta2); + if (!sigma2.isPresent()) + continue; + if(type.equals(theta2)) + continue; + Set theta1s = smaller(theta2); + for (Type theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + Type sigma1Theta1 = sigma2.get().apply(theta1); + result2.add(sigma1Theta1); + } + } } } - - return result; + else + result2 = result1; + + Set result3 = new HashSet<>(); + for(Type t : result2) { + ArrayList> paramCandidates = new ArrayList<>(); + for (Type param : t.getTypeParams()) + paramCandidates.add(smArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for (TypeParams newParams : permResult) + result3.add(t.setTypeParams(newParams)); + + } + + return result3; } /** @@ -260,19 +279,37 @@ public class FiniteClosure implements IFiniteClosure { return result; } + + public boolean isGenericType(Type t) { + if(t.getTypeParams().size() == 0) + return true; + + if(!strInheritanceGraph.containsKey(t.getName())) + return false; + + for(MPair pair : pairs) + if(pair.getLhsType().equals(t)) + return true; + + return false; + } + @Override - public Optional getGenericType(String typeName) { - if(!strInheritanceGraph.containsKey(typeName)) - return Optional.empty(); - - HashSet> candidates = strInheritanceGraph.get(typeName); - - for(Node node : candidates) { - Type candidate = node.getContent(); - if(candidate.getTypeParams().arePlaceholders()) - return Optional.of(candidate); + public Optional findGenericParent(String type) { + Type genericType = null; + for(MPair pair : pairs) { + Type lhs = pair.getLhsType(); + if(lhs.getName().equals(type)) { + genericType = lhs; + break; + } } + if(genericType == null) + return Optional.empty(); + + // TODO reduce reglen überarbeiten, es kann mehrere Typen D geben die eine bedingung + // erfüllen, diese methode ausimplementieren return Optional.empty(); } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java index 6ae0acf6..e3ae2322 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -101,8 +101,12 @@ public class MartelliMontanariUnify implements IUnify { TypeParams rhsTypeParams = rhs.getTypeParams(); TypeParams lhsTypeParams = lhs.getTypeParams(); - if(rhsTypeParams.size() != lhsTypeParams.size() || (!rhs.getName().equals(lhs.getName()) && rhsTypeParams.size() != 0)) - return null; // conflict + if(!(rhs instanceof PlaceholderType) && !(lhs instanceof PlaceholderType)) { + if(!rhs.getName().equals(lhs.getName())) + return null; // conflict + if(rhsTypeParams.size() != lhsTypeParams.size()) + return null; // conflict; + } if(rhsTypeParams.size() == 0 || lhsTypeParams.size() == 0) return Optional.empty(); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index f6b26ad9..bae13582 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -328,7 +328,7 @@ public class RuleSet implements IRuleSet{ if(typeD.getName().equals(typeDs.getName())) return Optional.empty(); - Optional opt = finiteClosure.getGenericType(typeD.getName()); + Optional opt = finiteClosure.findGenericParent(typeD.getName()); if(!opt.isPresent()) return Optional.empty(); @@ -373,9 +373,9 @@ public class RuleSet implements IRuleSet{ Type typeDgen; if(typeD instanceof SimpleType) - typeDgen = finiteClosure.getGenericType(typeD.getName()).orElse(null); + typeDgen = finiteClosure.findGenericParent(typeD.getName()).orElse(null); else { - Optional opt = finiteClosure.getGenericType(((ExtendsType) typeD).getExtendedType().getName()); + Optional opt = finiteClosure.findGenericParent(((ExtendsType) typeD).getExtendedType().getName()); typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null; } @@ -418,7 +418,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); - Optional opt = finiteClosure.getGenericType(((SuperType) typeSupD).getSuperedType().getName()); + Optional opt = finiteClosure.findGenericParent(((SuperType) typeSupD).getSuperedType().getName()); if(!opt.isPresent()) return Optional.empty(); @@ -462,13 +462,13 @@ public class RuleSet implements IRuleSet{ private int[] pi(Type C, Type D) { Type cFromFc = null; if(C instanceof SimpleType) - cFromFc = finiteClosure.getGenericType(C.getName()).orElse(null); + cFromFc = finiteClosure.findGenericParent(C.getName()).orElse(null); else if(C instanceof ExtendsType) { - Optional opt = finiteClosure.getGenericType(((ExtendsType) C).getExtendedType().getName()); + Optional opt = finiteClosure.findGenericParent(((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()); + Optional opt = finiteClosure.findGenericParent(((SuperType) C).getSuperedType().getName()); if(opt.isPresent()) cFromFc = new SuperType(opt.get()); } diff --git a/test/unify/FiniteClosureBuilder.java b/test/unify/FiniteClosureBuilder.java index 5a639b38..f4ea2133 100644 --- a/test/unify/FiniteClosureBuilder.java +++ b/test/unify/FiniteClosureBuilder.java @@ -33,7 +33,8 @@ public class FiniteClosureBuilder { Type collection = tf.getSimpleType("Collection"); Type set = tf.getSimpleType("Set", "T"); - Type sortedSet = tf.getSimpleType("Set", "T"); + //Type sortedSet = tf.getSimpleType("SortedSet", "T"); Sorted set bei den Unit-Tests vergessen + // nachträgliches einfügen zu aufwendig Type TreeSet = tf.getSimpleType("TreeSet", "T"); Type hashSet = tf.getSimpleType("HashSet", "T"); Type linkedHashSet = tf.getSimpleType("LinkedHashSet", "T"); @@ -46,8 +47,8 @@ public class FiniteClosureBuilder { Type arrayList = tf.getSimpleType("ArrayList", "T"); add(set, collection); - add(sortedSet, set); - add(TreeSet, sortedSet); + //add(sortedSet, set); + add(TreeSet, set); add(hashSet, set); add(linkedHashSet, set); @@ -67,7 +68,7 @@ public class FiniteClosureBuilder { Type treeMap = tf.getSimpleType("TreeMap", "K", "V"); Type hashMap = tf.getSimpleType("HashMap", "K", "V"); Type hashtable = tf.getSimpleType("Hashtable", "K", "V"); - Type linkedHashMap = tf.getSimpleType("LinkedHashSet", "K", "V"); + Type linkedHashMap = tf.getSimpleType("LinkedHashMap", "K", "V"); add(sortedMap, map); add(hashMap, map); diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index d3766e74..a8a72273 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -251,37 +251,91 @@ public class FiniteClosureTest { /* * Test Case 10: * - * smaller(HashMap) = - * { HashMap, HashMap, HashMap, HashMap - * HashMap, HashMap, HashMap, HashMap, - * HashMap, HashMap, HashMap - * HashMap, HashMap, HashMap, HashMap } + * smaller(TreeMap) = + * { TreeMap, TreeMap, TreeMap, TreeMap + * TreeMap, TreeMap, TreeMap, TreeMap, + * TreeMap, TreeMap, TreeMap + * TreeMap, TreeMap, TreeMap, TreeMap } */ + Type treeMapExtNumSupInt = tf.getSimpleType("TreeMap", extNum, superInt); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + treeMapExtNumSupInt, tf.getSimpleType("TreeMap", extNum, superNum), tf.getSimpleType("TreeMap", extNum, integer), tf.getSimpleType("TreeMap", extNum, number), + tf.getSimpleType("TreeMap", number, superInt), tf.getSimpleType("TreeMap", number, superNum), tf.getSimpleType("TreeMap", number, integer), tf.getSimpleType("TreeMap", number, number), + tf.getSimpleType("TreeMap", integer, superInt), tf.getSimpleType("TreeMap", integer, superNum), tf.getSimpleType("TreeMap", integer, integer), tf.getSimpleType("TreeMap", integer, number), + tf.getSimpleType("TreeMap", extInt, superInt), tf.getSimpleType("TreeMap", extInt, superNum), tf.getSimpleType("TreeMap", extInt, integer), tf.getSimpleType("TreeMap", extInt, number) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapExtNumSupInt); + Assert.assertEquals(expectedResult, actual); + /* * Test Case 11: * * smaller(SortedMap) = { SortedMap, NavigableMap, TreeMap } */ + Type sortedMapNumberT = tf.getSimpleType("SortedMap", number, t); + Type navigableMapNumberT = tf.getSimpleType("NavigableMap", number, t); + Type treeMapNumberT = tf.getSimpleType("TreeMap", number, t); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedMapNumberT, navigableMapNumberT, treeMapNumberT + }).collect(Collectors.toSet())); + + actual = fc.smaller(sortedMapNumberT); + Assert.assertEquals(expectedResult, actual); + /* * Test Case 12: * - * MyMap> <* HashMap + * MyMap <* TreeMap> * - * smaller(HashMap) = { HashMap>, MyMap> } + * smaller(TreeMap) = { TreeMap>, MyMap } */ + fcb = new FiniteClosureBuilder(); + Type k = tf.getPlaceholderType("K"); + Type myMap = tf.getSimpleType("MyMap", k); + fcb.add(myMap, tf.getSimpleType("TreeMap", k, tf.getSimpleType("List", k))); + fcb.add(integer, number); + fc = fcb.getCollectionExample(); + + Type treeMapNumberListNumber = tf.getSimpleType("TreeMap", number, tf.getSimpleType("List", number)); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + treeMapNumberListNumber, + tf.getSimpleType("MyMap", number) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapNumberListNumber); + Assert.assertEquals(expectedResult, actual); + /* * Test Case 13: * - * MyMap> <* HashMap + * MyMap <* TreeMap> * - * smaller(HashMap) = - * { HashMap, List>, - * HashMap>, - * MyMap> } + * smaller(TreeMap) = + * { TreeMap, List>, + * TreeMap>, + * TreeMap>, + * TreeMap>, + * MyMap } */ + + Type listInteger = tf.getSimpleType("List", integer); + Type treeMapExtNumberListInteger = tf.getSimpleType("TreeMap", extNum, listInteger); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + treeMapExtNumberListInteger, + tf.getSimpleType("TreeMap", extInt, listInteger), + tf.getSimpleType("TreeMap", number, listInteger), + tf.getSimpleType("TreeMap", integer, listInteger), + tf.getSimpleType("MyMap", integer) + }).collect(Collectors.toSet())); + + actual = fc.smaller(treeMapExtNumberListInteger); + Assert.assertEquals(expectedResult, actual); /* * Test Case 14 @@ -292,7 +346,7 @@ public class FiniteClosureTest { */ /* - * Test Case 13: + * Test Case 15: * * MyMap> <* HashMap // * TODO sinnvoll ausformulieren @@ -350,4 +404,12 @@ public class FiniteClosureTest { // TODO } + + private void printDiff(Set expected, Set actual) { + System.out.println("Diff:"); + System.out.println("In expected but not in actual:"); + Set expected1 = new HashSet<>(expected); + expected1.removeAll(actual); + System.out.println(expected1); + } } From de607cfd53c332a00e13dc88f81f8254161795bb Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 01:19:57 +0200 Subject: [PATCH 10/14] noch ein smaller test --- test/unify/FiniteClosureTest.java | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index a8a72273..7c422bda 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -340,17 +340,44 @@ public class FiniteClosureTest { /* * Test Case 14 * - * MyMap> <* HashMap + * MyMap <* TreeMap> * - * smaller(HashMap) = + * smaller(TreeMap) = + * { TreeMap, List>, + * TreeMap>, + * TreeMap>, + * TreeMap>, + * MyMap + * MyMap + * MyMap + * MyMap */ + Type listExtNum = tf.getSimpleType("List", extNum); + Type treeMapExtNumListExtNum = tf.getSimpleType("TreeMap", extNum, listExtNum); + Type myMapInt = tf.getSimpleType("MyMap", integer); + Type myMapNumber = tf.getSimpleType("MyMap", number); + Type myMapExtInt = tf.getSimpleType("MyMap", extInt); + Type myMapExtNum = tf.getSimpleType("MyMap", extNum); + + actual = fc.smaller(treeMapExtNumListExtNum); + + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + tf.getSimpleType("TreeMap", extNum, listExtNum), + tf.getSimpleType("TreeMap", extInt, listExtNum), + tf.getSimpleType("TreeMap", number, listExtNum), + tf.getSimpleType("TreeMap", integer, listExtNum), + myMapInt, myMapNumber, myMapExtInt, myMapExtNum + }).collect(Collectors.toSet())); + + Assert.assertEquals(expectedResult, actual); + /* * Test Case 15: * - * MyMap> <* HashMap -// * TODO sinnvoll ausformulieren - * smaller(HashMap) = + * MyMap <* HashMap> + * + * smaller(SortedSet) = * { HashMap, List>, * HashMap>, * MyMap> } From 67e1c5c7367c3db24c268a255ffe6f68d2352b3c Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 01:26:53 +0200 Subject: [PATCH 11/14] 15ter testcase --- test/unify/FiniteClosureTest.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 7c422bda..d1f99d60 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -377,11 +377,20 @@ public class FiniteClosureTest { * * MyMap <* HashMap> * - * smaller(SortedSet) = - * { HashMap, List>, - * HashMap>, - * MyMap> } + * smaller(NavigableSet>) = + * { NavigableSet>, + * NavigableSet> + * NavigableSet> + * NavigableSet> + * TreeSet>, + * TreeSet> + * TreeSet> + * TreeSet> } */ + + Type navSet = tf.getSimpleType("NavigableSet", extInt, tf.getExtendsType(tf.getSimpleType("ArrayList", extInt))); + + Assert.assertEquals(8, fc.smaller(navSet).size()); } @Test From ac3ce7d2147973ae5db41e3b8420c238dd5e0c4f Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 11:40:21 +0200 Subject: [PATCH 12/14] smaller --- .../unify/model/FiniteClosure.java | 9 +++++-- test/unify/FiniteClosureTest.java | 24 +++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 4a331353..1c45680b 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -122,8 +122,13 @@ public class FiniteClosure implements IFiniteClosure { Set permResult = new HashSet<>(); permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); - for (TypeParams newParams : permResult) - result3.add(t.setTypeParams(newParams)); + for (TypeParams newParams : permResult) { + Type tPrime = t.setTypeParams(newParams); + if(tPrime.equals(t)) + result3.add(t); + else + result3.addAll(smaller(tPrime)); + } } diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index d1f99d60..33ba1d0a 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -375,22 +375,22 @@ public class FiniteClosureTest { /* * Test Case 15: * - * MyMap <* HashMap> + * MyMap <* TreeMap> * - * smaller(NavigableSet>) = - * { NavigableSet>, - * NavigableSet> - * NavigableSet> - * NavigableSet> - * TreeSet>, - * TreeSet> - * TreeSet> - * TreeSet> } + * smaller(NavigableSet>) = + * { Permutationen der List, + * Permutationen der List in TreeSets, + * MyMap und MyMap + * } */ - Type navSet = tf.getSimpleType("NavigableSet", extInt, tf.getExtendsType(tf.getSimpleType("ArrayList", extInt))); + Type navSet = tf.getSimpleType("NavigableMap", extInt, tf.getExtendsType(tf.getSimpleType("List", extInt))); - Assert.assertEquals(8, fc.smaller(navSet).size()); + actual = fc.smaller(navSet); + + Assert.assertEquals(82, actual.size()); + Assert.assertTrue(actual.contains(myMapExtInt)); + Assert.assertTrue(actual.contains(myMapInt)); } @Test From 332dd57de3fe79dfb4fde48ceed17f4ed4632f0a Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 15:00:34 +0200 Subject: [PATCH 13/14] greater und testy --- .../unify/model/FiniteClosure.java | 83 ++++-- test/unify/FiniteClosureTest.java | 241 +++++++++++++++++- 2 files changed, 291 insertions(+), 33 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 1c45680b..4bbcde0b 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -140,32 +140,71 @@ public class FiniteClosure implements IFiniteClosure { * @return The set of supertypes of the argument. */ @Override - public Set greater(Type type) { - Set result = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfPredecessors() : new HashSet<>(); - result.add(type); - - if(type.getTypeParams().size() == 0) - return result; + public Set greater(Type type) { + IUnify unify = new MartelliMontanariUnify(); + Set result1 = new HashSet<>(); - ArrayList> paramCandidates = new ArrayList<>(); - for(Type param : type.getTypeParams()) { - if(param instanceof ExtendsType || param instanceof SuperType) { - Set pc = param.grArg(this); - paramCandidates.add(pc); - } else { - HashSet pc = new HashSet<>(); - pc.add(param); - paramCandidates.add(pc); + if(inheritanceGraph.containsKey(type)) + result1.addAll(inheritanceGraph.get(type).getContentOfPredecessors()); + + // if T = T' then T <=* T' + result1.add(type); + + {ArrayList> paramCandidates = new ArrayList<>(); + for (Type param : type.getTypeParams()) + paramCandidates.add(grArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for (TypeParams newParams : permResult) + result1.add(type.setTypeParams(newParams));} + + Set result2 = new HashSet<>(); + if (strInheritanceGraph.containsKey(type.getName()) && !inheritanceGraph.containsKey(type)) { + HashSet candidates = new HashSet<>(); + strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); + + for(Type typePrime : result1) { + for (Type theta2 : candidates) { + Optional sigma2 = unify.unify(typePrime, theta2); + if (!sigma2.isPresent()) + continue; + if(type.equals(theta2)) + continue; + Set theta1s = greater(theta2); + for (Type theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + Type sigma1Theta1 = sigma2.get().apply(theta1); + result2.add(sigma1Theta1); + } + } } } - Set permResult = new HashSet<>(); - permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + result2.addAll(result1); - for(TypeParams newParams : permResult) - result.add(type.setTypeParams(newParams)); + Set result3 = new HashSet<>(); + for(Type t : result2) { + ArrayList> paramCandidates = new ArrayList<>(); + for (Type param : t.getTypeParams()) + paramCandidates.add(grArg(param)); + + Set permResult = new HashSet<>(); + permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]); + + for (TypeParams newParams : permResult) { + Type tPrime = t.setTypeParams(newParams); + if(tPrime.equals(t)) + result3.add(t); + else + result3.addAll(greater(tPrime)); + } + + } + + return result3; - return result; } @Override @@ -217,8 +256,8 @@ public class FiniteClosure implements IFiniteClosure { public Set grArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - result.add(new SuperType(type)); - result.add(new ExtendsType(type)); + //result.add(new SuperType(type)); + //result.add(new ExtendsType(type)); return result; } diff --git a/test/unify/FiniteClosureTest.java b/test/unify/FiniteClosureTest.java index 33ba1d0a..7322e857 100644 --- a/test/unify/FiniteClosureTest.java +++ b/test/unify/FiniteClosureTest.java @@ -2,6 +2,7 @@ package unify; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -397,19 +398,237 @@ public class FiniteClosureTest { public void testGreater() { TypeFactory tf = new TypeFactory(); FiniteClosureBuilder fcb = new FiniteClosureBuilder(); - fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number")); - fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer"))); - fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection")); + Type k = tf.getPlaceholderType("K"); + Type integer = tf.getSimpleType("Integer"); + Type number = tf.getSimpleType("Number"); + Type myMap = tf.getSimpleType("MyMap", k); + Type myIntMap = tf.getSimpleType("MyIntMap"); + Type collection = tf.getSimpleType("Collection"); + Type sortedSet =tf.getSimpleType("SortedSet", "T"); + Type extInt = tf.getExtendsType(integer); + Type extNum = tf.getExtendsType(number); + Type supInt = tf.getSuperType(integer); + Type supNum = tf.getSuperType(number); + fcb.add(myMap, tf.getSimpleType("Map", k, tf.getSimpleType("List", k))); + fcb.add(myIntMap, tf.getSimpleType("MyMap", integer)); + fcb.add(sortedSet, tf.getSimpleType("Set", "T")); // sortedSet < Set missing in collection example + fcb.add(integer, number); IFiniteClosure fc = fcb.getCollectionExample(); - 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"))); - System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Integer")))); - System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Number")))); - System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getExtendsType(tf.getSimpleType("Integer"))))); - System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSuperType(tf.getSimpleType("Integer"))))); + /* + * Test Case 1: + * + * greater(SortedSet) = + * { SortedSet, Set, Collection + * SortedSet, SortedSet, SortedSet, + * Set, Set, Set } + */ + + Type sortedSetInteger = tf.getSimpleType("SortedSet", integer); + Set expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetInteger, tf.getSimpleType("Set", integer), collection, + tf.getSimpleType("SortedSet", extInt), tf.getSimpleType("SortedSet", supInt), + tf.getSimpleType("SortedSet", extNum), tf.getSimpleType("Set", extInt), + tf.getSimpleType("Set", supInt), tf.getSimpleType("Set", extNum) + }).collect(Collectors.toSet())); + + Set actual = fc.greater(sortedSetInteger); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 2: + * + * greater(SortedSet) = + * { SortedSet, SortedSet, + * Set, Set, Collection } + */ + + Type sortedSetExtInt = tf.getSimpleType("SortedSet", extInt); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetExtInt, tf.getSimpleType("SortedSet", extNum), collection, + tf.getSimpleType("Set", extInt), tf.getSimpleType("Set", extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetExtInt); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 3: + * + * TODO hier extends und super? (siehe test case 4 bei smaller) + * greater(SortedSet) = + * { SortedSet, SortedSet, SortedSet, + * Set, Set, Set, Collection } + */ + + /* + * Test Case 4: + * + * greater(SortedSet) = + * { SortedSet, SortedSet + * Set, Set, Collection } + */ + + Type sortedSetSupNum = tf.getSimpleType("SortedSet", supNum); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetSupNum, tf.getSimpleType("SortedSet", supInt), collection, + tf.getSimpleType("Set", supNum), tf.getSimpleType("Set", supInt) + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetSupNum); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 5: + * + * TODO nicht unifizierbar bei T wenn Set deklariert wurde. Können die beiden T's verschieden sein? + * greater(SortedSet) = + * { SortedSet, Set, Collection } + */ + + Type extT = tf.getExtendsType(tf.getPlaceholderType("T1")); + Type sortedSetExtT = tf.getSimpleType("SortedSet", extT); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetExtT, tf.getSimpleType("Set", extT), collection, + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetExtT); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 6: + * + * greater(SortedSet) = + * { SortedSet, SortedSet, SortedSet, + * Set, Set, Set, Collection } + */ + + Type notInFc = tf.getSimpleType("NotInFc"); + Type extNotInFc = tf.getExtendsType(notInFc); + Type supNotInFc = tf.getSuperType(notInFc); + Type sortedSetNotInFc= tf.getSimpleType("SortedSet", notInFc); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetNotInFc, tf.getSimpleType("SortedSet", extNotInFc), tf.getSimpleType("SortedSet", supNotInFc), + tf.getSimpleType("Set", notInFc), tf.getSimpleType("Set", extNotInFc), tf.getSimpleType("Set", supNotInFc), + collection + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 7: + * + * greater(SortedSet, Set, Collection } + */ + + Type sortedSetSupNotInFc= tf.getSimpleType("SortedSet", supNotInFc); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + sortedSetSupNotInFc, tf.getSimpleType("Set", supNotInFc), collection + }).collect(Collectors.toSet())); + + actual = fc.greater(sortedSetSupNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 8: + * + * greater(NotInFc) = + * { NotInFc, NotInFc, NotInFC, + * NotInFc } + */ + + Type notInFcInteger = tf.getSimpleType("NotInFc", integer); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + notInFcInteger, tf.getSimpleType("NotInFc", supInt), + tf.getSimpleType("NotInFc", extInt), tf.getSimpleType("NotInFc", extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(notInFcInteger); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 9: + * greater(NotInFc) = + * { NotInFc, NotInFc } + */ + + Type notInFcAlsoNotInFc = tf.getSimpleType("NotInFc", tf.getSimpleType("AlsoNotInFc")); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + notInFcAlsoNotInFc, tf.getSimpleType("NotInFc", tf.getExtendsType(tf.getSimpleType("AlsoNotInFc"))), + tf.getSimpleType("NotInFc", tf.getSuperType(tf.getSimpleType("AlsoNotInFc"))) + }).collect(Collectors.toSet())); + + actual = fc.greater(notInFcAlsoNotInFc); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 10: + * greater(Map) = + * { Map, Map, + * Map, Map, + * Map, Map, + * Map, Map } + */ + + Type mapExtIntInt = tf.getSimpleType("Map", extInt, integer); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + mapExtIntInt, tf.getSimpleType("Map", extInt, extInt), + tf.getSimpleType("Map", extInt, supInt), tf.getSimpleType("Map", extInt, extNum), + tf.getSimpleType("Map", extNum, integer), tf.getSimpleType("Map", extNum, extInt), + tf.getSimpleType("Map", extNum, supInt), tf.getSimpleType("Map", extNum, extNum) + }).collect(Collectors.toSet())); + + actual = fc.greater(mapExtIntInt); + Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 11: + * + * MyIntMap < MyMap + * MyMap < Map> + * + * greater(MyIntMap) = + * { MyMap, MyMap, MyMap, MyMap, + * Map, Map, List, + * Map, List, Map, MyIntMap } + */ + + Type listInteger = tf.getSimpleType("List", integer); + expectedResult = new HashSet<>(Arrays.stream(new Type[] { + myIntMap, tf.getSimpleType("MyMap", integer), tf.getSimpleType("MyMap", extInt), + tf.getSimpleType("MyMap", extNum), tf.getSimpleType("MyMap", supInt), + tf.getSimpleType("Map", integer, listInteger), tf.getSimpleType("Map", extInt, listInteger), + tf.getSimpleType("MyMap", extNum, listInteger), tf.getSimpleType("MyMap", supInt, listInteger) + }).collect(Collectors.toSet())); + + actual = fc.greater(myIntMap); + //Assert.assertEquals(expectedResult, actual); + + /* + * Test Case 12: + * + * MyIntMap < MyMap + * MyMap < Map> + * + * TODO + * D d = null; + * A> a = null; + * a = d; ist nicht möglich! + * + * greater(MyMap) = + * { MyMap, MyMap, + * Map>, + * Map, List> } + */ + + /* + * Test Case 13: + * + * greater(SortedMap, ? super List>) = + * + */ } @Test From 639ac8430ce2accca03597aa8c70492ae8e09fb2 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Mon, 28 Mar 2016 20:56:24 +0200 Subject: [PATCH 14/14] adapted adaptRules --- .../unify/interfaces/IFiniteClosure.java | 4 +- .../unify/model/FiniteClosure.java | 43 +++++---- .../typeinference/unifynew/RuleSet.java | 88 ++++++++----------- 3 files changed, 59 insertions(+), 76 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java index 00c12f65..d2c6f0f4 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java @@ -53,6 +53,8 @@ public interface IFiniteClosure { public Set grArg(FunNType type); public Set smArg(FunNType type); - public Optional findGenericParent(String typeName); + public Optional getLeftHandedType(Type t); + public Set getAncestors(Type t); + public Set getAllTypesByName(String typeName); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 4bbcde0b..9e1b8808 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -271,8 +272,6 @@ public class FiniteClosure implements IFiniteClosure { Set result = new HashSet(); result.add(type); - // smaller(type).forEach(x -> result.add(new ExtendsType(x))); TODO inkorrekt? daher erstmal raus - return result; } @@ -318,8 +317,6 @@ public class FiniteClosure implements IFiniteClosure { public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - //result.add(new SuperType(type)); TODO inkorrekt, daher erstmal raus - //result.add(new ExtendsType(type)); return result; } @@ -337,25 +334,6 @@ public class FiniteClosure implements IFiniteClosure { return false; } - - @Override - public Optional findGenericParent(String type) { - Type genericType = null; - for(MPair pair : pairs) { - Type lhs = pair.getLhsType(); - if(lhs.getName().equals(type)) { - genericType = lhs; - break; - } - } - - if(genericType == null) - return Optional.empty(); - - // TODO reduce reglen überarbeiten, es kann mehrere Typen D geben die eine bedingung - // erfüllen, diese methode ausimplementieren - return Optional.empty(); - } @Override public Set getAllTypesByName(String typeName) { @@ -364,6 +342,25 @@ public class FiniteClosure implements IFiniteClosure { return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } + @Override + public Optional getLeftHandedType(Type t) { + if(!strInheritanceGraph.containsKey(t.getName())) + return Optional.empty(); + + for(MPair pair : pairs) + if(pair.getLhsType().getName().equals(t.getName())) + return Optional.of(pair.getLhsType()); + + return Optional.empty(); + } + + @Override + public Set getAncestors(Type t) { + if(!inheritanceGraph.containsKey(t)) + return new HashSet<>(); + return inheritanceGraph.get(t).getContentOfPredecessors(); + } + protected void permuteParams(ArrayList> candidates, int idx, Set result, Type[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index bae13582..672c104d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -85,26 +85,26 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() != PairOperator.SMALLERDOTWC) return Optional.empty(); - Type lhsType = pair.getLhsType(); + Type x = pair.getLhsType(); - if(!(lhsType instanceof SimpleType) && !(lhsType instanceof ExtendsType)) + if(!(x instanceof SimpleType) && !(x instanceof ExtendsType)) return Optional.empty(); - Type rhsType = pair.getRhsType(); + Type extY = pair.getRhsType(); - if(!(rhsType instanceof ExtendsType)) + if(!(extY instanceof ExtendsType)) return Optional.empty(); - if(lhsType.getTypeParams().empty() || rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) + if(x.getTypeParams().empty() || extY.getTypeParams().size() != x.getTypeParams().size()) return Optional.empty(); - int[] pi = pi(lhsType, rhsType); + int[] pi = pi(x, extY); if(pi.length == 0) return Optional.empty(); - TypeParams rhsTypeParams = rhsType.getTypeParams(); - TypeParams lhsTypeParams = lhsType.getTypeParams(); + TypeParams rhsTypeParams = extY.getTypeParams(); + TypeParams lhsTypeParams = x.getTypeParams(); Set result = new HashSet<>(); for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) @@ -160,7 +160,7 @@ public class RuleSet implements IRuleSet{ if(!rhsType.getName().equals(lhsType.getName())) return Optional.empty(); - if(rhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) + if(rhsType instanceof PlaceholderType || lhsType instanceof PlaceholderType || rhsType.getTypeParams().empty()) return Optional.empty(); if(rhsType.getTypeParams().size() != lhsType.getTypeParams().size()) @@ -328,16 +328,16 @@ public class RuleSet implements IRuleSet{ if(typeD.getName().equals(typeDs.getName())) return Optional.empty(); - Optional opt = finiteClosure.findGenericParent(typeD.getName()); + Optional opt = finiteClosure.getLeftHandedType(typeD); if(!opt.isPresent()) return Optional.empty(); // 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); + Set greater = finiteClosure.getAncestors(typeDgen); opt = greater.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); if(!opt.isPresent()) @@ -350,7 +350,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); } @@ -373,9 +373,9 @@ public class RuleSet implements IRuleSet{ Type typeDgen; if(typeD instanceof SimpleType) - typeDgen = finiteClosure.findGenericParent(typeD.getName()).orElse(null); + typeDgen = finiteClosure.getLeftHandedType(typeD).orElse(null); else { - Optional opt = finiteClosure.findGenericParent(((ExtendsType) typeD).getExtendedType().getName()); + Optional opt = finiteClosure.getLeftHandedType(((ExtendsType) typeD).getExtendedType()); typeDgen = opt.isPresent() ? new ExtendsType(opt.get()) : null; } @@ -396,7 +396,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeDgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC)); } @@ -418,7 +418,7 @@ public class RuleSet implements IRuleSet{ return Optional.empty(); - Optional opt = finiteClosure.findGenericParent(((SuperType) typeSupD).getSuperedType().getName()); + Optional opt = finiteClosure.getLeftHandedType(((SuperType) typeSupD).getSuperedType()); if(!opt.isPresent()) return Optional.empty(); @@ -448,7 +448,7 @@ public class RuleSet implements IRuleSet{ Unifier unif = new Unifier((PlaceholderType) typeSupDsgenParams.get(0), typeDParams.get(0)); for(int i = 1; i < typeDParams.size(); i++) - unif.andThen(new Unifier((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i))); + unif.Add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); return Optional.of(new MPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC)); } @@ -460,43 +460,27 @@ 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 = null; - if(C instanceof SimpleType) - cFromFc = finiteClosure.findGenericParent(C.getName()).orElse(null); - else if(C instanceof ExtendsType) { - Optional opt = finiteClosure.findGenericParent(((ExtendsType) C).getExtendedType().getName()); - if(opt.isPresent()) cFromFc = new ExtendsType(opt.get()); - } - else if(C instanceof SuperType) { - Optional opt = finiteClosure.findGenericParent(((SuperType) C).getSuperedType().getName()); - if(opt.isPresent()) cFromFc = new SuperType(opt.get()); - } + String simpleTypeDName = D.getName(); + if(D instanceof ExtendsType) + simpleTypeDName = ((ExtendsType) D).getExtendedType().getName(); + else if(D instanceof SuperType) + simpleTypeDName = ((SuperType) D).getSuperedType().getName(); - if(cFromFc == null) + String simpleTypeCName = C.getName(); + if(C instanceof ExtendsType) + simpleTypeCName = ((ExtendsType) C).getExtendedType().getName(); + if(C instanceof SuperType) + simpleTypeCName = ((SuperType) C).getSuperedType().getName(); + + Optional typesFromFc = Optional.empty(); //TODO reduce regeln + //finiteClosure.findCandD(simpleTypeCName, simpleTypeDName); + + if(typesFromFc == null) return new int[0]; - 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().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().getName().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 dFromFc = opt.get(); - + Type cFromFc = typesFromFc.get()[0]; + Type dFromFc = typesFromFc.get()[1]; + Assert.assertEquals(cFromFc.getTypeParams().size(), dFromFc.getTypeParams().size()); Assert.assertTrue(dFromFc.getTypeParams().size() > 0);