From 039dd3b3f495011ce248c13e797fac9d29752dc4 Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Sat, 26 Dec 2015 18:49:11 +0100 Subject: [PATCH] step 5 and 6 implemented --- .../unify/interfaces/IRuleSet.java | 2 +- .../typeinference/unifynew/RuleSet.java | 30 ++++++++++------- .../typeinference/unifynew/Unify.java | 32 ++++++++++++------- test/unify/UnifyTest.java | 2 +- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java index 02611fd9..c997b4ff 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java @@ -27,5 +27,5 @@ public interface IRuleSet { public Optional adaptExt(MPair pair); public Optional adaptSup(MPair pair); - public Set subst(Set pair); + public Optional> subst(Set pair); } diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java index 6352aa07..c401be4a 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/RuleSet.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.unifynew; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -519,12 +520,24 @@ public class RuleSet implements IRuleSet{ } @Override - public Set subst(Set pairs) { - HashSet allTypes = new HashSet<>(); - pairs.forEach(x -> { allTypes.add(x.getLhsType()); allTypes.add(x.getRhsType()); }); + public Optional> subst(Set pairs) { + HashMap typeMap = new HashMap<>(); + + for(MPair pair : pairs) { + Type t1 = pair.getLhsType(); + Type t2 = pair.getRhsType(); + if(!typeMap.containsKey(t1)) + typeMap.put(t1, 0); + if(!typeMap.containsKey(t2)) + typeMap.put(t2, 0); + typeMap.put(t1, typeMap.get(t1)+1); + typeMap.put(t2, typeMap.get(t2)+1); + } Queue result = new LinkedList(pairs); + boolean applied = false; + for(int i = 0; i < result.size(); i++) { MPair pair = result.poll(); Type lhsType; @@ -532,21 +545,16 @@ public class RuleSet implements IRuleSet{ if(pair.getPairOp() == PairOperator.EQUALSDOT && ((lhsType = pair.getLhsType()) instanceof PlaceholderType) && !((rhsType = pair.getRhsType()) instanceof PlaceholderType) - && occursInSet(lhsType, allTypes) + && typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair. && !occurs(lhsType, rhsType)) { Unifier uni = new Unifier(lhsType, rhsType); result = result.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new)); + applied = true; } result.add(pair); } - return new HashSet<>(result); - } - - private boolean occursInSet(Type t, Set types) { - int origSize = types.size(); - types.add(t); - return types.size() == origSize; + return applied ? Optional.of(new HashSet<>(result)) : Optional.empty(); } private boolean occurs(Type t1, Type t2) { diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 3626fd05..49efd39d 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -30,7 +30,7 @@ import de.dhbwstuttgart.typinference.unify.model.Type; */ public class Unify { - public Menge> unify(Set eq, IFiniteClosure fc) { + public Set> unify(Set eq, IFiniteClosure fc) { /* * Step 1: Repeated application of reduce, adapt, erase, swap */ @@ -77,37 +77,47 @@ public class Unify { ISetOperations setOps = new GuavaSetOperations(); // Calculate the cartesian products - - - Set> result = setOps.cartesianProduct(sets).stream().map(x -> new HashSet(x)).collect(Collectors.toCollection(HashSet::new)); - - System.out.println(result); + Set> result = setOps.cartesianProduct(sets).stream() + .map(x -> new HashSet(x)).collect(Collectors.toCollection(HashSet::new)); + //System.out.println(result); /* * Step 5: Substitution */ - /* * TODO * Im Paper wird Eq'' genannt, es wird also von einer Menge in einer Menge in einer Menge ausgegangen. * Durch das flache Kartesische Produkt gibt es hier aber nur Mengen in Mengen. * Richtig so? */ - + IRuleSet rules = new RuleSet(fc); + Set> changed = new HashSet<>(); + Set> unchanged = new HashSet<>(); + + for(Set eqss : result) { + Optional> newEqss = rules.subst(eqss); + if(newEqss.isPresent()) + changed.add(newEqss.get()); + else + unchanged.add(eqss); + } /* - * Step 6: a) Restart for pairs where subst was applied - * b) Union over everything + * Step 6 a) Restart for pairs where subst was applied + * b) Build the union over everything */ + for(Set eqss : changed) + unchanged.addAll(this.unify(eqss, fc)); + /* * Step 7: Filter result for solved pairs */ - return null; + return unchanged; } diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index bab837df..356f6029 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -36,7 +36,7 @@ public class UnifyTest extends Unify { eq.add(new MPair(tf.getSimpleType("Double"), tf.getPlaceholderType("B"), PairOperator.SMALLERDOT)); //eq.add(new MPair(tf.getPlaceholderType("B"), tf.getSimpleType("Object"), PairOperator.EQUALSDOT)); - this.unify(eq, fc); + System.out.println(this.unify(eq, fc)); }