Skip to content

Warn prominently when the solver backend drops quantifiers - #4719

Open
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:surface-ignored-quantifiers
Open

Warn prominently when the solver backend drops quantifiers#4719
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:surface-ignored-quantifiers

Conversation

@tautschnig

Copy link
Copy Markdown
Member

Description

CBMC's SAT-based backends only support quantifiers with constant bounds (boolbv_quantifier.cpp's eager instantiation). A kani::forall!/kani::exists! with a symbolic bound reaches the backend's quantifier post-processing, which has no handling: the expression is replaced with unconstrained values, and CBMC reports only a low-visibility warning: ignoring forall among its status messages — which Kani currently swallows entirely.

The consequences are severe for usability:

  • a kani::assume containing such a quantifier is silently not enforced: the harness may report VERIFICATION:- SUCCESSFUL while covering none of the intended property (found while building quantified element-validity assumptions for autoharness slice generation, where the vacuous assume was only caught by a non-tautological probe);
  • a kani::assert containing one may fail spuriously.

This PR detects CBMC's ignoring-quantifier messages in the output parser, counts them on VerificationResult, and renders a prominent warning after the result (on both successful and failed outcomes), explaining the effect and suggesting #[kani::solver(z3)], which handles these quantifiers (verified: the same harnesses verify correctly, fast, under z3).

A proper fix (quantifier instantiation in CBMC's SAT backend) is in progress upstream; this warning closes the silent-degradation window until it lands.

Testing

New expected test pins the dangerous case: a harness that succeeds only because its assertion does not depend on the (unenforced) quantified assumption, with the warning attached. Verified no-warning behavior for constant-bound quantifiers (eagerly instantiated) and under --solver z3. All quantifier expected tests and kani-driver unit tests pass.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

CBMC's SAT-based backends only support quantifiers with constant bounds.
A quantifier with a symbolic bound reaches the backend's quantifier
post-processing, which has no handling and replaces the expression with
unconstrained values, reporting only a low-visibility 'warning: ignoring
forall' among CBMC's status messages (which Kani does not surface).

The consequences are severe for usability: a kani::assume containing such
a quantifier is silently NOT enforced -- the harness may verify
successfully while covering none of the intended property -- and a
kani::assert containing one may fail spuriously.

Detect CBMC's ignoring-quantifier messages in the output parser, count
them on VerificationResult, and render a prominent warning after the
result (on both successful and failed outcomes) explaining the effect and
suggesting an SMT solver backend (#[kani::solver(z3)]), which supports
these quantifiers.

The new expected test pins the dangerous case: a harness that SUCCEEDS
only because its final assertion does not depend on the (unenforced)
quantified assumption, with the warning attached.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig
tautschnig requested a review from a team as a code owner August 5, 2026 21:22
Copilot AI lite review requested due to automatic review settings August 5, 2026 21:22
@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Aug 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Kani’s user-facing diagnostics around CBMC SAT-backend quantifiers by detecting CBMC “ignoring forall/exists” messages, tracking how many quantifier expressions were dropped, and emitting a prominent warning so users don’t mistake vacuous assumes (or spurious assert failures) for reliable results.

Changes:

  • Add parsing/counting of CBMC “ignoring forall/exists” messages and plumb the count into VerificationResult.
  • Render a prominent, multi-line warning when dropped quantifiers are detected.
  • Add a new expected test that pins the dangerous “vacuous assume” scenario and asserts the warning is emitted.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

File Description
tests/expected/quantifiers/ignored_quantifier_warning.rs New regression test harness that triggers a symbolic-bound quantifier being dropped.
tests/expected/quantifiers/ignored_quantifier_warning.expected Expected output asserting the new prominent warning is printed.
kani-driver/src/call_cbmc.rs Counts ignored-quantifier messages and renders a warning via VerificationResult.
Cargo.lock Updates locked charon version (appears unrelated to the PR’s stated scope).
Suppressed comments (1)

kani-driver/src/call_cbmc.rs:461

  • The ignored-quantifier warning is appended after format_result/format_coverage, which already ends with the final VERIFICATION:- ... line. This means the warning currently prints after the overall status line (and with an extra blank line), but the new expected test output places the warning before VERIFICATION:- ... so it’s not missed on successful runs.
                if self.ignored_quantifiers > 0 {
                    result.push('\n');
                    result.push_str(&ignored_quantifiers_warning(self.ignored_quantifiers));
                }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +350 to +360
fn ignored_quantifiers_warning(count: usize) -> String {
format!(
"warning: the solver backend does not support quantifiers with non-constant bounds \
and ignored {count} quantifier expression(s), replacing them with unconstrained values.\n\
Verification results are unreliable: `kani::assume` calls containing such a \
quantifier are NOT enforced (a successful result may not cover the intended property), and \
`kani::assert` calls containing one may fail spuriously.\n\
Consider using an SMT solver backend, e.g. `#[kani::solver(z3)]`, which supports \
these quantifiers.\n"
)
}
@feliperodri feliperodri added this to the Contracts milestone Aug 6, 2026
@feliperodri feliperodri added the Z-Quantifiers Issues related to quantifiers label Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-Quantifiers Issues related to quantifiers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants