{"id":13748657,"url":"https://github.com/snsinfu/dpll-sat","last_synced_at":"2026-02-07T21:35:08.137Z","repository":{"id":45644524,"uuid":"355985651","full_name":"snsinfu/dpll-sat","owner":"snsinfu","description":"Naïve SAT solver implementing the classic DPLL algorithm","archived":false,"fork":false,"pushed_at":"2021-04-13T16:03:11.000Z","size":549,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-22T19:32:00.611Z","etag":null,"topics":["dpll-algorithm","learning","sat-solver"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snsinfu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-08T16:53:39.000Z","updated_at":"2022-07-14T12:51:27.000Z","dependencies_parsed_at":"2022-07-19T12:59:06.664Z","dependency_job_id":null,"html_url":"https://github.com/snsinfu/dpll-sat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snsinfu%2Fdpll-sat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snsinfu%2Fdpll-sat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snsinfu%2Fdpll-sat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snsinfu%2Fdpll-sat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snsinfu","download_url":"https://codeload.github.com/snsinfu/dpll-sat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253240350,"owners_count":21876593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dpll-algorithm","learning","sat-solver"],"created_at":"2024-08-03T07:00:46.768Z","updated_at":"2026-02-07T21:35:07.689Z","avatar_url":"https://github.com/snsinfu.png","language":"Rust","funding_links":[],"categories":["Projects"],"sub_categories":["Provers and Solvers"],"readme":"# dpll-sat\n\n[![Build Status][build-badge]][build-url]\n\n[build-badge]: https://github.com/snsinfu/dpll-sat/workflows/test/badge.svg\n[build-url]: https://github.com/snsinfu/dpll-sat/actions?query=workflow%3Atest\n\n**dpll-sat** is a SAT solver implementing the classic [DPLL algorithm][dpll]. I\nwrote this program for learning purposes and also for comparing the performance\nof a naive DPLL solver and modern solvers.\n\n- [Build](#build)\n- [Usage](#usage)\n- [Implementation notes](#implementation-notes)\n- [Benchmarks](#benchmarks)\n- [References](#references)\n\n[dpll]: https://en.wikipedia.org/wiki/DPLL_algorithm\n\n## Build\n\n```console\n$ git clone https://github.com/snsinfu/dpll-sat\n$ cd dpll-sat\n$ cargo build --release\n$ cp target/release/dpll-sat ~/bin/\n```\n\n## Usage\n\n**dpll-sat** command reads [a simplified DIMACS CNF][format] from stdin. It\nprints \"sat\" followed by an assignment and exits with exit code 0 if the formula\nis satisfiable. Otherwise, it prints \"unsat\" and exits with exit code 1.\n\n```console\n$ dpll-sat \u003c examples/qg3-08.cnf\nsat\n1 2 3 4 5 6 7 8 -9 -10 -11 -12 -13 -14 -15 -16 -17 ...\n```\n\nThe second line shows an assignment. A positive number `i` means that the i-th\nvariable is true. A negative number `-i` means that the i-th variable is false.\nThe output format is essentially the same as that of [z3][z3].\n\n[format]: http://www.satcompetition.org/2011/format-benchmarks2011.html\n[z3]: https://github.com/Z3Prover/z3\n\n## Implementation notes\n\nThe algorithm is implemented in the following way in pseudocode:\n\n```javascript\nfunction DPLL(formula, vars) {\n    // Simplify formula by determining variables in unit clauses.\n    formula = copy(formula);\n    unit_propagate(formula, vars);\n\n    // Stopping conditions.\n    if (formula is empty) {\n        return \"SAT\";\n    }\n    if (empty clause in formula) {\n        return \"UNSAT\";\n    }\n\n    // Choose a branching literal and recurse.\n    v = choose_literal(formula);\n\n    return DPLL(formula + [v], vars) || DPLL(formula + [not(v)], vars);\n}\n```\n\n- Pure literal elimination is not implemented due to the complexity of keeping\n  track of the polarity of every literal in a formula.\n- The branching literal is chosen to be the most-used variable in a formula.\n  The literal is eliminated in the next recursion, so this strategy eagerly\n  reduces the size of the formula.\n- Every recursion creates a new copy of a formula. This is inefficient. The copy\n  is necessary because the algorithm eliminates some clauses and literals in a\n  formula and later revert it for backtracking. But, most clauses are untouched.\n  There would be a clever data structure that can reduce the number of copies.\n  Maybe deque?\n- A formula is represented as a vector-of-vectors. It's horribly inefficient\n  since a formula tends to consist of many small clauses, making memory access\n  extremely scattered. It would be much better to use a flat vector with\n  sentinel values.\n\n## Benchmarks\n\nRun time for some benchmark instances found on [the satlib site][satlib] and a\n[benchmark page][bench]. The run time is the total \"USER\" time spent from a\nprogram startup to termination. Benchmarks ran on Fedora 33 Linux with AMD Ryzen\n3600 CPU @ 4.2GHz (boost).\n\n| Instance                                  | #var | #clause | dpll   | z3     | cadical |\n|-------------------------------------------|------|---------|--------|--------|---------|\n| Random 3-SAT CBS_k3_n100_m403_b10_0.cnf   | 100  | 403     | 0.03s  |  0.01s | 0.00s   |\n| blocksworld huge.cnf                      | 459  | 7054    | 0.15s  |  0.00s | 0.00s   |\n| SAT-02 glassy-sat-sel_N210_n.shuffled.cnf | 210  | 980     | 215min |  0.85s | 0.31s   |\n| SAT-02 homer10.shuffled.cnf               | 360  | 3460    | \u003e 1day | 12.77s | 4.22s   |\n\nZ3 does pretty good job considering [CaDiCaL][cadical] is the top-1 winner in\nthe SAT track of the SAT Race 2019.\n\n[satlib]: https://www.cs.ubc.ca/~hoos/SATLIB/\n[bench]: https://www.cs.ubc.ca/~hoos/SATLIB/benchm.html\n[cadical]: http://fmv.jku.at/cadical/\n\n## References\n\nThis lecture note is useful to understand the DPLL algorithm:\n\n- http://www.cs.cornell.edu/courses/cs4860/2009sp/lec-04.pdf\n\nThis book has a ton of examples:\n\n- https://sat-smt.codes/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnsinfu%2Fdpll-sat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnsinfu%2Fdpll-sat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnsinfu%2Fdpll-sat/lists"}