Skip to content

Commit 9617d14

Browse files
l46kokcopybara-github
authored andcommitted
Optimize SwitchBuilder to prune dead SMT branches
PiperOrigin-RevId: 951041974
1 parent b3d1158 commit 9617d14

3 files changed

Lines changed: 33 additions & 15 deletions

File tree

verifier/src/main/java/dev/cel/verifier/CelZ3OperatorTranslator.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -654,15 +654,16 @@ private ProbeResult createProbeResult(
654654
BoolExpr inMap2 = (BoolExpr) ctx.mkSelect(mapPresence, key2);
655655
Expr<?> val2 = ctx.mkSelect(mapValues, key2);
656656

657-
BoolExpr altInMap = ctx.mkOr(inMapOrig, ctx.mkAnd(cond1, inMap1), ctx.mkAnd(cond2, inMap2));
657+
BoolExpr condMap1 = CelZ3TypeSystem.mkAndFlattened(ctx, cond1, inMap1);
658+
BoolExpr condMap2 = CelZ3TypeSystem.mkAndFlattened(ctx, cond2, inMap2);
659+
660+
BoolExpr altInMap = CelZ3TypeSystem.mkOrFlattened(ctx, inMapOrig, condMap1, condMap2);
658661
Expr<?> altVal =
659-
ctx.mkITE(
660-
inMapOrig,
661-
valOrig,
662-
ctx.mkITE(
663-
ctx.mkAnd(cond1, inMap1),
664-
val1,
665-
ctx.mkITE(ctx.mkAnd(cond2, inMap2), val2, valOrig)));
662+
CelZ3TypeSystem.SwitchBuilder.newBuilder(ctx)
663+
.addCase(inMapOrig, valOrig)
664+
.addCase(condMap1, val1)
665+
.addCase(condMap2, val2)
666+
.build(valOrig);
666667

667668
return new ProbeResult(altInMap, altVal);
668669
}

verifier/src/main/java/dev/cel/verifier/CelZ3TypeSystem.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,9 @@ public <R extends Sort> SeqExpr<R> mkConcatSafe(Expr<?> arg1, Expr<?> arg2) {
723723
/**
724724
* Helper to build a chain of nested ITE (If-Then-Else) conditions.
725725
*
726-
* <p>Conditions are evaluated in the order they are added.
726+
* <p>Conditions are evaluated in the order they are added. Branches with {@code isFalse()}
727+
* conditions are skipped, and redundant {@code ITE(condition, X, X)} creations are omitted to
728+
* avoid allocating dead AST paths in Z3.
727729
*/
728730
public static final class SwitchBuilder {
729731

@@ -746,13 +748,21 @@ public static SwitchBuilder newBuilder(Context ctx) {
746748

747749
@CanIgnoreReturnValue
748750
public SwitchBuilder addCase(BoolExpr condition, Expr<?> value) {
751+
// Skip branches that can never be hit (e.g. `isFalse()` probes).
752+
if (condition.isFalse()) {
753+
return this;
754+
}
749755
cases.add(new SwitchCase(condition, value));
750756
return this;
751757
}
752758

753759
public Expr<?> build(Expr<?> defaultFallback) {
754760
Expr<?> result = defaultFallback;
755761
for (SwitchCase c : Lists.reverse(cases)) {
762+
// ITE(condition, X, X) simplifies to X; skip calling into native C++ Z3_mk_ite.
763+
if (c.value.equals(result)) {
764+
continue;
765+
}
756766
result = ctx.mkITE(c.condition, c.value, result);
757767
}
758768
return result;
@@ -764,6 +774,15 @@ private SwitchBuilder(Context ctx) {
764774
}
765775
}
766776

777+
/**
778+
* Helper to construct a flattened logical OR expression to avoid deep left-leaning ASTs.
779+
*
780+
* <p>Returns {@code false} if the list is empty.
781+
*/
782+
public static BoolExpr mkOrFlattened(Context ctx, BoolExpr... args) {
783+
return mkOrFlattened(ctx, Arrays.asList(args));
784+
}
785+
767786
/**
768787
* Helper to construct a flattened logical OR expression to avoid deep left-leaning ASTs.
769788
*

verifier/src/main/java/dev/cel/verifier/TranslatedValue.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,10 @@ static TranslatedValue propagateStrict(
194194
BoolExpr isSafe =
195195
CelZ3TypeSystem.mkOrFlattened(
196196
ctx,
197-
Arrays.asList(
198-
hasExactUnknown,
199-
CelZ3TypeSystem.mkAndFlattened(
200-
ctx,
201-
Arrays.asList(hasExactError, CelZ3TypeSystem.mkNotFlattened(ctx, hasUnknown))),
202-
CelZ3TypeSystem.mkNotFlattened(ctx, anyTaint)));
197+
hasExactUnknown,
198+
CelZ3TypeSystem.mkAndFlattened(
199+
ctx, hasExactError, CelZ3TypeSystem.mkNotFlattened(ctx, hasUnknown)),
200+
CelZ3TypeSystem.mkNotFlattened(ctx, anyTaint));
203201

204202
return create(finalResult, celExpr, ts, CelZ3TypeSystem.mkNotFlattened(ctx, isSafe));
205203
}

0 commit comments

Comments
 (0)