public Builder addEquality(Expression expression) { expression = normalizeInPredicateToEquality(expression); checkArgument(isInferenceCandidate().apply(expression), "Expression must be a simple equality: " + expression); ComparisonExpression comparison = (ComparisonExpression) expression; addEquality(comparison.getLeft(), comparison.getRight()); return this; }
@Test(expectedExceptions = IllegalArgumentException.class) public void testInvalidEqualityExpression2() { new EqualityInference.Builder() .addEquality(someExpression("a1", "b1")); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testInvalidEqualityExpression1() { new EqualityInference.Builder() .addEquality(equals("a1", "a1")); }
builder.addEquality(nameReference("a1"), nameReference("b1")); builder.addEquality(add("a1", "a1"), multiply(nameReference("a1"), number(2))); builder.addEquality(nameReference("b1"), nameReference("c1")); builder.addEquality(add("a1", "a1"), nameReference("c1")); builder.addEquality(add("a1", "b1"), nameReference("c1"));
@Test public void testConstantEqualities() throws Exception { EqualityInference.Builder builder = new EqualityInference.Builder(); addEquality("a1", "b1", builder); addEquality("b1", "c1", builder); builder.addEquality(nameReference("c1"), number(1)); EqualityInference inference = builder.build(); // Should always prefer a constant if available (constant is part of all scopes) assertEquals(inference.rewriteExpression(nameReference("a1"), matchesSymbols("a1", "b1")), number(1)); // All scope equalities should utilize the constant if possible EqualityInference.EqualityPartition equalityPartition = inference.generateEqualitiesPartitionedBy(matchesSymbols("a1", "b1")); assertEquals(equalitiesAsSets(equalityPartition.getScopeEqualities()), set(set(nameReference("a1"), number(1)), set(nameReference("b1"), number(1)))); assertEquals(equalitiesAsSets(equalityPartition.getScopeComplementEqualities()), set(set(nameReference("c1"), number(1)))); // There should be no scope straddling equalities as the full set of equalities should be already represented by the scope and inverse scope assertTrue(equalityPartition.getScopeStraddlingEqualities().isEmpty()); }
@Test public void testSubExpressionRewrites() throws Exception { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.addEquality(nameReference("a1"), add("b", "c")); // a1 = b + c builder.addEquality(nameReference("a2"), multiply(nameReference("b"), add("b", "c"))); // a2 = b * (b + c) builder.addEquality(nameReference("a3"), multiply(nameReference("a1"), add("b", "c"))); // a3 = a1 * (b + c) EqualityInference inference = builder.build(); // Expression (b + c) should get entirely rewritten as a1 assertEquals(inference.rewriteExpression(add("b", "c"), symbolBeginsWith("a")), nameReference("a1")); // Only the sub-expression (b + c) should get rewritten in terms of a* assertEquals(inference.rewriteExpression(multiply(nameReference("ax"), add("b", "c")), symbolBeginsWith("a")), multiply(nameReference("ax"), nameReference("a1"))); // To be compliant, could rewrite either the whole expression, or just the sub-expression. Rewriting larger expressions are preferred assertEquals(inference.rewriteExpression(multiply(nameReference("a1"), add("b", "c")), symbolBeginsWith("a")), nameReference("a3")); }
private static void addEquality(String symbol1, String symbol2, EqualityInference.Builder builder) { builder.addEquality(nameReference(symbol1), nameReference(symbol2)); }
@Test public void testEqualityGeneration() throws Exception { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.addEquality(nameReference("a1"), add("b", "c")); // a1 = b + c builder.addEquality(nameReference("e1"), add("b", "d")); // e1 = b + d addEquality("c", "d", builder); EqualityInference inference = builder.build(); Expression scopedCanonical = inference.getScopedCanonical(nameReference("e1"), symbolBeginsWith("a")); assertEquals(scopedCanonical, nameReference("a1")); }
@Test public void testParseEqualityExpression() throws Exception { EqualityInference inference = new EqualityInference.Builder() .addEquality(equals("a1", "b1")) .addEquality(equals("a1", "c1")) .addEquality(equals("c1", "a1")) .build(); Expression expression = inference.rewriteExpression(someExpression("a1", "b1"), matchesSymbols("c1")); assertEquals(expression, someExpression("c1", "c1")); }
public Builder addEquality(Expression expression) { expression = normalizeInPredicateToEquality(expression); checkArgument(isInferenceCandidate().apply(expression), "Expression must be a simple equality: " + expression); ComparisonExpression comparison = (ComparisonExpression) expression; addEquality(comparison.getLeft(), comparison.getRight()); return this; }
public Builder addAllEqualities(Iterable<Expression> expressions) { for (Expression expression : expressions) { addEquality(expression); } return this; }
@Test(expectedExceptions = IllegalArgumentException.class) public void testInvalidEqualityExpression1() throws Exception { new EqualityInference.Builder() .addEquality(equals("a1", "a1")); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testInvalidEqualityExpression2() throws Exception { new EqualityInference.Builder() .addEquality(someExpression("a1", "b1")); }
builder.addEquality(nameReference("a1"), nameReference("b1")); builder.addEquality(add("a1", "a1"), multiply(nameReference("a1"), number(2))); builder.addEquality(nameReference("b1"), nameReference("c1")); builder.addEquality(add("a1", "a1"), nameReference("c1")); builder.addEquality(add("a1", "b1"), nameReference("c1"));
@Test public void testConstantEqualities() { EqualityInference.Builder builder = new EqualityInference.Builder(); addEquality("a1", "b1", builder); addEquality("b1", "c1", builder); builder.addEquality(nameReference("c1"), number(1)); EqualityInference inference = builder.build(); // Should always prefer a constant if available (constant is part of all scopes) assertEquals(inference.rewriteExpression(nameReference("a1"), matchesSymbols("a1", "b1")), number(1)); // All scope equalities should utilize the constant if possible EqualityInference.EqualityPartition equalityPartition = inference.generateEqualitiesPartitionedBy(matchesSymbols("a1", "b1")); assertEquals(equalitiesAsSets(equalityPartition.getScopeEqualities()), set(set(nameReference("a1"), number(1)), set(nameReference("b1"), number(1)))); assertEquals(equalitiesAsSets(equalityPartition.getScopeComplementEqualities()), set(set(nameReference("c1"), number(1)))); // There should be no scope straddling equalities as the full set of equalities should be already represented by the scope and inverse scope assertTrue(equalityPartition.getScopeStraddlingEqualities().isEmpty()); }
@Test public void testSubExpressionRewrites() { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.addEquality(nameReference("a1"), add("b", "c")); // a1 = b + c builder.addEquality(nameReference("a2"), multiply(nameReference("b"), add("b", "c"))); // a2 = b * (b + c) builder.addEquality(nameReference("a3"), multiply(nameReference("a1"), add("b", "c"))); // a3 = a1 * (b + c) EqualityInference inference = builder.build(); // Expression (b + c) should get entirely rewritten as a1 assertEquals(inference.rewriteExpression(add("b", "c"), symbolBeginsWith("a")), nameReference("a1")); // Only the sub-expression (b + c) should get rewritten in terms of a* assertEquals(inference.rewriteExpression(multiply(nameReference("ax"), add("b", "c")), symbolBeginsWith("a")), multiply(nameReference("ax"), nameReference("a1"))); // To be compliant, could rewrite either the whole expression, or just the sub-expression. Rewriting larger expressions are preferred assertEquals(inference.rewriteExpression(multiply(nameReference("a1"), add("b", "c")), symbolBeginsWith("a")), nameReference("a3")); }
private static void addEquality(String symbol1, String symbol2, EqualityInference.Builder builder) { builder.addEquality(nameReference(symbol1), nameReference(symbol2)); }
public Builder addAllEqualities(Iterable<Expression> expressions) { for (Expression expression : expressions) { addEquality(expression); } return this; }
@Test public void testEqualityGeneration() { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.addEquality(nameReference("a1"), add("b", "c")); // a1 = b + c builder.addEquality(nameReference("e1"), add("b", "d")); // e1 = b + d addEquality("c", "d", builder); EqualityInference inference = builder.build(); Expression scopedCanonical = inference.getScopedCanonical(nameReference("e1"), symbolBeginsWith("a")); assertEquals(scopedCanonical, nameReference("a1")); }
@Test public void testParseEqualityExpression() { EqualityInference inference = new EqualityInference.Builder() .addEquality(equals("a1", "b1")) .addEquality(equals("a1", "c1")) .addEquality(equals("c1", "a1")) .build(); Expression expression = inference.rewriteExpression(someExpression("a1", "b1"), matchesSymbols("c1")); assertEquals(expression, someExpression("c1", "c1")); }