Skip to content

Commit 42d5ce2

Browse files
authored
Merge pull request #7493 from zhassan-aws/cadical-option
Allow building CBMC with multiple backend SAT solvers that can be selected at runtime via a new `--sat-solver` option
2 parents 5678ed6 + 85c6f6c commit 42d5ce2

File tree

24 files changed

+501
-186
lines changed

24 files changed

+501
-186
lines changed

.github/workflows/pull-request-checks.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ jobs:
9292
run: |
9393
sudo apt-get update
9494
sudo apt-get install --no-install-recommends -yq clang-10 clang++-10 gdb maven jq flex bison libxml2-utils cpanminus ccache z3
95-
make -C src minisat2-download
95+
make -C src minisat2-download cadical-download
9696
cpanm Thread::Pool::Simple
9797
- name: Confirm z3 solver is available and log the version installed
9898
run: z3 --version
@@ -118,7 +118,7 @@ jobs:
118118
run: ccache -z --max-size=500M
119119
- name: Build with make
120120
run: |
121-
make -C src -j2
121+
make -C src -j2 MINISAT2=../../minisat-2.2.1 CADICAL=../../cadical
122122
make -C unit -j2
123123
make -C jbmc/src -j2
124124
make -C jbmc/unit -j2
@@ -223,7 +223,7 @@ jobs:
223223
echo "CCACHE_BASEDIR=$PWD" >> $GITHUB_ENV
224224
echo "CCACHE_DIR=$PWD/.ccache" >> $GITHUB_ENV
225225
- name: Configure using CMake
226-
run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
226+
run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -Dsat_impl="minisat2;cadical"
227227
- name: Check that doc task works
228228
run: ninja -C build doc
229229
- name: Zero ccache stats and limit in size
@@ -260,7 +260,7 @@ jobs:
260260
run: |
261261
sudo apt-get update
262262
sudo apt-get install --no-install-recommends -yq clang clang-14 gdb maven jq flex bison libxml2-utils cpanminus ccache z3
263-
make -C src minisat2-download
263+
make -C src minisat2-download cadical-download
264264
cpanm Thread::Pool::Simple
265265
- name: Confirm z3 solver is available and log the version installed
266266
run: z3 --version
@@ -290,7 +290,7 @@ jobs:
290290
make -C src/cpp library_check
291291
- name: Build with make
292292
run: |
293-
make -C src -j2
293+
make -C src -j2 MINISAT2=../../minisat-2.2.1 CADICAL=../../cadical
294294
make -C unit -j2
295295
make -C jbmc/src -j2
296296
make -C jbmc/unit -j2
@@ -348,7 +348,7 @@ jobs:
348348
echo "CCACHE_BASEDIR=$PWD" >> $GITHUB_ENV
349349
echo "CCACHE_DIR=$PWD/.ccache" >> $GITHUB_ENV
350350
- name: Configure using CMake
351-
run: cmake -S . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
351+
run: cmake -S . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -Dsat_impl="minisat2;cadical"
352352
- name: Check that doc task works
353353
run: ninja -C build doc
354354
- name: Zero ccache stats and limit in size
@@ -439,7 +439,7 @@ jobs:
439439
echo "CCACHE_BASEDIR=$PWD" >> $GITHUB_ENV
440440
echo "CCACHE_DIR=$PWD/.ccache" >> $GITHUB_ENV
441441
- name: Configure using CMake
442-
run: cmake -H. -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
442+
run: cmake -H. -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -Dsat_impl="minisat2;cadical"
443443
- name: Zero ccache stats and limit in size
444444
run: ccache -z --max-size=500M
445445
- name: Build with Ninja
@@ -482,8 +482,8 @@ jobs:
482482
run: ccache -z --max-size=500M
483483
- name: Build using Make
484484
run: |
485-
make -C src minisat2-download
486-
make -C src -j3 CXX="ccache clang++"
485+
make -C src minisat2-download cadical-download
486+
make -C src -j3 CXX="ccache clang++" MINISAT2=../../minisat-2.2.1 CADICAL=../../cadical
487487
make -C jbmc/src -j3 CXX="ccache clang++"
488488
make -C unit "CXX=ccache clang++"
489489
make -C jbmc/unit "CXX=ccache clang++"

.github/workflows/release-packages.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
echo "CCACHE_BASEDIR=$PWD" >> $GITHUB_ENV
4040
echo "CCACHE_DIR=$PWD/.ccache" >> $GITHUB_ENV
4141
- name: Configure CMake
42-
run: cmake -S . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
42+
run: cmake -S . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -Dsat_impl="minisat2;cadical"
4343
- name: Zero ccache stats and limit in size
4444
run: ccache -z --max-size=500M
4545
- name: Build using Ninja
@@ -112,7 +112,7 @@ jobs:
112112
run: |
113113
mkdir build
114114
cd build
115-
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release
115+
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -Dsat_impl="minisat2;cadical"
116116
- name: Zero ccache stats and limit in size
117117
run: ccache -z --max-size=500M
118118
- name: Build using Ninja
@@ -198,7 +198,7 @@ jobs:
198198
run: |
199199
mkdir build
200200
cd build
201-
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release
201+
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -Dsat_impl="minisat2;cadical"
202202
- name: Zero ccache stats and limit in size
203203
run: ccache -z --max-size=500M
204204
- name: Build using Ninja

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ jbmc/regression/**/tests-symex-driven-loading.log
7474

7575
# libs downloaded by make [name]-download
7676
minisat*/
77+
cadical*/
7778
glucose-syrup/
7879

7980
# flex/bison generated files

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ else()
273273
FetchContent_MakeAvailable(Corrosion)
274274

275275
corrosion_import_crate(MANIFEST_PATH src/libcprover-rust/Cargo.toml)
276-
corrosion_set_env_vars(cprover-api-rust CBMC_BUILD_DIR=${CMAKE_BINARY_DIR} SAT_IMPL=${sat_impl})
276+
list(JOIN sat_impl " " sat_impl_str)
277+
corrosion_set_env_vars(cprover-api-rust CBMC_BUILD_DIR=${CMAKE_BINARY_DIR} "SAT_IMPL=${sat_impl_str}")
277278
corrosion_link_libraries(cprover-api-rust cprover-api-cpp)
278279
install(TARGETS cprover-api-rust RUNTIME DESTINATION lib)
279280
# NOTE: We want to rename to a name consistent with the name of the

COMPILING.md

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ files.
8282
to generate IDE projects by supplying the `-G` flag. Run `cmake -G` for a
8383
comprehensive list of supported back-ends.
8484
85-
As part of this step, CMake will download the back-end solver (see Section
85+
As part of this step, CMake will download the back-end solvers (see Section
8686
"Compiling with alternative SAT solvers" in this document for configuration
8787
options). Should it be necessary to perform this step without network access,
8888
a solver can be downloaded ahead of the above `cmake` invocation as follows:
@@ -371,28 +371,40 @@ compilation flag:
371371
## Compiling with alternative SAT solvers
372372
373373
For the packaged builds of CBMC on our release page we currently build CBMC
374-
with the MiniSat2 SAT solver statically linked at compile time. However it is
375-
also possible to build CBMC using alternative SAT solvers.
374+
with the MiniSat2 and CaDiCaL SAT solvers statically linked at compile time.
375+
However it is also possible to build CBMC using alternative SAT solvers.
376376
377377
### Compiling CBMC Using Solver Native Interfaces
378378
379379
The following solvers are supported by CBMC using custom interfaces and can
380-
by downloaded and compiled by the build process: MiniSAT2, CaDiCaL, and Glucose.
380+
be downloaded and compiled by the build process: MiniSAT2, CaDiCaL, and Glucose.
381381
382-
For `make` alternatives to the default (i.e. not MiniSAT) can be built with the
383-
following commands for CaDiCaL:
384-
```
385-
make -C src cadical-download
386-
make -C src CADICAL=../../cadical
387-
```
388-
and for glucose
382+
For `make`, alternatives to the default (i.e. not MiniSAT and CaDiCaL) can be
383+
built with the following commands for glucose:
389384
```
390385
make -C src glucose-download
391386
make -C src GLUCOSE=../../glucose-syrup
392387
```
388+
CBMC can be built with multiple solvers, which can then be selected at runtime
389+
using the `--sat-solver` option.
390+
For example, to build CBMC with MiniSAT2 and Glucose, do:
391+
```
392+
make -C src minisat2-download glucose-download
393+
make -C src MINISAT2=../../minisat-2.2.1 GLUCOSE=../../glucose-syrup
394+
```
395+
The build sets the default solver based on the priority defined by the
396+
`#if/#elif` tree defined at the end of
397+
[`src/solvers/sat/satcheck.h`](https://github.com/diffblue/cbmc/blob/develop/src/solvers/sat/satcheck.h).
398+
In the above example, MiniSAT2 will be set as the default solver because it is
399+
listed before Glucose. To switch to glucose at runtime, run CBMC with
400+
`--sat-solver glucose`.
393401
394402
For CMake the alternatives can be built with the following arguments to `cmake`
395-
for CaDiCaL `-Dsat_impl=cadical` and for glucose `-Dsat_impl=glucose`.
403+
for glucose `-Dsat_impl=glucose`.
404+
To build CBMC with multiple solvers, specify the solvers in a semicolon-separated list to `-Dsat_impl`, e.g.:
405+
```
406+
cmake -S . -Bbuild -Dsat_impl="minisat2;glucose"
407+
```
396408
397409
398410
### Compiling with IPASIR Interface
@@ -520,7 +532,7 @@ successfully on Windows or macOS.
520532
This document assumes you have already been able to build CPROVER on
521533
your chosen architecture.
522534

523-
#RUNNING REGRESSION AND UNIT TESTS
535+
# RUNNING REGRESSION AND UNIT TESTS
524536

525537
Regression and unit tests can be run using cmake or make. Your choice here
526538
should be the same as the compiling of the project itself.

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ RUN echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \
1010
echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \
1111
apt-get update && apt-get upgrade -y && apt-get install --no-install-recommends -y \
1212
cmake \
13+
make \
1314
ninja-build \
1415
gcc \
1516
g++ \

doc/man/cbmc.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ enable caching of repeated dereferences
388388
\fB\-\-object\-bits\fR n
389389
number of bits used for object addresses
390390
.TP
391+
\fB\-\-sat\-solver\fR solver
392+
use specified SAT solver
393+
.TP
391394
\fB\-\-external\-sat\-solver\fR cmd
392395
command to invoke SAT solver process
393396
.TP

doc/man/jbmc.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ enable caching of repeated dereferences
382382
\fB\-\-object\-bits\fR n
383383
number of bits used for object addresses
384384
.TP
385+
\fB\-\-sat\-solver\fR solver
386+
use specified SAT solver
387+
.TP
385388
\fB\-\-external\-sat\-solver\fR \fIcmd\fR
386389
command to invoke SAT solver process
387390
.TP
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
unsigned x;
6+
unsigned y = 0;
7+
assert(x * y == y);
8+
return 0;
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE broken-z3-smt-backend broken-cprover-smt-backend paths-lifo-expected-failure
2+
test.c
3+
--sat-solver non-existing-solver
4+
^EXIT=1$
5+
^SIGNAL=0$
6+
unknown solver 'non-existing-solver'
7+
--
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
unsigned x;
6+
unsigned y = x;
7+
x /= 2;
8+
y /= 2;
9+
assert(x == y);
10+
return 0;
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE broken-z3-smt-backend broken-cprover-smt-backend
2+
test.c
3+
--sat-solver lingeling
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
The specified solver, 'lingeling', is not available\. The default solver will be used instead\.
7+
\[main\.assertion\.1] line \d+ assertion x == y: SUCCESS
8+
^VERIFICATION SUCCESSFUL$
9+
--

regression/cbmc/sat-solver/test.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
unsigned x;
6+
unsigned y = x / 2;
7+
assert(y != x);
8+
assert(y <= x);
9+
return 0;
10+
}

regression/cbmc/sat-solver/test.desc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE broken-z3-smt-backend broken-cprover-smt-backend
2+
test.c
3+
--sat-solver cadical
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
Solving with CaDiCaL|The specified solver, 'cadical', is not available. The default solver will be used instead.
7+
\[main\.assertion\.1] line \d+ assertion y != x: FAILURE
8+
\[main\.assertion\.2] line \d+ assertion y <= x: SUCCESS
9+
^VERIFICATION FAILED$
10+
--

regression/validate-trace-xml-schema/check.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
['bad_option', 'test_multiple.desc'],
4343
['bad_option', 'test.desc'],
4444
['unknown-argument-suggestion', 'test.desc'],
45+
['sat-solver-error', 'test.desc'],
4546
# this one produces XML intermingled with main XML output when used with --xml-ui
4647
['graphml_witness2', 'test.desc'],
4748
# these are producing coverage goals which aren't included in the schema

scripts/cadical-1.4.1-patch

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
diff --git a/scripts/make-build-header.sh b/scripts/make-build-header.sh
2+
index e8f6746..1290024 100755
3+
--- a/scripts/make-build-header.sh
4+
+++ b/scripts/make-build-header.sh
5+
@@ -20,7 +20,7 @@ warning () {
6+
7+
#--------------------------------------------------------------------------#
8+
9+
-[ ! -f VERSION -a ! -f ../VERSION ] && \
10+
+[ ! -f VERSION.txt -a ! -f ../VERSION.txt ] && \
11+
die "needs to be called from build sub-directory"
12+
13+
[ -f makefile ] || \
14+
@@ -29,7 +29,7 @@ warning "could not find 'makefile'"
15+
#--------------------------------------------------------------------------#
16+
# The version.
17+
#
18+
-VERSION="`cat ../VERSION`"
19+
+VERSION="`cat ../VERSION.txt`"
20+
if [ x"$VERSION" = x ]
21+
then
22+
warning "could not determine 'VERSION'"
23+
diff --git a/src/lookahead.cpp b/src/lookahead.cpp
24+
index 9e8a16b..3d5721a 100644
25+
--- a/src/lookahead.cpp
26+
+++ b/src/lookahead.cpp
27+
@@ -390,6 +390,7 @@ int Internal::lookahead_probing() {
28+
CubesWithStatus Internal::generate_cubes(int depth, int min_depth) {
29+
if (!active() || depth == 0) {
30+
CubesWithStatus cubes;
31+
+ cubes.status = 0;
32+
cubes.cubes.push_back(std::vector<int>());
33+
return cubes;
34+
}

scripts/cadical_CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
file(GLOB sources "src/*.cpp" "src/*.hpp" "src/*.h")
2+
# Remove "app" sources from list
3+
list(REMOVE_ITEM sources
4+
"${CMAKE_CURRENT_SOURCE_DIR}/src/cadical.cpp"
5+
"${CMAKE_CURRENT_SOURCE_DIR}/src/mobical.cpp"
6+
)
7+
8+
add_library(cadical ${sources})
9+
10+
# Pass -DNBUILD to disable including the version information, which is not
11+
# needed since cbmc doesn't run the cadical binary
12+
target_compile_options(cadical PUBLIC -DNBUILD)
13+
14+
set_target_properties(
15+
cadical
16+
PROPERTIES
17+
CXX_STANDARD 11
18+
CXX_STANDARD_REQUIRED true
19+
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Developer ID Application: Daniel Kroening"
20+
)
21+
22+
target_include_directories(cadical
23+
PUBLIC
24+
${CMAKE_CURRENT_SOURCE_DIR}/src
25+
)
26+
27+
target_link_libraries(cadical util)

src/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,11 @@ cadical-download:
177177
@$(TAR) xfz $(cadical_release).tar.gz
178178
@rm -Rf ../cadical
179179
@mv cadical-$(cadical_release) ../cadical
180-
@cd ../cadical && CXX=$(CXX) ./configure -O3 -s && make -j
180+
@(cd ../cadical; patch -p1 < ../scripts/cadical-1.4.1-patch)
181+
@(cd ../cadical && ./configure)
182+
# Need to rename VERSION so that it isn't picked up by `#include<version>` on
183+
# macOS which is case insensitive
184+
@(cd ../cadical && mv VERSION VERSION.txt)
181185
@$(RM) $(cadical_release).tar.gz
182186

183187
doc :

0 commit comments

Comments
 (0)