cdclkit
A conflict-driven clause-learning SAT solver, a preprocessor, an encoding library and a modelling layer — written from scratch in readable Python.
Every answer comes with a certificate, and the certificate gets checked.
pip install cdclkit # pure Python
pip install "cdclkit[native]" # plus the Rust engine, ~18x faster
Three packages, and no third-party code:
cdclkit,
dratify (the proof checker, zero
dependencies), and optionally
cdclkit-native (abi3 wheels for
Linux and macOS).
python3 -m cdclkit solve instance.cnf --self-check --check-model
- SAT → the model is re-evaluated against the input formula, clause by clause.
- UNSAT → the solver emits a DRAT proof and
dratifyreplays it, confirming every derived clause really follows and the empty clause is reached.
A solver that says "unsatisfiable" and offers nothing else is asking to be trusted. This one hands you the proof — and the checker that reads it shares no code with the solver that wrote it.
Quick start
from cdclkit import parse_dimacs, solve
formula = parse_dimacs("p cnf 2 4\n1 2 0\n1 -2 0\n-1 2 0\n-1 -2 0\n")
sat, model = solve(formula)
print(sat) # False -- and `solve` returns (False, None)
Note the shape: solve() returns a tuple, so if solve(f): is always
true. Unpack it.
Worked examples live in examples/ — Sudoku with a uniqueness proof, the zebra
puzzle, graph colouring, bounded model checking, circuit equivalence.
What's in it
| module | what it does |
|---|---|
solver |
CDCL: two watched literals, first-UIP learning, LBD, Luby restarts, phase saving, target phases, probSAT rephasing |
preprocess |
subsumption, self-subsumption, blocked-clause elimination, pure literals, bounded variable elimination with model reconstruction |
encodings |
at-most-one (pairwise, binary, commander), cardinality (sequential, totalizer), pseudo-Boolean |
model |
a modelling layer — integer variables, all-different, differential encoding |
mus |
minimal unsatisfiable subsets, deletion-based and QuickXplain |
portfolio |
parallel configurations |
pyeq |
experimental — bounded equivalence of two Python integer functions |
An optional Rust engine (cdclkit-native)
is roughly 18x faster
and bit-exact with the Python one: identical conflicts, decisions and
propagations on every instance. The pure-Python path has zero third-party
dependencies and is the one that must never break.
Relationship to dratify
Proof checking lives in a separate package,
dratify
(source, also a
Rust crate), which cdclkit depends on.
That split is deliberate:
- You should not have to install a SAT solver to verify a proof someone else produced.
- The checker stays small enough to audit, which is the point of a checker.
cdclkitexercises it on every test run, so the checker is dogfooded by the solver rather than only by its own suite.
dratify has no dependencies of its own, so installing cdclkit pulls in no
third-party code. With [native], cdclkit-native hands its compiled checker
to dratify through register_native(), so proof checking gets the Rust
implementation too rather than only the solver.
Performance
See BENCHMARKS.md. Read the caveats there before quoting any
number — in particular, all figures come from a single machine, and the
comparison against kissat is against its default configuration on a public
benchmark suite whose instances are small enough that process startup is part
of what is being measured.
If you need raw speed, install PySAT: it ships kissat, CaDiCaL and Glucose as binary wheels on every platform. This project is not trying to beat them. It is trying to be a complete, readable, self-checking implementation you can audit.
Honest limitations
- No Windows. Never tested; the classifiers say so rather than implying support.
- Pure Python is ~18x slower than its own Rust port, which is itself far from kissat. Not a tool for competition-scale instances.
- No inprocessing, no XOR/Gaussian reasoning. Parity families are a known
weakness and
bench/includes one to keep that visible. pyeqmodels a small subset of Python and is experimental. Measured against CrossHair on a 48-function corpus it found nothing CrossHair missed (0 of 105). Seeexperiments/pyeq-llm-refactor/report.mdfor the full negative result.- Every performance figure comes from one machine.
Documentation
- docs/ALGORITHMS.md — the mathematics, from resolution through first-UIP, LBD, DRAT, encodings and preprocessing, including a section on what is deliberately absent.
- docs/ROADMAP.md — what is planned, in sprints.
- docs/RELEASING.md — the release checklist.
Licence
Apache-2.0. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdclkit-0.1.2.tar.gz.
File metadata
- Download URL: cdclkit-0.1.2.tar.gz
- Upload date:
- Size: 119.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16daaee39cbc0d446b1c4a5cfae0348f0c7fe0a93f03867a2635d3a7c9340b68
|
|
| MD5 |
181f3ae43e6f3d02ab7e6190f24ee12d
|
|
| BLAKE2b-256 |
1a5be858e99cb5e4a60659be065d709bd3e50919e5c7d9f16bc9efcee56fcba4
|
Provenance
The following attestation bundles were made for cdclkit-0.1.2.tar.gz:
Publisher:
release.yml on carlok/cdclkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdclkit-0.1.2.tar.gz -
Subject digest:
16daaee39cbc0d446b1c4a5cfae0348f0c7fe0a93f03867a2635d3a7c9340b68 - Sigstore transparency entry: 2640721211
- Sigstore integration time:
-
Permalink:
carlok/cdclkit@b83704560a4105ffec1be7a0bc59409282d92fb0 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/carlok
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b83704560a4105ffec1be7a0bc59409282d92fb0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cdclkit-0.1.2-py3-none-any.whl.
File metadata
- Download URL: cdclkit-0.1.2-py3-none-any.whl
- Upload date:
- Size: 83.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b08802a7ad4dd4649830d80048d1d337b10adda89b0d3cf554edf1c5a11ca91
|
|
| MD5 |
92fb0e6959c3d3916cec11dee45f1427
|
|
| BLAKE2b-256 |
f2215caae65d1895309f4ac6f57c15877bfdaef165ebf381202ebdca9d33c06c
|
Provenance
The following attestation bundles were made for cdclkit-0.1.2-py3-none-any.whl:
Publisher:
release.yml on carlok/cdclkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdclkit-0.1.2-py3-none-any.whl -
Subject digest:
8b08802a7ad4dd4649830d80048d1d337b10adda89b0d3cf554edf1c5a11ca91 - Sigstore transparency entry: 2640721579
- Sigstore integration time:
-
Permalink:
carlok/cdclkit@b83704560a4105ffec1be7a0bc59409282d92fb0 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/carlok
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b83704560a4105ffec1be7a0bc59409282d92fb0 -
Trigger Event:
push
-
Statement type: