diff --git a/notizen/stf/Notes b/notizen/stf/Notes index 515019a7e..ddca19bee 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 0dd264a52..7c020817d 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 eb23e17f7..5fdb53d34 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 d0c6e2726..bbf6a3bfc 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 5d326b47b..6509060c1 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 0ef52ee49..ea32f9a75 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 72ac18390..201dc80dd 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