Skip to content

Commit fd07ebb

Browse files
committed
Add support for CaDiCaL
CaDiCaL is Armin Biere's latest solver with a minimal IPASIR-compatible interface. In some initial experiments it considerable outperforms Minisat.
1 parent 69fb74a commit fd07ebb

File tree

8 files changed

+223
-3
lines changed

8 files changed

+223
-3
lines changed

scripts/cadical-patch

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--- a/src/cadical.hpp 2018-03-10 14:22:11.000000000 +0000
2+
+++ b/src/cadical.hpp 2018-03-31 16:18:32.000000000 +0100
3+
@@ -141,6 +141,6 @@
4+
File * output (); // get access to internal 'output' file
5+
};
6+
7+
-};
8+
+}
9+
10+
#endif

src/Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ ipasir-build: ipasir-download
107107
$(MAKE) -C ../ipasir/sat/picosat961 libipasirpicosat961.a
108108
@(cd ../ipasir; ln -sf sat/picosat961/libipasirpicosat961.a libipasir.a)
109109

110+
cadical_release = rel-06w
111+
cadical-download:
112+
@echo "Downloading CaDiCaL $(cadical_release)"
113+
@curl -L https://github.com/arminbiere/cadical/archive/$(cadical_release).tar.gz | tar xz
114+
@rm -Rf ../cadical
115+
@mv cadical-$(cadical_release) ../cadical
116+
@(cd ../cadical; patch -p1 < ../scripts/cadical-patch)
117+
@cd ../cadical && CXX=$(CXX) CXXFLAGS=-O3 ./configure --debug && make
118+
110119
doc :
111120
doxygen
112121

src/common

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ else
156156
endif
157157

158158
# select default solver to be minisat2 if no other is specified
159-
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(PICOSAT)$(PRECOSAT),)
159+
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(PICOSAT)$(PRECOSAT)$(CADICAL),)
160160
MINISAT2 = ../../minisat-2.2.1
161161
endif
162162

@@ -196,6 +196,10 @@ ifneq ($(GLUCOSE),)
196196
CP_CXXFLAGS += -DHAVE_GLUCOSE
197197
endif
198198

199+
ifneq ($(CADICAL),)
200+
CP_CXXFLAGS += -DHAVE_CADICAL
201+
endif
202+
199203

200204

201205
first_target: all

src/config.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ endif
2525
#MINISAT2 = ../../minisat-2.2.1
2626
#IPASIR = ../../ipasir
2727
#GLUCOSE = ../../glucose-syrup
28+
#CADICAL = ../../cadical
2829
#SMVSAT =
2930

3031
# Extra library for SAT solver. This should link to the archive file to be used
@@ -63,6 +64,10 @@ ifneq ($(GLUCOSE),)
6364
CP_CXXFLAGS += -DSATCHECK_GLUCOSE
6465
endif
6566

67+
ifneq ($(CADICAL),)
68+
CP_CXXFLAGS += -DSATCHECK_CADICAL
69+
endif
70+
6671
ifneq ($(SMVSAT),)
6772
CP_CXXFLAGS += -DSATCHECK_SMVSAT
6873
endif

src/solvers/Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ ifneq ($(LIMMAT),)
8484
CP_CXXFLAGS += -DHAVE_LIMMAT
8585
endif
8686

87+
ifneq ($(CADICAL),)
88+
CADICAL_SRC=sat/satcheck_cadical.cpp
89+
CADICAL_INCLUDE=-I $(CADICAL)/src
90+
CADICAL_LIB=$(CADICAL)/build/libcadical$(LIBEXT)
91+
CP_CXXFLAGS += -DHAVE_CADICAL
92+
endif
93+
8794
SRC = $(BOOLEFORCE_SRC) \
8895
$(CHAFF_SRC) \
8996
$(CUDD_SRC) \
@@ -97,6 +104,7 @@ SRC = $(BOOLEFORCE_SRC) \
97104
$(SMVSAT_SRC) \
98105
$(SQUOLEM2_SRC) \
99106
$(LIMMAT_SRC) \
107+
$(CADICAL_SRC) \
100108
cvc/cvc_conv.cpp \
101109
cvc/cvc_dec.cpp \
102110
flattening/arrays.cpp \
@@ -215,7 +223,7 @@ INCLUDES += -I .. \
215223
$(CHAFF_INCLUDE) $(BOOLEFORCE_INCLUDE) $(MINISAT_INCLUDE) $(MINISAT2_INCLUDE) \
216224
$(IPASIR_INCLUDE) \
217225
$(SMVSAT_INCLUDE) $(SQUOLEM2_INC) $(CUDD_INCLUDE) $(GLUCOSE_INCLUDE) \
218-
$(PRECOSAT_INCLUDE) $(PICOSAT_INCLUDE) $(LINGELING_INCLUDE)
226+
$(PRECOSAT_INCLUDE) $(PICOSAT_INCLUDE) $(LINGELING_INCLUDE) $(CADICAL_INCLUDE)
219227

220228
CLEANFILES = solvers$(LIBEXT) smt2_solver$(EXEEXT)
221229

@@ -235,7 +243,7 @@ endif
235243

236244
SOLVER_LIB = $(CHAFF_LIB) $(BOOLEFORCE_LIB) $(MINISAT_LIB) \
237245
$(MINISAT2_LIB) $(SMVSAT_LIB) $(SQUOLEM2_LIB) $(CUDD_LIB) \
238-
$(PRECOSAT_LIB) $(PICOSAT_LIB) $(LINGELING_LIB) $(GLUCOSE_LIB)
246+
$(PRECOSAT_LIB) $(PICOSAT_LIB) $(LINGELING_LIB) $(GLUCOSE_LIB) $(CADICAL_LIB)
239247

240248
###############################################################################
241249

src/solvers/sat/satcheck.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected]
2222
// #define SATCHECK_PRECOSAT
2323
// #define SATCHECK_PICOSAT
2424
// #define SATCHECK_LINGELING
25+
// #define SATCHECK_CADICAL
2526

2627
#if defined(HAVE_IPASIR) && !defined(SATCHECK_IPASIR)
2728
#define SATCHECK_IPASIR
@@ -59,6 +60,10 @@ Author: Daniel Kroening, [email protected]
5960
#define SATCHECK_LINGELING
6061
#endif
6162

63+
#if defined(HAVE_CADICAL) && !defined(SATCHECK_CADICAL)
64+
#define SATCHECK_CADICAL
65+
#endif
66+
6267
#if defined SATCHECK_ZCHAFF
6368

6469
#include "satcheck_zchaff.h"
@@ -122,6 +127,13 @@ typedef satcheck_lingelingt satcheck_no_simplifiert;
122127
typedef satcheck_glucose_simplifiert satcheckt;
123128
typedef satcheck_glucose_no_simplifiert satcheck_no_simplifiert;
124129

130+
#elif defined SATCHECK_CADICAL
131+
132+
#include "satcheck_cadical.h"
133+
134+
typedef satcheck_cadicalt satcheckt;
135+
typedef satcheck_cadicalt satcheck_no_simplifiert;
136+
125137
#endif
126138

127139
#endif // CPROVER_SOLVERS_SAT_SATCHECK_H

src/solvers/sat/satcheck_cadical.cpp

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include "satcheck_cadical.h"
10+
11+
#include <util/invariant.h>
12+
#include <util/threeval.h>
13+
14+
#ifdef HAVE_CADICAL
15+
16+
#include <cadical.hpp>
17+
18+
tvt satcheck_cadicalt::l_get(literalt a) const
19+
{
20+
if(a.is_constant())
21+
return tvt(a.sign());
22+
23+
tvt result;
24+
25+
if(a.var_no() > static_cast<unsigned>(solver->max()))
26+
return tvt(tvt::tv_enumt::TV_UNKNOWN);
27+
28+
const int val = solver->val(a.dimacs());
29+
if(val>0)
30+
result = tvt(true);
31+
else if(val<0)
32+
result = tvt(false);
33+
else
34+
return tvt(tvt::tv_enumt::TV_UNKNOWN);
35+
36+
return result;
37+
}
38+
39+
const std::string satcheck_cadicalt::solver_text()
40+
{
41+
return std::string("CaDiCaL ") + solver->version();
42+
}
43+
44+
void satcheck_cadicalt::lcnf(const bvt &bv)
45+
{
46+
for(const auto &lit : bv)
47+
{
48+
if(lit.is_true())
49+
return;
50+
else if(!lit.is_false())
51+
INVARIANT(lit.var_no() < no_variables(), "reject out of bound variables");
52+
}
53+
54+
for(const auto &lit : bv)
55+
{
56+
if(!lit.is_false())
57+
{
58+
// add literal with correct sign
59+
solver->add(lit.dimacs());
60+
}
61+
}
62+
solver->add(0); // terminate clause
63+
64+
clause_counter++;
65+
}
66+
67+
propt::resultt satcheck_cadicalt::prop_solve()
68+
{
69+
INVARIANT(status != statust::ERROR, "there cannot be an error");
70+
71+
messaget::status() << (no_variables() - 1) << " variables, " << clause_counter
72+
<< " clauses" << eom;
73+
74+
if(status == statust::UNSAT)
75+
{
76+
messaget::status() << "SAT checker inconsistent: instance is UNSATISFIABLE"
77+
<< eom;
78+
}
79+
else
80+
{
81+
switch(solver->solve())
82+
{
83+
case 10:
84+
messaget::status() << "SAT checker: instance is SATISFIABLE" << eom;
85+
status = statust::SAT;
86+
return resultt::P_SATISFIABLE;
87+
case 20:
88+
messaget::status() << "SAT checker: instance is UNSATISFIABLE" << eom;
89+
break;
90+
default:
91+
messaget::status() << "SAT checker: solving returned without solution"
92+
<< eom;
93+
throw "solving inside CaDiCaL SAT solver has been interrupted";
94+
}
95+
}
96+
97+
status = statust::UNSAT;
98+
return resultt::P_UNSATISFIABLE;
99+
}
100+
101+
void satcheck_cadicalt::set_assignment(literalt a, bool value)
102+
{
103+
INVARIANT(!a.is_constant(), "cannot set an assignment for a constant");
104+
INVARIANT(false, "method not supported");
105+
}
106+
107+
satcheck_cadicalt::satcheck_cadicalt() :
108+
solver(new CaDiCaL::Solver())
109+
{
110+
solver->set("quiet", 1);
111+
}
112+
113+
satcheck_cadicalt::~satcheck_cadicalt()
114+
{
115+
delete solver;
116+
}
117+
118+
void satcheck_cadicalt::set_assumptions(const bvt &bv)
119+
{
120+
INVARIANT(false, "method not supported");
121+
}
122+
123+
bool satcheck_cadicalt::is_in_conflict(literalt a) const
124+
{
125+
INVARIANT(false, "method not supported");
126+
return false;
127+
}
128+
129+
#endif

src/solvers/sat/satcheck_cadical.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
10+
#ifndef CPROVER_SOLVERS_SAT_SATCHECK_CADICAL_H
11+
#define CPROVER_SOLVERS_SAT_SATCHECK_CADICAL_H
12+
13+
#include "cnf.h"
14+
15+
namespace CaDiCaL // NOLINT(readability/namespace)
16+
{
17+
class Solver; // NOLINT(readability/identifiers)
18+
}
19+
20+
class satcheck_cadicalt:public cnf_solvert
21+
{
22+
public:
23+
satcheck_cadicalt();
24+
virtual ~satcheck_cadicalt();
25+
26+
virtual const std::string solver_text();
27+
virtual resultt prop_solve();
28+
virtual tvt l_get(literalt a) const;
29+
30+
virtual void lcnf(const bvt &bv);
31+
virtual void set_assignment(literalt a, bool value);
32+
33+
virtual void set_assumptions(const bvt &_assumptions);
34+
virtual bool has_set_assumptions() const { return false; }
35+
virtual bool has_is_in_conflict() const { return false; }
36+
virtual bool is_in_conflict(literalt a) const;
37+
38+
protected:
39+
// NOLINTNEXTLINE(readability/identifiers)
40+
CaDiCaL::Solver * solver;
41+
};
42+
43+
#endif // CPROVER_SOLVERS_SAT_SATCHECK_CADICAL_H

0 commit comments

Comments
 (0)