Skip Ackermann constraints for derived arrays (weak equivalence)#8841
Skip Ackermann constraints for derived arrays (weak equivalence)#8841tautschnig wants to merge 2 commits intodiffblue:developfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements the "weak equivalence" optimization for array constraints in the SMT solver, specifically reducing redundant Ackermann constraints for derived arrays. The optimization recognizes that arrays created through operations like with (store), if, array_of, and similar expressions don't need separate Ackermann constraints because these are already implied by the combination of the operation's own constraints and the Ackermann constraints on the base arrays.
Changes:
- Modified
add_array_Ackermann_constraints()to skip generating constraints for derived array expressions - Added regression test demonstrating ~50% reduction in Ackermann constraints (from 110 to 60 for 5 stores)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/solvers/flattening/arrays.cpp | Added logic to skip Ackermann constraint generation for derived arrays (with, if, array_of, etc.) |
| regression/cbmc/Array_UF23/test.desc | Test configuration verifying the constraint count reduction from 110 to 60 |
| regression/cbmc/Array_UF23/main.c | Test case with 5 array stores to demonstrate the optimization |
Comments suppressed due to low confidence (1)
src/solvers/flattening/arrays.cpp:355
- The
let_exprtcheck is separated from the other ID checks. Consider addingID_letto the compound condition above (lines 347-350) for consistency and to avoid the need for a dynamic cast.
if(expr_try_dynamic_cast<let_exprt>(arr))
continue;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f46faa4 to
9415ca8
Compare
Skip generating Ackermann constraints for arrays that are derived from other arrays via with (store), if, array_of, array constants, array_comprehension, typecast, or let expressions. For a derived array such as x = y with [k := v], the Ackermann constraint i1 = i2 => x[i1] = x[i2] is already implied by: (1) the with constraint: k != j => x[j] = y[j], and (2) the Ackermann constraint on the base array y. This is the read-over-weakeq optimisation from the theory of weakly equivalent arrays (Christ & Hoenicke, 2014). The same reasoning applies to if, array_of, and other derived array expressions, all of which already have constraints connecting them element-wise to their constituent arrays. With 5 stores to the same unbounded array the Ackermann constraint count drops from 110 to 60; with 40 stores it drops from 63180 to 31980 (approximately 50% reduction in all cases). Co-authored-by: Kiro
9415ca8 to
a082485
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #8841 +/- ##
===========================================
+ Coverage 80.00% 80.02% +0.01%
===========================================
Files 1700 1700
Lines 188252 188280 +28
Branches 73 73
===========================================
+ Hits 150613 150664 +51
+ Misses 37639 37616 -23 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add TIMEOUT 1200 to the set_tests_properties call in both copies of the add_test_pl_profile macro (regression/CMakeLists.txt and regression/libcprover-cpp/CMakeLists.txt). This ensures CTest will kill and report as failed any regression test that exceeds 20 minutes, preventing CI jobs from hanging indefinitely on tests that time out. Co-authored-by: Kiro (autonomous agent) <kiro-agent@users.noreply.github.com>
|
Needs #8851 for CI to pass. |
Skip generating Ackermann constraints for arrays that are derived from other arrays via with (store), if, array_of, array constants, array_comprehension, typecast, or let expressions.
For a derived array such as x = y with [k := v], the Ackermann constraint i1 = i2 => x[i1] = x[i2] is already implied by:
(1) the with constraint: k != j => x[j] = y[j], and
(2) the Ackermann constraint on the base array y.
This is the read-over-weakeq optimisation from the theory of weakly equivalent arrays (Christ & Hoenicke, 2014).
The same reasoning applies to if, array_of, and other derived array expressions, all of which already have constraints connecting them element-wise to their constituent arrays.
With 5 stores to the same unbounded array the Ackermann constraint count drops from 110 to 60; with 40 stores it drops from 63180 to 31980 (approximately 50% reduction in all cases).
Co-authored-by: Kiro