Bug in Simplify-Algo gefixt

This commit is contained in:
Fayez Abu Alia 2018-11-21 11:58:58 +01:00
parent a269ee9690
commit 7bfc222037
3 changed files with 120 additions and 21 deletions

View File

@ -16,7 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
// 1. check if there are any cycles like L<R and R<L:
// 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and:
// * remove both constraints
// * substitute L with R in all constraint
@ -28,8 +28,10 @@ public class Simplify {
// b) no
// 3. is
// all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
// step 1:
for(TPHConstraint c : allCons) {
@ -39,12 +41,16 @@ public class Simplify {
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
if(revCon != null) {
revCon.setRel(Relation.EQUAL);
// the reverse constraint is removed because
// otherwise there is twice the same constraint
// (e.g. A<B and B<A => A=B and B=A)
consToRemove.add(revCon);
c.setRel(Relation.EQUAL);
substituteTPH(allCons,left, right);
}
}
}
System.out.println();
System.out.println("NEW ALL CONST: " + allCons.size());
allCons.forEach(c->System.out.println(c.toString()));
@ -59,51 +65,75 @@ public class Simplify {
System.out.println("----------------");
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
// check if there is any long cycle (e.g. A<B<C<A)
// to save all types that are in relation
LinkedList<String> allTypes = new LinkedList<>();
// we will put all constraints which are in the cycle, in this ArrayList.
// Later these contraints will be converted to equal-constraints
ArrayList<TPHConstraint> constraints = new ArrayList<>(size);
int visited = 0;
// contains all constraints
HashMap<String,String> ss1 = new HashMap<>();
for(TPHConstraint constr : allCons) {
ss1.put(constr.getLeft(), constr.getRight());
}
for(TPHConstraint c : allCons) {
if(visited >= size)
break;
// Only extends-constraints will be checked
if(c.getRel() == Relation.EXTENDS) {
++visited;
String left = c.getLeft();
String right = c.getRight();
// put the types in linked list
allTypes.add(left);
allTypes.add(right);
constraints.add(c);
HashMap<String,String> ss1 = new HashMap<>();
for(TPHConstraint constr : allCons) {
ss1.put(constr.getLeft(), constr.getRight());
}
boolean isCycle = false;
boolean isCycle = false;
// iterate through the map to check if there is a cycle
while(ss1.containsKey(right)) {
++visited;
String oldRight = right;
right = ss1.get(right);
TPHConstraint toAdd = getConstraint(oldRight, right, allCons);
if(toAdd != null)
constraints.add(toAdd);
if(left.equals(right)) {
isCycle = true;
break;
}
allTypes.add(right);
}
if(isCycle) {
// convert all constraints to equal constraints
setAllEqual(constraints);
// these constraints will be removed from allCons
consToRemove.addAll(constraints);
// all equal types will be substitute with one type
substituteAllTPH(allCons,constraints,left);
HashSet<String> eq = new HashSet<>();
// put all equal types in a set
for(String t:allTypes) {
eq.add(t);
}
// generate a new constraint (left < Object)
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS);
// put the generated constraint and its equal set into result set
result.put(constraint, eq);
constraints.clear();
allTypes.clear();
@ -111,7 +141,10 @@ public class Simplify {
}
}
// build an equal set that contains all types
// which are equal and for each equal constraint put left side and right side
// in this set Then generate a constraint type < Object and put it
// with the equal set into the result.
for(TPHConstraint c : allCons) {
if(c.getRel()==Relation.EQUAL) {
if(!isTPHInResEqual(result, c.getLeft())) {
@ -125,6 +158,7 @@ public class Simplify {
size--;
}
}
System.out.println("Step 2 Result: ");
result.forEach((c,hs)->{
System.out.print(c.toString() + " -> ");
@ -134,7 +168,9 @@ public class Simplify {
System.out.println();
});
System.out.println("----------------");
// remove all equal-constraints
allCons.removeAll(consToRemove);
// add all generated constraints to allCons
allCons.addAll(result.keySet());
if(!allCons.isEmpty() && allCons.size()<2) {
@ -146,11 +182,13 @@ public class Simplify {
}
size += result.keySet().size();
// all constraints which have Object on the right side will
// be ignored, because they are simplified and can not be changed.
for(TPHConstraint c : allCons) {
if(c.getRight().equals(Type.getInternalName(Object.class)))
size--;
}
// get all tph of the method
ArrayList<String> methodTphs = new ArrayList<>();
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
if(m.getName().equals(name)) {
@ -158,7 +196,9 @@ public class Simplify {
break;
}
}
// check if there are multiple constraint with the same left side.
// if yes => check if the super type in the method, if not
// then ignore it.
HashMap<String, String> subAndSuper = new HashMap<>();
for(TPHConstraint c : allCons) {
if(subAndSuper.containsKey(c.getLeft())) {
@ -210,6 +250,8 @@ public class Simplify {
// Die größte Supertype
String superTphRes = tphInRel.getLast();
// if there is any constraint X < subTph, then
// add X at the beginning of the list.
while(subAndSuper.containsValue(subTphRes)) {
for(String tph : subAndSuper.keySet()) {
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
@ -220,12 +262,18 @@ public class Simplify {
if(subTphRes.equals(tphInRel.getFirst())) {
break;
}
if(isTPHInConstraint(result, subTphRes))
break;
tphInRel.addFirst(subTphRes);
numOfVisitedPairs++;
}
subTphRes = tphInRel.getFirst();
// if the last type in the list not a type in method-types
// then find the last type in front of this type, which is
// a type in method-types
int i = 2;
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
superTphRes = tphInRel.get(tphInRel.size()-i);
@ -236,7 +284,8 @@ public class Simplify {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
} else {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
if(!isTPHInConstraint(result, superTphRes))
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
}
}

View File

@ -2,14 +2,19 @@ package bytecode.simplifyalgo;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.HashSet;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
import de.dhbwstuttgart.typedeployment.TypeInsertPlacer;
/**
@ -22,6 +27,7 @@ public class SameLeftSide {
// private ist => Test geht nicht
private static TPHExtractor tphExtractor;
private static String methName;
private static String methName2;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
@ -38,11 +44,54 @@ public class SameLeftSide {
methName = "m1";
MethodAndTPH m1 = new MethodAndTPH("m1");
// tphExtractor.ListOfMethodsAndTph.add(e)
methName2 = "m2";
MethodAndTPH m2 = new MethodAndTPH("m2");
m1.getTphs().add("A");
m1.getTphs().add("B");
m1.getTphs().add("D");
m2.getTphs().add("C");
m2.getTphs().add("E");
tphExtractor.ListOfMethodsAndTph.add(m1);
tphExtractor.ListOfMethodsAndTph.add(m2);
tphExtractor.allCons.add(c1);
tphExtractor.allCons.add(c2);
tphExtractor.allCons.add(c3);
tphExtractor.allCons.add(c4);
}
@Test
public void testM1() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
TPHConstraint d = new ExtendsConstraint("D", Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint a = new ExtendsConstraint("A", "D", Relation.EXTENDS);
TPHConstraint b = new ExtendsConstraint("B", "D", Relation.EXTENDS);
result.put(d, null);
result.put(a, null);
result.put(b, null);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals);
}
@Test
public void testM2() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
TPHConstraint e = new ExtendsConstraint("E", Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint c = new ExtendsConstraint("C", "E", Relation.EXTENDS);
result.put(e, null);
result.put(c, null);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor);
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals);
}
}

View File

@ -58,16 +58,17 @@ public class SimpleCycle {
HashSet<String> eq1 = m1.get(c);
HashSet<String> eq2 = m2.get(c2);
if(eq1.size() != eq2.size())
if((eq1 == null && eq2 != null) || (eq1 != null && eq2 == null))
return false;
for(String tph:eq1) {
if(!eq2.contains(tph))
if(eq1 != null) {
if(eq1.size() != eq2.size())
return false;
for(String tph:eq1) {
if(!eq2.contains(tph))
return false;
}
}
}else {
return false;
}
}