Skip to content

Commit 8ad9e4a

Browse files
conp-solutionstautschnig
authored andcommitted
Add support for MergeSat
MergeSat is a recent SAT solver that fits the MiniSat2 interface. Run the check-ubuntu-20_04-cmake-gcc and check-vs-2019-cmake-build-and-test CI jobs with MergeSat to continuously confirm that this configuration actually works. To use MergeSat as a proper SAT backend, some extensions might be dropped. Especially being able to print memory usage is not helpful for CBMC, but requires pulling in a new dependency. Signed-off-by: Norbert Manthey <[email protected]>
1 parent 9bf24e0 commit 8ad9e4a

File tree

8 files changed

+142
-13
lines changed

8 files changed

+142
-13
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ jobs:
222222
run: |
223223
mkdir build
224224
cd build
225-
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
225+
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -Dsat_impl=mergesat
226226
- name: Check that doc task works
227227
run: |
228228
cd build
@@ -458,7 +458,7 @@ jobs:
458458
echo "CLCACHE_BASEDIR=$((Get-Item -Path '.\').FullName)" >> $env:GITHUB_ENV
459459
echo "CLCACHE_DIR=$pwd\.ccache" >> $env:GITHUB_ENV
460460
- name: Configure with cmake
461-
run: cmake -S . -B build
461+
run: cmake -S . -B build -Dsat_impl=mergesat
462462
- name: Build Release
463463
run: cmake --build build --config Release -- /p:UseMultiToolTask=true /p:CLToolExe=clcache
464464
- name: Print ccache stats

scripts/mergesat_CMakeLists.txt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# CBMC only uses part of MergeSat.
2+
# This CMakeLists is designed to build just the parts that are needed.
3+
4+
add_library(mergesat-condensed
5+
minisat/core/Lookahead.cc
6+
minisat/core/Solver.cc
7+
minisat/simp/SimpSolver.cc
8+
minisat/utils/ccnr.cc
9+
minisat/utils/Options.cc
10+
minisat/utils/System.cc
11+
)
12+
13+
set_target_properties(
14+
mergesat-condensed
15+
PROPERTIES
16+
CXX_STANDARD 11
17+
CXX_STANDARD_REQUIRED true
18+
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Developer ID Application: Daniel Kroening"
19+
)
20+
21+
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
22+
target_compile_options(mergesat-condensed PUBLIC /w)
23+
endif()
24+
25+
target_include_directories(mergesat-condensed
26+
PUBLIC
27+
${CMAKE_CURRENT_SOURCE_DIR}
28+
)

src/Makefile

+9
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ minisat2-download:
139139
@(cd ../minisat-2.2.1; patch -p1 < ../scripts/minisat-2.2.1-patch)
140140
@rm minisat2_2.2.1.orig.tar.gz
141141

142+
mergesat_version = 4.0-rc
143+
mergesat-download:
144+
@echo "Downloading MergeSat $(mergesat_version)"
145+
@$(DOWNLOADER) https://github.com/conp-solutions/mergesat/archive/$(mergesat_version).tar.gz
146+
@$(TAR) xfz $(mergesat_version).tar.gz
147+
@rm -Rf ../mergesat
148+
@mv mergesat-$(mergesat_version) ../mergesat
149+
@$(RM) $(mergesat_version).tar.gz
150+
142151
cudd-download:
143152
@echo "Downloading Cudd 3.0.0"
144153
@$(DOWNLOADER) https://sourceforge.net/projects/cudd-mirror/files/cudd-3.0.0.tar.gz/download cudd-3.0.0.tar.gz

src/config.inc

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ endif
3030
#BOOLEFORCE = ../../booleforce-0.4
3131
#MINISAT = ../../MiniSat-p_v1.14
3232
#MINISAT2 = ../../minisat-2.2.1
33+
#MERGESAT = ../../mergesat-3.0
3334
#IPASIR = ../../ipasir
3435
#GLUCOSE = ../../glucose-syrup
3536
#CADICAL = ../../cadical
3637

3738
# select default solver to be minisat2 if no other is specified
38-
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(PICOSAT)$(CADICAL),)
39+
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(MERGESAT)$(PICOSAT)$(CADICAL),)
3940
MINISAT2 = ../../minisat-2.2.1
4041
endif
4142

@@ -63,6 +64,10 @@ ifneq ($(MINISAT2),)
6364
CP_CXXFLAGS += -DSATCHECK_MINISAT2
6465
endif
6566

67+
ifneq ($(MERGESAT),)
68+
CP_CXXFLAGS += -DSATCHECK_MERGESAT
69+
endif
70+
6671
ifneq ($(GLUCOSE),)
6772
CP_CXXFLAGS += -DSATCHECK_GLUCOSE
6873
endif

src/solvers/CMakeLists.txt

+22-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(chaff_source
99
set(minisat_source
1010
${CMAKE_CURRENT_SOURCE_DIR}/sat/satcheck_minisat.cpp
1111
)
12-
set(minisat2_source
12+
set(minisat2_mergesat_source
1313
${CMAKE_CURRENT_SOURCE_DIR}/sat/satcheck_minisat2.cpp
1414
)
1515
set(glucose_source
@@ -44,7 +44,7 @@ file(GLOB_RECURSE sources "*.cpp" "*.h")
4444
list(REMOVE_ITEM sources
4545
${chaff_source}
4646
${minisat_source}
47-
${minisat2_source}
47+
${minisat2_mergesat_source}
4848
${glucose_source}
4949
${squolem2_source}
5050
${cudd_source}
@@ -78,9 +78,28 @@ if("${sat_impl}" STREQUAL "minisat2")
7878
SATCHECK_MINISAT2 HAVE_MINISAT2 __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
7979
)
8080

81-
target_sources(solvers PRIVATE ${minisat2_source})
81+
target_sources(solvers PRIVATE ${minisat2_mergesat_source})
8282

8383
target_link_libraries(solvers minisat2-condensed)
84+
elseif("${sat_impl}" STREQUAL "mergesat")
85+
message(STATUS "Building solvers with MergeSat")
86+
87+
download_project(PROJ mergesat
88+
URL https://github.com/conp-solutions/mergesat/archive/4.0-rc.tar.gz
89+
PATCH_COMMAND true
90+
COMMAND cmake -E copy ${CBMC_SOURCE_DIR}/../scripts/mergesat_CMakeLists.txt CMakeLists.txt
91+
URL_MD5 069c0d4f69723847055c3491cff5940e
92+
)
93+
94+
add_subdirectory(${mergesat_SOURCE_DIR} ${mergesat_BINARY_DIR})
95+
96+
target_compile_definitions(solvers PUBLIC
97+
SATCHECK_MERGESAT HAVE_MERGESAT __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS
98+
)
99+
100+
target_sources(solvers PRIVATE ${minisat2_mergesat_source})
101+
102+
target_link_libraries(solvers mergesat-condensed)
84103
elseif("${sat_impl}" STREQUAL "glucose")
85104
message(STATUS "Building solvers with glucose")
86105

src/solvers/Makefile

+43-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ ifneq ($(MINISAT2),)
2222
CLEANFILES += $(MINISAT2_LIB) $(patsubst %$(OBJEXT), %$(DEPEXT), $(MINISAT2_LIB))
2323
endif
2424

25+
ifneq ($(MERGESAT),)
26+
# MergeSat is based on MiniSat2 and is invoked (with suitable defines/ifdefs)
27+
# via satcheck_minisat2.{h,cpp}
28+
MERGESAT_SRC=sat/satcheck_minisat2.cpp
29+
MERGESAT_INCLUDE=-I $(MERGESAT)
30+
MERGESAT_LIB=$(MERGESAT)/minisat/core/Lookahead$(OBJEXT) \
31+
$(MERGESAT)/minisat/core/Solver$(OBJEXT) \
32+
$(MERGESAT)/minisat/simp/SimpSolver$(OBJEXT) \
33+
$(MERGESAT)/minisat/utils/ccnr$(OBJEXT) \
34+
$(MERGESAT)/minisat/utils/Options$(OBJEXT) \
35+
$(MERGESAT)/minisat/utils/System$(OBJEXT)
36+
CP_CXXFLAGS += -DHAVE_MERGESAT -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
37+
CLEANFILES += $(MERGESAT_LIB) $(patsubst %$(OBJEXT), %$(DEPEXT), $(MERGESAT_LIB))
38+
endif
39+
2540
ifneq ($(IPASIR),)
2641
IPASIR_SRC=sat/satcheck_ipasir.cpp
2742
IPASIR_INCLUDE=-I $(IPASIR)
@@ -74,6 +89,7 @@ SRC = $(BOOLEFORCE_SRC) \
7489
$(GLUCOSE_SRC) \
7590
$(LINGELING_SRC) \
7691
$(MINISAT2_SRC) \
92+
$(MERGESAT_SRC) \
7793
$(IPASIR_SRC) \
7894
$(MINISAT_SRC) \
7995
$(PICOSAT_SRC) \
@@ -226,6 +242,31 @@ $(MINISAT2)/minisat/core/Solver$(OBJEXT): $(MINISAT2)/minisat/core/Solver.cc
226242
endif
227243
endif
228244

245+
ifneq ($(MERGESAT),)
246+
ifeq ($(BUILD_ENV_),MSVC)
247+
sat/satcheck_minisat2$(OBJEXT): sat/satcheck_minisat2.cpp
248+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
249+
250+
$(MERGESAT)/minisat/core/Lookahead$(OBJEXT): $(MERGESAT)/minisat/core/Lookahead.cc
251+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
252+
253+
$(MERGESAT)/minisat/core/Solver$(OBJEXT): $(MERGESAT)/minisat/core/Solver.cc
254+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
255+
256+
$(MERGESAT)/minisat/simp/SimpSolver$(OBJEXT): $(MERGESAT)/minisat/simp/SimpSolver.cc
257+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
258+
259+
$(MERGESAT)/minisat/utils/ccnr$(OBJEXT): $(MERGESAT)/minisat/utils/ccnr.cc
260+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
261+
262+
$(MERGESAT)/minisat/utils/Options$(OBJEXT): $(MERGESAT)/minisat/utils/Options.cc
263+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
264+
265+
$(MERGESAT)/minisat/utils/System$(OBJEXT): $(MERGESAT)/minisat/utils/System.cc
266+
$(CXX) $(CP_CXXFLAGS) /w /nologo /c /EHsc $< /Fo$@
267+
endif
268+
endif
269+
229270
ifneq ($(GLUCOSE),)
230271
ifeq ($(BUILD_ENV_),MSVC)
231272
sat/satcheck_glucose$(OBJEXT): sat/satcheck_glucose.cpp
@@ -241,6 +282,7 @@ endif
241282

242283
INCLUDES += -I .. \
243284
$(CHAFF_INCLUDE) $(BOOLEFORCE_INCLUDE) $(MINISAT_INCLUDE) $(MINISAT2_INCLUDE) \
285+
$(MERGESAT_INCLUDE) \
244286
$(IPASIR_INCLUDE) \
245287
$(SQUOLEM2_INC) $(CUDD_INCLUDE) $(GLUCOSE_INCLUDE) \
246288
$(PICOSAT_INCLUDE) $(LINGELING_INCLUDE) $(CADICAL_INCLUDE)
@@ -259,7 +301,7 @@ endif
259301
endif
260302

261303
SOLVER_LIB = $(CHAFF_LIB) $(BOOLEFORCE_LIB) $(MINISAT_LIB) \
262-
$(MINISAT2_LIB) $(SQUOLEM2_LIB) $(CUDD_LIB) \
304+
$(MINISAT2_LIB) $(MERGESAT_LIB) $(SQUOLEM2_LIB) $(CUDD_LIB) \
263305
$(PICOSAT_LIB) $(LINGELING_LIB) $(GLUCOSE_LIB) $(CADICAL_LIB)
264306

265307
SOLVER_OBJS = $(filter %$(OBJEXT), $(SOLVER_LIB))

src/solvers/sat/satcheck.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, [email protected]
1717
// #define SATCHECK_ZCHAFF
1818
// #define SATCHECK_MINISAT1
1919
// #define SATCHECK_MINISAT2
20+
// #define SATCHECK_MERGESAT
2021
// #define SATCHECK_GLUCOSE
2122
// #define SATCHECK_BOOLEFORCE
2223
// #define SATCHECK_PICOSAT
@@ -39,6 +40,10 @@ Author: Daniel Kroening, [email protected]
3940
#define SATCHECK_MINISAT2
4041
#endif
4142

43+
#if defined(HAVE_MERGESAT) && !defined(SATCHECK_MERGESAT)
44+
# define SATCHECK_MERGESAT
45+
#endif
46+
4247
#if defined(HAVE_GLUCOSE) && !defined(SATCHECK_GLUCOSE)
4348
#define SATCHECK_GLUCOSE
4449
#endif
@@ -80,9 +85,11 @@ typedef satcheck_booleforcet satcheck_no_simplifiert;
8085
typedef satcheck_minisat1t satcheckt;
8186
typedef satcheck_minisat1t satcheck_no_simplifiert;
8287

83-
#elif defined SATCHECK_MINISAT2
88+
#elif defined SATCHECK_MINISAT2 || defined SATCHECK_MERGESAT
89+
// MergeSat is based on MiniSat2 and is invoked (with suitable defines/ifdefs)
90+
// via satcheck_minisat2.{h,cpp}
8491

85-
#include "satcheck_minisat2.h"
92+
# include "satcheck_minisat2.h"
8693

8794
typedef satcheck_minisat_simplifiert satcheckt;
8895
typedef satcheck_minisat_no_simplifiert satcheck_no_simplifiert;

src/solvers/sat/satcheck_minisat2.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@ Author: Daniel Kroening, [email protected]
1313
# include <unistd.h>
1414
#endif
1515

16-
#include <limits>
17-
1816
#include <util/invariant.h>
1917
#include <util/make_unique.h>
2018
#include <util/threeval.h>
2119

2220
#include <minisat/core/Solver.h>
2321
#include <minisat/simp/SimpSolver.h>
2422

25-
#ifndef HAVE_MINISAT2
26-
#error "Expected HAVE_MINISAT2"
23+
#include <cstdlib>
24+
#include <limits>
25+
26+
// MergeSat is based on MiniSat2; variations in their API are handled via
27+
// #ifdefs
28+
#if !defined(HAVE_MINISAT2) && !defined(HAVE_MERGESAT)
29+
# error "Expected HAVE_MINISAT2 or HAVE_MERGESAT"
2730
#endif
2831

2932
void convert(const bvt &bv, Minisat::vec<Minisat::Lit> &dest)
@@ -77,7 +80,11 @@ void satcheck_minisat2_baset<T>::set_polarity(literalt a, bool value)
7780
try
7881
{
7982
add_variables();
83+
#ifdef HAVE_MERGESAT
84+
solver->setPolarity(a.var_no(), value);
85+
#else
8086
solver->setPolarity(a.var_no(), value ? l_True : l_False);
87+
#endif
8188
}
8289
catch(Minisat::OutOfMemoryException)
8390
{
@@ -101,12 +108,20 @@ void satcheck_minisat2_baset<T>::clear_interrupt()
101108

102109
const std::string satcheck_minisat_no_simplifiert::solver_text()
103110
{
111+
#ifdef HAVE_MERGESAT
112+
return "MergeSat 4.0-rc without simplifier";
113+
#else
104114
return "MiniSAT 2.2.1 without simplifier";
115+
#endif
105116
}
106117

107118
const std::string satcheck_minisat_simplifiert::solver_text()
108119
{
120+
#ifdef HAVE_MERGESAT
121+
return "MergeSat 4.0-rc with simplifier";
122+
#else
109123
return "MiniSAT 2.2.1 with simplifier";
124+
#endif
110125
}
111126

112127
template<typename T>
@@ -314,6 +329,10 @@ satcheck_minisat2_baset<T>::satcheck_minisat2_baset(
314329
solver(util_make_unique<T>()),
315330
time_limit_seconds(0)
316331
{
332+
#ifdef HAVE_MERGESAT
333+
if constexpr(std::is_same<T, Minisat::SimpSolver>::value)
334+
solver->grow_iterations = false;
335+
#endif
317336
}
318337

319338
template <typename T>

0 commit comments

Comments
 (0)