Skip to content

Commit a8a288e

Browse files
l46kokcopybara-github
authored andcommitted
Internal Changes
PiperOrigin-RevId: 949795380
1 parent 186eb6b commit a8a288e

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,14 @@ public CelVerifier build() {
141141
public CelVerificationResult isSatisfiable(CelAbstractSyntaxTree ast)
142142
throws CelVerificationException {
143143
Preconditions.checkArgument(ast.isChecked(), "AST must be type-checked.");
144-
return checkSatisfiability(ast, false);
144+
return checkSatisfiability(ast, /* searchForCounterexample= */ false);
145145
}
146146

147147
@Override
148148
public CelVerificationResult isAlwaysTrue(CelAbstractSyntaxTree ast)
149149
throws CelVerificationException {
150150
Preconditions.checkArgument(ast.isChecked(), "AST must be type-checked.");
151-
return checkSatisfiability(ast, true);
151+
return checkSatisfiability(ast, /* searchForCounterexample= */ true);
152152
}
153153

154154
@Override
@@ -191,12 +191,14 @@ public CelVerificationResult verifyEquivalence(
191191
case EXACT_MATCH:
192192
return CelVerificationResult.failed(
193193
"Equivalence violation detected."
194-
+ getCounterexampleString(ctx, translator.getTypeSystem(), result.model));
194+
+ getCounterexampleString(
195+
ctx, translator.getTypeSystem(), result.model, /* isApproximate= */ false));
195196
case APPROXIMATE_MATCH:
196197
return CelVerificationResult.inconclusive(
197198
"Inconclusive: a divergence may exist, but it depends on approximations, missing"
198199
+ " theories, or loop bounds."
199-
+ getCounterexampleString(ctx, translator.getTypeSystem(), result.model));
200+
+ getCounterexampleString(
201+
ctx, translator.getTypeSystem(), result.model, /* isApproximate= */ true));
200202
case TRUNCATED:
201203
return CelVerificationResult.inconclusive(
202204
"Inconclusive: expressions are equivalent within the current loop unroll limit, but"
@@ -244,7 +246,11 @@ private CelVerificationResult checkSatisfiability(
244246
return searchForCounterexample
245247
? CelVerificationResult.failed(
246248
"Condition is not always true."
247-
+ getCounterexampleString(ctx, translator.getTypeSystem(), result.model))
249+
+ getCounterexampleString(
250+
ctx,
251+
translator.getTypeSystem(),
252+
result.model,
253+
/* isApproximate= */ false))
248254
: CelVerificationResult.verified();
249255

250256
case APPROXIMATE_MATCH:
@@ -255,7 +261,9 @@ private CelVerificationResult checkSatisfiability(
255261
: "Inconclusive: a satisfying model may exist, but it depends on"
256262
+ " approximations, missing theories, or loop bounds.";
257263
return CelVerificationResult.inconclusive(
258-
prefix + getCounterexampleString(ctx, translator.getTypeSystem(), result.model));
264+
prefix
265+
+ getCounterexampleString(
266+
ctx, translator.getTypeSystem(), result.model, /* isApproximate= */ true));
259267

260268
case TRUNCATED:
261269
return CelVerificationResult.inconclusive(
@@ -349,8 +357,8 @@ private Solver newSolver(Context ctx) {
349357
}
350358

351359
private static String getCounterexampleString(
352-
Context ctx, CelZ3TypeSystem typeSystem, Model model) {
353-
return CelZ3CounterexampleGenerator.generate(ctx, typeSystem, model);
360+
Context ctx, CelZ3TypeSystem typeSystem, Model model, boolean isApproximate) {
361+
return CelZ3CounterexampleGenerator.generate(ctx, typeSystem, model, isApproximate);
354362
}
355363

356364
CelVerifierZ3Impl(

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ final class CelZ3CounterexampleGenerator {
3535

3636
private CelZ3CounterexampleGenerator() {}
3737

38-
static String generate(Context ctx, CelZ3TypeSystem typeSystem, Model model) {
38+
static String generate(
39+
Context ctx, CelZ3TypeSystem typeSystem, Model model, boolean isApproximate) {
3940
FuncDecl[] constDecls = model.getConstDecls();
4041

4142
List<String> bindings = new ArrayList<>();
@@ -57,7 +58,8 @@ static String generate(Context ctx, CelZ3TypeSystem typeSystem, Model model) {
5758
return " (The expression fails unconditionally, regardless of input state)";
5859
}
5960

60-
return " Counterexample input:" + String.join("", bindings);
61+
String prefix = isApproximate ? " Potential counterexample input:" : " Counterexample input:";
62+
return prefix + String.join("", bindings);
6163
}
6264

6365
private static String formatExpr(

verifier/src/test/java/dev/cel/verifier/CelVerifierZ3ImplTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,8 @@ private enum IsAlwaysTrueTestCase {
602602
"'key' in string_int_map ? type(string_int_map['key']) == int : true"),
603603
LITERAL_LIST_INDEX("[1, 2][0] == 1"),
604604
NESTED_LIST_VARIABLES_EQUALITY(
605-
"nested_list == [[1]] && nested_list_2 == [[1]] ? nested_list == nested_list_2 : true");
605+
"nested_list == [[1]] && nested_list_2 == [[1]] ? nested_list == nested_list_2 : true"),
606+
;
606607

607608
final String expr;
608609

@@ -1124,6 +1125,17 @@ public void isAlwaysTrue_inconclusive(@TestParameter IsInconclusiveTestCase test
11241125
assertThat(result.status()).isEqualTo(VerificationStatus.INCONCLUSIVE);
11251126
}
11261127

1128+
@Test
1129+
public void isAlwaysTrue_inconclusive_containsPotentialCounterexample() throws Exception {
1130+
CelAbstractSyntaxTree ast = CEL.compile("request.matches('^[a-z]+$') == true").getAst();
1131+
1132+
CelVerificationResult result = VERIFIER.isAlwaysTrue(ast);
1133+
1134+
assertThat(result.status()).isEqualTo(VerificationStatus.INCONCLUSIVE);
1135+
assertThat(result.message())
1136+
.containsMatch("Potential counterexample input:\\n\\s*request = .*");
1137+
}
1138+
11271139
private enum EquivalenceInconclusiveTestCase {
11281140
MASKED_BY_BMC(
11291141
"int_list == [1, 2, 3, 4, 5, 6] ? int_list.all(x, x > 0) : true",

0 commit comments

Comments
 (0)