Skip to content

Commit

Permalink
branch distances for arithmetic comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
jgaleotti committed Dec 18, 2024
1 parent 230970b commit 5ebbd97
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ public static Truthness getEqualityTruthness(long a, long b) {
);
}


public static Truthness getLessThanTruthness(double a, double b) {
double distance = DistanceHelper.getDistanceToEquality(a, b);
return new Truthness(
a < b ? 1d : 1d / (1.1d + distance),
a >= b ? 1d : 1d / (1.1d + distance)
);
}

public static Truthness getLessThanTruthness(long a, long b) {
double distance = DistanceHelper.getDistanceToEquality(a, b);
return new Truthness(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.evomaster.client.java.distance.heuristics.DistanceHelper;
import org.evomaster.client.java.distance.heuristics.Truthness;
import org.evomaster.client.java.distance.heuristics.TruthnessUtils;
import org.evomaster.client.java.sql.DataRow;
Expand Down Expand Up @@ -40,22 +39,49 @@ public Truthness getEvaluatedTruthness() {
return computedTruthnesses.peek();
}

private void visitComparisonOperator(ComparisonOperator comparisonOperator) {
final Object concreteRightValue = concreteValues.pop();
final Object concreteLeftValue = concreteValues.pop();
final Truthness truthness = computeTruthnessForComparisonOperator(concreteLeftValue, concreteRightValue, comparisonOperator);
computedTruthnesses.push(truthness);
}

@Override
public void visit(EqualsTo equalsTo) {
super.visit(equalsTo);
final Object concreteRightValue = concreteValues.pop();
final Object concreteLeftValue = concreteValues.pop();
visitComparisonOperator(equalsTo);
}

private Truthness computeTruthnessForComparisonOperator(Object concreteLeftValue, Object concreteRightValue, ComparisonOperator comparisonOperator) {
final Truthness truthness;
if (concreteLeftValue == null && concreteRightValue == null) {
truthness = SqlHeuristicsCalculator.FALSE_TRUTHNESS;
} else if (concreteLeftValue == null || concreteRightValue == null) {
truthness = SqlHeuristicsCalculator.FALSE_TRUTHNESS_BETTER;
} else {
final double ofTrue;
final Truthness truthnessOfExpression;
if (concreteLeftValue instanceof Number && concreteRightValue instanceof Number) {
double leftValueAsDouble = ((Number) concreteLeftValue).doubleValue();
double rightValueAsDouble = ((Number) concreteRightValue).doubleValue();
ofTrue = TruthnessUtils.getEqualityTruthness(leftValueAsDouble, rightValueAsDouble).getOfTrue();
if (comparisonOperator instanceof EqualsTo) {
truthnessOfExpression = TruthnessUtils.getEqualityTruthness(leftValueAsDouble, rightValueAsDouble);
} else if (comparisonOperator instanceof NotEqualsTo) {
//a != b => !(a == b)
truthnessOfExpression = TruthnessUtils.getEqualityTruthness(leftValueAsDouble, rightValueAsDouble).invert();
} else if (comparisonOperator instanceof GreaterThan) {
//a > b => b < a
truthnessOfExpression = TruthnessUtils.getLessThanTruthness(rightValueAsDouble, leftValueAsDouble);
} else if (comparisonOperator instanceof MinorThan) {
truthnessOfExpression = TruthnessUtils.getLessThanTruthness(leftValueAsDouble, rightValueAsDouble);
} else if (comparisonOperator instanceof MinorThanEquals) {
//a <= b => b >= a => !(b < a)
truthnessOfExpression = TruthnessUtils.getLessThanTruthness(rightValueAsDouble, leftValueAsDouble).invert();
} else if (comparisonOperator instanceof GreaterThanEquals) {
//a >= b => ! (a < b)
truthnessOfExpression = TruthnessUtils.getLessThanTruthness(leftValueAsDouble, rightValueAsDouble).invert();
} else {
throw new UnsupportedOperationException("Unsupported comparison operator: " + comparisonOperator);
}
} else if (concreteRightValue instanceof String && concreteLeftValue instanceof String) {
throw new UnsupportedOperationException("String comparison not yet supported");
} else if (concreteLeftValue instanceof Timestamp || concreteRightValue instanceof Timestamp
Expand All @@ -66,9 +92,13 @@ public void visit(EqualsTo equalsTo) {
} else {
throw new UnsupportedOperationException("type not supported");
}
truthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, ofTrue);
if (truthnessOfExpression.isTrue()) {
truthness = truthnessOfExpression;
} else {
truthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, truthnessOfExpression.getOfTrue());
}
}
computedTruthnesses.push(truthness);
return truthness;
}

@Override
Expand Down Expand Up @@ -185,12 +215,14 @@ public void visit(OverlapsCondition overlapsCondition) {

@Override
public void visit(GreaterThan greaterThan) {
throw new UnsupportedOperationException("visit(GreaterThan) not supported");
super.visit(greaterThan);
this.visitComparisonOperator(greaterThan);
}

@Override
public void visit(GreaterThanEquals greaterThanEquals) {
throw new UnsupportedOperationException("visit(GreaterThanEquals) not supported");
super.visit(greaterThanEquals);
this.visitComparisonOperator(greaterThanEquals);
}

@Override
Expand Down Expand Up @@ -220,17 +252,20 @@ public void visit(LikeExpression likeExpression) {

@Override
public void visit(MinorThan minorThan) {
throw new UnsupportedOperationException("visit(MinorThan) not supported");
super.visit(minorThan);
visitComparisonOperator(minorThan);
}

@Override
public void visit(MinorThanEquals minorThanEquals) {
throw new UnsupportedOperationException("visit(MinorThanEquals) not supported");
super.visit(minorThanEquals);
visitComparisonOperator(minorThanEquals);
}

@Override
public void visit(NotEqualsTo notEqualsTo) {
throw new UnsupportedOperationException("visit(NotEqualsTo) not supported");
super.visit(notEqualsTo);
visitComparisonOperator(notEqualsTo);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,72 @@ public void testCrossJoinNoFromTableWithRows() {
}

@Test
public void testSelectWithWhereNoRows() {
public void testSelectNotEquals() {
String sqlCommand = "SELECT name, age FROM Persons WHERE age=18";
QueryResult personsContents = new QueryResult(Arrays.asList("name","age"), "Persons");
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 15));
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 18));
SqlDistanceWithMetrics distanceWithMetrics = SqlHeuristicsCalculator.computeDistance(sqlCommand, null, null, personsContents);
assertEquals(0.0, distanceWithMetrics.sqlDistance);
}

@Test
public void testSelectMinorThan() {
String sqlCommand = "SELECT name, age FROM Persons WHERE age<18";
QueryResult personsContents = new QueryResult(Arrays.asList("name","age"), "Persons");
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 33));
SqlDistanceWithMetrics distanceWithMetrics = SqlHeuristicsCalculator.computeDistance(sqlCommand, null, null, personsContents);

double equalityTruthness = TruthnessUtils.getLessThanTruthness(33.0d, 18.0d).getOfTrue();
double scaledTruthnessBetter = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, equalityTruthness).getOfTrue();
double scaledTruthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C, scaledTruthnessBetter).getOfTrue();
double expectedDistance = 1 - scaledTruthness;

assertEquals(expectedDistance, distanceWithMetrics.sqlDistance);
}

@Test
public void testSelectMinorThanEquals() {
String sqlCommand = "SELECT name, age FROM Persons WHERE age<=18";
QueryResult personsContents = new QueryResult(Arrays.asList("name","age"), "Persons");
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 33));
SqlDistanceWithMetrics distanceWithMetrics = SqlHeuristicsCalculator.computeDistance(sqlCommand, null, null, personsContents);

double equalityTruthness = TruthnessUtils.getEqualityTruthness(15.0d, 18.0d).getOfTrue();
double equalityTruthness = TruthnessUtils.getLessThanTruthness(18.0d, 33.0d).invert().getOfTrue();
double scaledTruthnessBetter = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, equalityTruthness).getOfTrue();
double scaledTruthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C, scaledTruthnessBetter).getOfTrue();
double expectedDistance = 1 - scaledTruthness;

assertEquals(expectedDistance, distanceWithMetrics.sqlDistance);
}

@Test
public void testSelectGreaterThan() {
String sqlCommand = "SELECT name, age FROM Persons WHERE 18>age";
QueryResult personsContents = new QueryResult(Arrays.asList("name","age"), "Persons");
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 33));
SqlDistanceWithMetrics distanceWithMetrics = SqlHeuristicsCalculator.computeDistance(sqlCommand, null, null, personsContents);

double equalityTruthness = TruthnessUtils.getLessThanTruthness( 33,18.0d).getOfTrue();
double scaledTruthnessBetter = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, equalityTruthness).getOfTrue();
double scaledTruthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C, scaledTruthnessBetter).getOfTrue();
double expectedDistance = 1 - scaledTruthness;

assertEquals(expectedDistance, distanceWithMetrics.sqlDistance);
}

@Test
public void testSelectGreaterThanEquals() {
String sqlCommand = "SELECT name, age FROM Persons WHERE 18>=age";
QueryResult personsContents = new QueryResult(Arrays.asList("name","age"), "Persons");
personsContents.addRow(Arrays.asList("name","age"),"Persons",Arrays.asList("John", 33));
SqlDistanceWithMetrics distanceWithMetrics = SqlHeuristicsCalculator.computeDistance(sqlCommand, null, null, personsContents);

double equalityTruthness = TruthnessUtils.getLessThanTruthness( 18,33.0d).invert().getOfTrue();
double scaledTruthnessBetter = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C_BETTER, equalityTruthness).getOfTrue();
double scaledTruthness = TruthnessUtils.buildScaledTruthness(SqlHeuristicsCalculator.C, scaledTruthnessBetter).getOfTrue();
double expectedDistance = 1 - scaledTruthness;

assertEquals(expectedDistance, distanceWithMetrics.sqlDistance);
}

}

0 comments on commit 5ebbd97

Please sign in to comment.