From 1e968111278c66d214c4298473e5ee62dad8e9b8 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Tue, 12 Apr 2016 10:54:17 +0200 Subject: [PATCH] refactoring and commenting --- .../unify/MartelliMontanariUnify.java | 6 +- .../typeinference/unify/RuleSet.java | 8 +-- .../typeinference/unify/Unify.java | 2 +- .../unify/model/FiniteClosure.java | 15 ----- .../typeinference/unify/model/Unifier.java | 63 +++++++++++++++---- 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java index ae0172354..45e52133e 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java @@ -25,7 +25,7 @@ public class MartelliMontanariUnify implements IUnify { public Optional unify(Set terms) { // Sets with less than 2 terms are trivially unified if(terms.size() < 2) - return Optional.of(Unifier.Identity()); + return Optional.of(Unifier.identity()); // For the the set of terms {t1,...,tn}, // build a list of equations {(t1 = t2), (t2 = t3), (t3 = t4), ....} @@ -39,7 +39,7 @@ public class MartelliMontanariUnify implements IUnify { } // Start with the identity unifier. Substitutions will be added later. - Unifier mgu = Unifier.Identity(); + Unifier mgu = Unifier.identity(); // Apply rules while possible int idx = 0; @@ -91,7 +91,7 @@ public class MartelliMontanariUnify implements IUnify { // SUBST - Rule if(lhsType instanceof PlaceholderType) { - mgu.Add((PlaceholderType) lhsType, rhsType); + mgu.add((PlaceholderType) lhsType, rhsType); termsList = termsList.stream().map(mgu::apply).collect(Collectors.toCollection(ArrayList::new)); idx = idx+1 == termsList.size() ? 0 : idx+1; continue; diff --git a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java index 82ee96832..8fb5ddf25 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/RuleSet.java @@ -417,9 +417,9 @@ public class RuleSet implements IRuleSet{ TypeParams typeDParams = typeD.getTypeParams(); TypeParams typeDgenParams = typeDgen.getTypeParams(); - Unifier unif = Unifier.Identity(); + Unifier unif = Unifier.identity(); for(int i = 0; i < typeDParams.size(); i++) - unif.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); + unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); } @@ -465,7 +465,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.Add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); + unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC)); } @@ -517,7 +517,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.Add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); + unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC)); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index 0d2014b99..0bb0723fa 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -377,7 +377,7 @@ public class Unify { Unifier unifier = opt.get(); unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams().toArray()); Set substitutionSet = new HashSet<>(); - for (Entry sigma : unifier.getSubstitutions()) + for (Entry sigma : unifier) substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT)); List freshTphs = new ArrayList<>(); diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index f06fead70..fd946eb0b 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -372,21 +372,6 @@ public class FiniteClosure implements IFiniteClosure { return result; } - - public boolean isGenericType(UnifyType t) { - if(t.getTypeParams().size() == 0) - return true; - - if(!strInheritanceGraph.containsKey(t.getName())) - return false; - - for(UnifyPair pair : pairs) - if(pair.getLhsType().equals(t)) - return true; - - return false; - } - @Override public Set getAllTypesByName(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index f5af52d03..61302430a 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -1,15 +1,26 @@ package de.dhbwstuttgart.typeinference.unify.model; import java.util.HashMap; +import java.util.Iterator; import java.util.Map.Entry; -import java.util.Set; import java.util.function.Function; - -public class Unifier implements Function /*, Set*/ { // TODO set implementieren +/** + * A set of substitutions (s -> t) that is an applicable function to types and pairs. + * @author Florian Steurer + */ +public class Unifier implements Function, Iterable> { + + /** + * The set of substitutions that unify a type-term + */ private HashMap substitutions = new HashMap<>(); - + /** + * Creates a new instance with a single substitution (source -> target). + * @param The type that is replaced + * @param The type that replaces + */ public Unifier(PlaceholderType source, UnifyType target) { substitutions.put(source, target); } @@ -20,13 +31,23 @@ public class Unifier implements Function /*, Set*/ protected Unifier() { } - - public static Unifier Identity() { + + /** + * Creates an unifier that is the identity function (thus has no substitutions). + */ + public static Unifier identity() { return new Unifier(); } - public void Add(PlaceholderType source, UnifyType target) { + /** + * Adds a substitution to the unifier from (source -> target) + * @param The type that is replaced + * @param The type that replaces + */ + public void add(PlaceholderType source, UnifyType target) { Unifier tempU = new Unifier(source, target); + // Every new substitution must be applied to previously added substitutions + // otherwise the unifier needs to be applied multiple times to unify two terms for(PlaceholderType pt : substitutions.keySet()) substitutions.put(pt, substitutions.get(pt).apply(tempU)); substitutions.put(source, target); @@ -37,26 +58,39 @@ public class Unifier implements Function /*, Set*/ return t.apply(this); } + /** + * Applies the unifier to the two terms of the pair. + * @return A new pair where the left and right-hand side are applied + */ public UnifyPair apply(UnifyPair p) { return new UnifyPair(this.apply(p.getLhsType()), this.apply(p.getRhsType()), p.getPairOp()); } + /** + * True if the typevariable t will be substituted if the unifier is applied. + * false otherwise. + */ public boolean hasSubstitute(PlaceholderType t) { return substitutions.containsKey(t); } + /** + * Returns the type that will replace the typevariable t if the unifier is applied. + */ public UnifyType getSubstitute(PlaceholderType t) { return substitutions.get(t); } - - public Set> getSubstitutions() { - return substitutions.entrySet(); - } - + + /** + * Garantuees that if there is a substitutions (a -> b) in this unifier, + * a is not an element of the targetParams. Substitutions that do not + * satisfy this condition, are swapped. + */ public void swapPlaceholderSubstitutions(UnifyType... targetParams) { for(UnifyType tph : targetParams) { if(!(tph instanceof PlaceholderType)) continue; + // Swap a substitutions (a -> b) if a is an element of the target params. if(substitutions.containsKey(tph) && substitutions.get(tph) instanceof PlaceholderType) { PlaceholderType newLhs = (PlaceholderType) substitutions.get(tph); substitutions.remove(tph); @@ -75,5 +109,10 @@ public class Unifier implements Function /*, Set*/ result += " }"; return result; } + + @Override + public Iterator> iterator() { + return substitutions.entrySet().iterator(); + } }