cadical
A Ruby binding for CaDiCaL, a state-of-the-art incremental SAT solver. The CaDiCaL C++ sources are vendored and compiled straight into the extension, so there is no external dependency.
This is a thin, general-purpose binding over CaDiCaL's C API (ccadical_*). The Ruby class is
CaDiCaL, and CaDiCaL.new creates a solver.
Installation
gem install cadical
Building the extension requires a C++17 compiler.
Usage
A literal is an Integer in DIMACS form: positive v = "variable v is true", -v =
false. A clause is just a list of literals.
require "cadical"
c = CaDiCaL.new
x1, x2 = c.new_var, c.new_var
c.add(x1, x2) # (x1 \/ x2)
c.add(x1, -x2) # (x1 \/ !x2)
c.add(-x1, -x2) # (!x1 \/ !x2)
c.solve # => :sat
c.true?(x1) # => true
c.true?(x2) # => false
Incremental solving
Clauses added with #add stay for good, so you can keep solving as you learn more. An
assumption is a temporary hypothesis for the next #solve only -- handy to pose what-if
questions without rebuilding the formula:
c.assume(-x1) # what if x1 were false?
c.solve # => :unsat -- the clauses above force x1 true
c.solve # => :sat again; the assumption is already gone
A constraint is the same idea but a whole clause (a disjunction), at most one at a time:
c.constrain(-x1, x2) # require (!x1 \/ x2) for the next solve only
c.solve # => :unsat
c.constraint_failed? # => true -- the constraint is what made it unsat
API
CaDiCaL (every ccadical_* function, plus a couple of conveniences)
| method | C function | description | ||
|---|---|---|---|---|
CaDiCaL.signature |
ccadical_signature |
the bundled CaDiCaL version string | ||
CaDiCaL.new |
ccadical_init |
create a solver | ||
#release |
ccadical_release |
free the solver now (else at GC) | ||
#add(*lits) |
ccadical_add |
add a permanent clause (splat an array: add(*clause)) |
||
#assume(lit) |
ccadical_assume |
assume a literal for the next solve only |
||
#constrain(*lits) |
ccadical_constrain |
temporary constraint clause for the next solve |
||
#constraint_failed? |
ccadical_constraint_failed |
did the constraint cause the last UNSAT? | ||
#solve |
ccadical_solve |
solve -> :sat / :unsat / :unknown |
||
#simplify |
ccadical_simplify |
inprocessing -> :sat / :unsat / :unknown |
||
#val(lit) |
ccadical_val |
raw model value (signed literal) | ||
#failed(lit) |
ccadical_failed |
did this assumption take part in the last UNSAT core? | ||
#fixed(lit) |
ccadical_fixed |
1 / -1 / 0: proven true / false / not yet fixed |
||
#set_terminate { } |
ccadical_set_terminate |
abort solve when the block is truthy (no block clears) |
||
| `#set_learn(max) { \ | clause\ | }` | ccadical_set_learn |
observe learned clauses (no block clears) |
#terminate |
ccadical_terminate |
force the running solve to stop | ||
#declare_one_more_variable |
ccadical_declare_one_more_variable |
allocate one fresh variable | ||
#declare_more_variables(n) |
ccadical_declare_more_variables |
allocate n variables |
||
#vars |
ccadical_vars |
number of variables | ||
#phase(lit) / #unphase(lit) |
ccadical_phase / ccadical_unphase |
set / clear a forced decision phase | ||
#freeze_lit(lit) / #melt_lit(lit) / #frozen_lit?(lit) |
ccadical_freeze / _melt / _frozen |
freeze a literal against elimination | ||
#set_option(name, v) / #get_option(name) |
ccadical_set_option / _get_option |
options | ||
#limit(name, v) |
ccadical_limit |
set a solve limit | ||
#active / #irredundant |
ccadical_active / _irredundant |
active-variable / irredundant-clause counts | ||
#trace_proof(path) / #close_proof / #conclude |
ccadical_trace_proof / _close_proof / _conclude |
DRAT proof tracing | ||
#new_var |
-- | alias for #declare_one_more_variable |
||
#true?(lit) |
-- | convenience boolean: is lit assigned true? |
||
#true_var / #false_var |
-- | a variable pinned true / false, usable as a constant literal |
Notes
Unlike many SAT-solver APIs where any integer can be used as a literal directly, the bundled
CaDiCaL (with its defaults) rejects a literal whose variable was not produced by #new_var
(the examples above use it). Set c.set_option("factor", 0) to allow raw integer literals.
License
MIT. The bundled CaDiCaL solver (ext/cadical/cadical/) is also MIT-licensed; see
ext/cadical/cadical/LICENSE.