Skip to main content

dratify

Check a DRAT/DRUP proof of unsatisfiability, inside your Python process.

A SAT solver that answers "unsatisfiable" is asking to be trusted. A DRAT proof is how it stops asking: the solver logs every clause it derives, and a checker that shares no code with it replays the log and confirms the empty clause really follows.

Emitting those proofs is routine. PySAT exposes them from six solver families with with_proof=True / get_proof(). Checking them from Python has not been practical: drat-trim is C you compile and shell out to, and the only checker on PyPI installs on Linux x86-64 under Python ≤ 3.10 alone.

pip install dratify              # pure Python, zero dependencies

The same checker is published as a Rust crate, for use from Rust directly:

cargo add dratify                # https://crates.io/crates/dratify

Want the Rust checker from Python? This package deliberately ships no compiled extension of its own -- installing a proof checker should never need a toolchain. Instead it exposes a seam, register_native(), and anything that already embeds the crate can supply an implementation. Today that is cdclkit-native:

pip install "cdclkit[native]"    # brings wheels that register with dratify

After that, engine="auto" uses the Rust checker (~18x faster on large proofs) with no further configuration.

Check a proof from PySAT

from pysat.formula import CNF as PyCNF
from pysat.solvers import Glucose42
from dratify import parse_dimacs, check_proof

cnf = PyCNF(from_file="problem.cnf")
with Glucose42(bootstrap_with=cnf, with_proof=True) as s:
    assert not s.solve()
    proof = s.get_proof()

result = check_proof(parse_dimacs(cnf.to_dimacs()), "\n".join(proof))
print(result.ok)          # True -- the refutation is genuine

No subprocess, no compiler, no temporary files.

Two engines, and that is the point

Proof checking is the one domain where two independent implementations agreeing is the evidence. This ships both:

Pure Python zero dependencies, runs anywhere Python does
Rust (crate) ~18x faster; reachable from Python via register_native()

Neither is the "real" one. They have been differentially tested against each other on acceptances and on rejections, and they agree.

check_proof(formula, proof, engine="python")   # always available
check_proof(formula, proof, engine="native")   # once an implementation is registered
check_proof(formula, proof, engine="auto")     # default: native when present

What it checks

  • RUP (reverse unit propagation) — the common case.
  • RAT (resolution asymmetric tautology) — the "A" in DRAT, checked properly: pivot on the first literal, resolvent against every clause containing its negation, RUP on each.
  • Deletion, applied by default. Deletion is monotone-safe for RUP; RAT is not monotone, so RAT steps are checked against exactly the clauses present.

Checking is forward: every step is verified, rather than working backwards from the empty clause as drat-trim does. That makes it slower on large proofs and means a corrupted step is caught where it occurs.

Speed

Measured against drat-trim (which does backward checking by default):

proof steps pure Python Rust drat-trim
uuf100-01 774 0.01s 0.01s 0.05s
uuf100-010 1,103 0.05s 0.00s 0.06s
uuf250-01 209,367 41.47s 2.27s 1.30s

Rust wins on small proofs — drat-trim pays process startup and cannot be called in-process — and loses 1.75x on the large one, while checking forward.

On 10 proofs from two solvers, dratify and drat-trim agreed on every case, including four rejections.

Honest limitations

  • Forward checking only. Backward checking would close the large-proof gap.
  • No binary DRAT format yet; text proofs only.
  • Not formally verified. It is carefully written, differentially tested against a second implementation, and cross-validated against drat-trim — which is not the same thing as a machine-checked proof of the checker itself. If you need that, cake_lpr is CakeML-verified and consumes LRAT.

Related

cdclkit (source) is a from-scratch CDCL SAT solver by the same author that uses this package to check its own refutations. You do not need it to use dratify — checking a proof should never require installing a solver, which is why these are separate packages.

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

dratify-0.1.2.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dratify-0.1.2-py3-none-any.whl (22.5 kB view details)

Uploaded Python 3

File details

Details for the file dratify-0.1.2.tar.gz.

File metadata

  • Download URL: dratify-0.1.2.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dratify-0.1.2.tar.gz
Algorithm Hash digest
SHA256 ba0780227830bd8632b5aca4389b40cad267853a7ce4932991f3f8d239b6bd6e
MD5 3309cd4fa31e3dc32ab662d73747edeb
BLAKE2b-256 5ddb87e4537ddadd55cbb668005dfb245efe1e45ff92d231c3439dd6888661ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for dratify-0.1.2.tar.gz:

Publisher: release.yml on carlok/dratify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dratify-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: dratify-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 22.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dratify-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2a72f4d6941f03238bc2c869b8af666e30a6350d2c5ccaaba04dedda2dcae217
MD5 57e979ec152187d2c49b93e2aadcb63c
BLAKE2b-256 bf671f17ee4988be1a4cc11f913f939e302bea30a10b86455980689a99c9ef2d

See more details on using hashes here.

Provenance

The following attestation bundles were made for dratify-0.1.2-py3-none-any.whl:

Publisher: release.yml on carlok/dratify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page