Project

cadical

0.0
The project is in a healthy, maintained state
A Ruby binding for CaDiCaL, a state-of-the-art incremental SAT solver. The CaDiCaL C++ sources are vendored and compiled into the extension, so there is no external dependency. Supports incremental solving, assumptions, temporary constraints, fixed-literal queries and phase hints.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

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.