Limit MiniSat simplifier only when arrays-uf-always is used#8851
Limit MiniSat simplifier only when arrays-uf-always is used#8851tautschnig wants to merge 2 commits intodiffblue:developfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a hang in CBMC's incremental SAT solving when using MiniSat's SimpSolver. The issue occurs because MiniSat's simplifier runs variable elimination (eliminate()) before every solveLimited/solve call, which can degrade the solver's ability to prove UNSAT during the all-properties verification loop. The fix passes do_simp=false on all calls after the first, allowing the initial full simplification pass but skipping it on subsequent incremental calls.
Changes:
- Added a
solver_was_calledflag tosatcheck_minisat2_basetto track whether the solver has been called before, and useif constexprto passdo_simp=falsetoSimpSolver::solveLimited/solveon subsequent calls - Reordered includes to follow the
.clang-formatpriority ordering and added<type_traits>forstd::is_same_v - Added a regression test (
Array_UF23) that reproduces the hang scenario with--arrays-uf-always --unwind 1 --32
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/solvers/sat/satcheck_minisat2.h | Added solver_was_called boolean member with in-class default initializer |
| src/solvers/sat/satcheck_minisat2.cpp | Used if constexpr to conditionally disable SimpSolver's simplifier after first solve, reordered includes |
| regression/cbmc/Array_UF23/main.c | New regression test C source with VLA array stores and an assertion |
| regression/cbmc/Array_UF23/test.desc | Test descriptor for the regression test |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #8851 +/- ##
========================================
Coverage 80.01% 80.01%
========================================
Files 1703 1703
Lines 188396 188405 +9
Branches 73 73
========================================
+ Hits 150738 150747 +9
Misses 37658 37658 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Is this a genuine issue in MiniSat, or are we using it wrong? |
|
It's a known limitation of MiniSat's SimpSolver when used incrementally. The SimpSolver was designed primarily for single-shot solving — its MiniSat's API does provide the |
75c8bd0 to
59fef53
Compare
c8ca115 to
6052d4b
Compare
MiniSat's SimpSolver runs variable elimination (eliminate()) before every solveLimited/solve call by default. When used incrementally in the all-properties verification loop, this repeated elimination can degrade the solver's ability to prove UNSAT, causing the CDCL search to hang indefinitely. Fix by passing do_simp=false on all calls after the first. The first call still benefits from the full simplification pass, but subsequent incremental calls skip it, preventing the problematic variable elimination between iterations. This fixes a hang when running: cbmc --arrays-uf-always --unwind 1 --32 Array_UF23/main.c Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The previous unconditional disabling of the simplifier after the first incremental solve caused Multi_Dimensional_Array6 to hang in the 32-bit CI build. The simplifier is beneficial for most workloads; only the Ackermann-style array encoding (--arrays-uf-always) generates the problematic pattern of many incremental calls where variable elimination between solves degrades CDCL performance. Make the behaviour opt-in via set_limit_incremental_simplification() on the MiniSat solver, and activate it from solver_factory when arrays-uf is set to "always". Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
6052d4b to
f382772
Compare
MiniSat's SimpSolver runs variable elimination (eliminate()) before every solveLimited/solve call by default. When used incrementally in the all-properties verification loop, this repeated elimination can degrade the solver's ability to prove UNSAT, causing the CDCL search to hang indefinitely.
Fix by passing do_simp=false on all calls after the first. The first call still benefits from the full simplification pass, but subsequent incremental calls skip it, preventing the problematic variable elimination between iterations.
This fixes a hang when running:
cbmc --arrays-uf-always --unwind 1 --32 Array_UF23/main.c