From b1febd7a50b63149235e6a57686a2e6c0fcc7b9d Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 13 Apr 2016 11:38:07 +0200 Subject: [PATCH] commenting refactoring --- .../typeinference/unify/Unify.java | 72 +++++++++++++++---- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index c1c81ed0..25c60984 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -32,21 +32,36 @@ import de.dhbwstuttgart.typeinference.unify.model.Unifier; */ public class Unify { + /** + * The implementation of setOps that will be used during the unification + */ protected ISetOperations setOps = new GuavaSetOperations(); + + /** + * The implementation of the standard unify that will be used during the unification + */ protected IUnify stdUnify = new MartelliMontanariUnify(); + + /** + * The implementation of the rules that will be used during the unification. + */ protected IRuleSet rules = new RuleSet(); + /** + * Computes all principal type unifiers for a set of constraints. + * @param eq The set of constraints + * @param fc The finite closure + * @return The set of all principal type unifiers + */ public Set> unify(Set eq, IFiniteClosure fc) { /* * Step 1: Repeated application of reduce, adapt, erase, swap */ - Set eq0 = applyTypeUnificationRules(eq, fc); /* * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs */ - Set eq1s = new HashSet<>(); Set eq2s = new HashSet<>(); splitEq(eq0, eq1s, eq2s); @@ -62,7 +77,7 @@ public class Unify { // cartesian product of the sets created by pattern matching. List>> topLevelSets = new ArrayList<>(); - if(eq1s.size() != 0) { + if(eq1s.size() != 0) { // Do not add empty sets or the cartesian product will always be empty. Set> wrap = new HashSet<>(); wrap.add(eq1s); topLevelSets.add(wrap); // Add Eq1' @@ -73,7 +88,7 @@ public class Unify { .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) .collect(Collectors.toSet()); - if(bufferSet.size() != 0) { + if(bufferSet.size() != 0) { // Do not add empty sets or the cartesian product will always be empty. Set> wrap = new HashSet<>(); wrap.add(bufferSet); topLevelSets.add(wrap); @@ -94,10 +109,12 @@ public class Unify { * filters for pairs and sets can be applied here */ // Sub cartesian products of the second level (pattern matched) sets + // "the big (x)" for(Set>> secondLevelSet : secondLevelSets) { List>> secondLevelSetList = new ArrayList<>(secondLevelSet); Set>> cartResult = setOps.cartesianProduct(secondLevelSetList); + // Flatten and add to top level sets Set> flat = new HashSet<>(); for(List> s : cartResult) { Set flat1 = new HashSet<>(); @@ -114,10 +131,7 @@ public class Unify { .collect(Collectors.toCollection(HashSet::new)); //System.out.println(result); - /* - * Step 5: Substitution - */ - + // Flatten the cartesian product Set> eqPrimeSetFlat = new HashSet<>(); for(Set> setToFlatten : eqPrimeSet) { Set buffer = new HashSet<>(); @@ -125,6 +139,10 @@ public class Unify { eqPrimeSetFlat.add(buffer); } + + /* + * Step 5: Substitution + */ Set> restartSet = new HashSet<>(); Set> eqPrimePrimeSet = new HashSet<>(); @@ -162,6 +180,11 @@ public class Unify { } + /** + * Checks whether a set of pairs is in solved form. + * @param eqPrimePrime The set of pair + * @return True if in solved form, false otherwise. + */ protected boolean isSolvedForm(Set eqPrimePrime) { for(UnifyPair pair : eqPrimePrime) { UnifyType lhsType = pair.getLhsType(); @@ -170,13 +193,18 @@ public class Unify { if(!(lhsType instanceof PlaceholderType)) return false; + // If operator is not equals, both sides must be placeholders if(pair.getPairOp() != PairOperator.EQUALSDOT && !(rhsType instanceof PlaceholderType)) return false; } - return true; } + /** + * Repeatedly applies type unification rules to a set of equations. + * This is step one of the unification algorithm. + * @return The set of pairs that results from repeated application of the inference rules. + */ protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { /* @@ -255,6 +283,12 @@ public class Unify { return targetSet; } + /** + * Applies the rule swap to a pair if possible. Then adds the pair to the set if no erase rule applies. + * If an erase rule applies, the pair is not added (erased). + * @param pair The pair to swap and add or erase. + * @param collection The collection to which the pairs are added. + */ protected void swapAddOrErase(UnifyPair pair, IFiniteClosure fc, Collection collection) { Optional opt = rules.swap(pair); UnifyPair pair2 = opt.isPresent() ? opt.get() : pair; @@ -265,6 +299,13 @@ public class Unify { collection.add(pair2); } + /** + * Splits the equation eq into a set eq1s where both terms are type variables, + * and a set eq2s where one of both terms is not a type variable. + * @param eq Set of pairs to be splitted. + * @param eq1s Subset of eq where both terms are type variables. + * @param eq2s eq/eq1s. + */ protected void splitEq(Set eq, Set eq1s, Set eq2s) { for(UnifyPair pair : eq) if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType) @@ -273,16 +314,21 @@ public class Unify { eq2s.add(pair); } - + /** + * Creates sets of pairs specified in the fourth step. Does not calculate cartesian products. + * @param undefined All pairs that did not match one of the 8 cases are added to this set. + * @return The set of the eight cases (without empty sets). Each case is a set, containing sets generated + * from the pairs that matched the case. Each generated set contains singleton sets or sets with few elements + * (as in case 1 where sigma is added to the innermost set). + */ protected Set>>> calculatePairSets(Set eq2s, IFiniteClosure fc, Set undefined) { - List>>> result = new ArrayList<>(); + List>>> result = new ArrayList<>(8); // Init all 8 cases for(int i = 0; i < 8; i++) result.add(new HashSet<>()); for(UnifyPair pair : eq2s) { - PairOperator pairOp = pair.getPairOp(); UnifyType lhsType = pair.getLhsType(); UnifyType rhsType = pair.getRhsType(); @@ -323,9 +369,9 @@ public class Unify { // Pairs that do not have one of the aboves form are contradictory. else undefined.add(pair); - } + // Filter empty sets or sets that only contain an empty set. return result.stream().map(x -> x.stream().filter(y -> y.size() > 0).collect(Collectors.toCollection(HashSet::new))) .filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new)); }