Skip to content

Commit c34e073

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 1bd9efd commit c34e073

File tree

8 files changed

+223
-3
lines changed

8 files changed

+223
-3
lines changed

scripts/cadical-patch

+10
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

+9
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

+5-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ else
159159
endif
160160

161161
# select default solver to be minisat2 if no other is specified
162-
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(PICOSAT),)
162+
ifeq ($(BOOLEFORCE)$(CHAFF)$(GLUCOSE)$(IPASIR)$(LINGELING)$(MINISAT)$(MINISAT2)$(PICOSAT)$(CADICAL),)
163163
MINISAT2 = ../../minisat-2.2.1
164164
endif
165165

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

198+
ifneq ($(CADICAL),)
199+
CP_CXXFLAGS += -DHAVE_CADICAL
200+
endif
201+
198202

199203

200204
first_target: all

src/config.inc

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ endif
2424
#MINISAT2 = ../../minisat-2.2.1
2525
#IPASIR = ../../ipasir
2626
#GLUCOSE = ../../glucose-syrup
27+
#CADICAL = ../../cadical
2728

2829
# Extra library for SAT solver. This should link to the archive file to be used
2930
# when linking against an IPASIR solver.
@@ -57,6 +58,10 @@ ifneq ($(GLUCOSE),)
5758
CP_CXXFLAGS += -DSATCHECK_GLUCOSE
5859
endif
5960

61+
ifneq ($(CADICAL),)
62+
CP_CXXFLAGS += -DSATCHECK_CADICAL
63+
endif
64+
6065
# Signing identity for MacOS Gatekeeper
6166

6267
OSX_IDENTITY="Developer ID Application: Daniel Kroening"

src/solvers/Makefile

+10-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ ifneq ($(LINGELING),)
6767
CP_CXXFLAGS += -DHAVE_LINGELING
6868
endif
6969

70+
ifneq ($(CADICAL),)
71+
CADICAL_SRC=sat/satcheck_cadical.cpp
72+
CADICAL_INCLUDE=-I $(CADICAL)/src
73+
CADICAL_LIB=$(CADICAL)/build/libcadical$(LIBEXT)
74+
CP_CXXFLAGS += -DHAVE_CADICAL
75+
endif
76+
7077
SRC = $(BOOLEFORCE_SRC) \
7178
$(CHAFF_SRC) \
7279
$(CUDD_SRC) \
@@ -77,6 +84,7 @@ SRC = $(BOOLEFORCE_SRC) \
7784
$(MINISAT_SRC) \
7885
$(PICOSAT_SRC) \
7986
$(SQUOLEM2_SRC) \
87+
$(CADICAL_SRC) \
8088
cvc/cvc_conv.cpp \
8189
cvc/cvc_dec.cpp \
8290
flattening/arrays.cpp \
@@ -194,7 +202,7 @@ INCLUDES += -I .. \
194202
$(CHAFF_INCLUDE) $(BOOLEFORCE_INCLUDE) $(MINISAT_INCLUDE) $(MINISAT2_INCLUDE) \
195203
$(IPASIR_INCLUDE) \
196204
$(SQUOLEM2_INC) $(CUDD_INCLUDE) $(GLUCOSE_INCLUDE) \
197-
$(PICOSAT_INCLUDE) $(LINGELING_INCLUDE)
205+
$(PICOSAT_INCLUDE) $(LINGELING_INCLUDE) $(CADICAL_INCLUDE)
198206

199207
CLEANFILES += solvers$(LIBEXT) \
200208
smt2_solver$(EXEEXT) smt2/smt2_solver$(OBJEXT) smt2/smt2_solver$(DEPEXT)
@@ -211,7 +219,7 @@ endif
211219

212220
SOLVER_LIB = $(CHAFF_LIB) $(BOOLEFORCE_LIB) $(MINISAT_LIB) \
213221
$(MINISAT2_LIB) $(SQUOLEM2_LIB) $(CUDD_LIB) \
214-
$(PICOSAT_LIB) $(LINGELING_LIB) $(GLUCOSE_LIB)
222+
$(PICOSAT_LIB) $(LINGELING_LIB) $(GLUCOSE_LIB) $(CADICAL_LIB)
215223

216224
###############################################################################
217225

src/solvers/sat/satcheck.h

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Author: Daniel Kroening, [email protected]
2121
// #define SATCHECK_BOOLEFORCE
2222
// #define SATCHECK_PICOSAT
2323
// #define SATCHECK_LINGELING
24+
// #define SATCHECK_CADICAL
2425

2526
#if defined(HAVE_IPASIR) && !defined(SATCHECK_IPASIR)
2627
#define SATCHECK_IPASIR
@@ -54,6 +55,10 @@ Author: Daniel Kroening, [email protected]
5455
#define SATCHECK_LINGELING
5556
#endif
5657

58+
#if defined(HAVE_CADICAL) && !defined(SATCHECK_CADICAL)
59+
#define SATCHECK_CADICAL
60+
#endif
61+
5762
#if defined SATCHECK_ZCHAFF
5863

5964
#include "satcheck_zchaff.h"
@@ -110,6 +115,13 @@ typedef satcheck_lingelingt satcheck_no_simplifiert;
110115
typedef satcheck_glucose_simplifiert satcheckt;
111116
typedef satcheck_glucose_no_simplifiert satcheck_no_simplifiert;
112117

118+
#elif defined SATCHECK_CADICAL
119+
120+
#include "satcheck_cadical.h"
121+
122+
typedef satcheck_cadicalt satcheckt;
123+
typedef satcheck_cadicalt satcheck_no_simplifiert;
124+
113125
#endif
114126

115127
#endif // CPROVER_SOLVERS_SAT_SATCHECK_H

src/solvers/sat/satcheck_cadical.cpp

+129
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

+43
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() override;
27+
virtual resultt prop_solve() override;
28+
virtual tvt l_get(literalt a) const override;
29+
30+
virtual void lcnf(const bvt &bv) override;
31+
virtual void set_assignment(literalt a, bool value) override;
32+
33+
virtual void set_assumptions(const bvt &_assumptions) override;
34+
virtual bool has_set_assumptions() const override { return false; }
35+
virtual bool has_is_in_conflict() const override { return false; }
36+
virtual bool is_in_conflict(literalt a) const override;
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)