{"id":13748671,"url":"https://github.com/timbeurskens/rsbdd","last_synced_at":"2026-02-23T14:40:36.020Z","repository":{"id":39915432,"uuid":"437308048","full_name":"timbeurskens/rsbdd","owner":"timbeurskens","description":"A Reduced-order Binary Decision Diagram (RoBDD) SAT solver written in Rust","archived":false,"fork":false,"pushed_at":"2025-04-22T08:51:30.000Z","size":349,"stargazers_count":7,"open_issues_count":6,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-09T11:33:54.927Z","etag":null,"topics":["binary-decision-diagrams","boolean-satisfiability","np-complete","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timbeurskens.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-12-11T14:44:37.000Z","updated_at":"2025-04-16T11:07:01.000Z","dependencies_parsed_at":"2024-04-18T09:26:32.638Z","dependency_job_id":"aa34bdd9-98f9-4c94-8fbc-2af801bcf6b5","html_url":"https://github.com/timbeurskens/rsbdd","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/timbeurskens/rsbdd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Frsbdd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Frsbdd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Frsbdd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Frsbdd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timbeurskens","download_url":"https://codeload.github.com/timbeurskens/rsbdd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Frsbdd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29745900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["binary-decision-diagrams","boolean-satisfiability","np-complete","sat-solver"],"created_at":"2024-08-03T07:00:47.134Z","updated_at":"2026-02-23T14:40:35.972Z","avatar_url":"https://github.com/timbeurskens.png","language":"Rust","funding_links":[],"categories":["Projects"],"sub_categories":["Provers and Solvers"],"readme":"# RsBDD\n\n[![Rust](https://github.com/timbeurskens/rsbdd/actions/workflows/rust.yml/badge.svg)](https://github.com/timbeurskens/rsbdd/actions/workflows/rust.yml)\n\n_Solving satisfiability problems in Rust_\n\n## Installation\n\n1) Make sure to install the [Rust toolchain](https://www.rust-lang.org/tools/install).\n\n2) Clone the latest version of this repository:\n\n```\n$ git clone git@github.com:timbeurskens/rsbdd.git\n```\n\n3) Build and install the RsBDD tools:\n\n```\n$ cd rsbdd\n$ cargo install --bins --path .\n```\n\nThe following tools will be available after installing the RsBDD package:\n\n- `max_clique_gen`\n- `n_queens_gen`\n- `random_graph_gen`\n- `rsbdd`\n- `sudoku_gen`\n\n## Syntax\n\n### Comments\n\nCharacters contained within \"...\" (excluding the \" char itself) are regarded as comments and can be placed at any point\nin the formula.\n\n### Constants\n\nThe most basic building blocks of the syntax are 'variables' and 'constants'. A constant can be either 'true' or '\nfalse'. A variable can accept either a 'true' or 'false' value after evaluation depending on its environment.\n\n```\ntrue\nfalse\n```\n\n### Variables\n\nA variable is a single word starting with a non-digit character. Examples of good variable names are:\n\n```\na\na'\nalpha\n_x\na1\nhello_world\n```\n\n### Negation\n\nA variable, constant, or sub-formula can be negated using the negation operator. This operator can be expressed by\neither `!`, `-`, or `not`.\n\n```\nnot true\n-false\n!variable\n```\n\n### Binary operators\n\nRsBDD supports the most common, and some uncommon binary operators, such as conjunction, disjunction, implication and\nbi-implication.\n\nMost operators have a symbolic and textual representation, e.g. `and` or `\u0026`.\n\n| Operator           | Option 1          | Option 2 |\n|--------------------|-------------------|----------|\n| Conjunction        | `and`             | `\u0026`      |\n| Disjunction        | `or`              | `\\|`     |\n| Implication        | `implies` or `in` | `=\u003e`     |\n| Bi-implication     | `iff` or `eq`     | `\u003c=\u003e`    |\n| Exlusive or        | `xor`             | `^`      |\n| Joint denial       | `nor`             | N.A.     |\n| Alternative denial | `nand`            | N.A.     |\n\n```\ntrue or false\ntrue | false\na | b\na \u0026 b\na and b\na =\u003e b\nhello \u003c=\u003e world\non ^ off\n```\n\n### Composition\n\nLarger formulae can be composed using left and right parentheses: `(`, `)`:\n\n```\na | (a \u0026 b)\n(a)\n((a))\n!(a \u0026 b)\n(a \u0026 b) | (b \u0026 c)\n```\n\n### If-then-else\n\nA simplification of a common expression `(a =\u003e b) \u0026 ((!a) =\u003e c)` can be made using the ternary if-then-else (ite)\noperator.\n\n```\nif a then b else c\nif exists a # a \u003c=\u003e b then b \u003c=\u003e c else false | c\n```\n\n### Quantifiers\n\nThe RsBDD supports universal and existential quantification using the `exists` and `forall`/`all`\nkeywords: `{forall|exists} var_1, var_2, .., var_n # {subformula}`\n\n```\nforall a # true\nforall a # a | b\nforall a, b # exists c # (c | a) \u0026 (c | b)\n```\n\n### Counting\n\nFor some problems it can be beneficial to express properties relating to the number of true or false variables, e.g. \"at\nleast 2 of the 4 properties must hold\".\n\nThe counting operator (`[]`) in combination with five new equality and inequality operators (`=`, `\u003c=`, `\u003e=`, `\u003c`, `\u003e`)\ncan be used to concisely express these properties.\n\n_Note:_ like most operators, the counting operator can be expressed using logic primitives, but this operator simplifies\nthe expression significantly.\n\nA counting comparison can either be made by comparing a set of expressions to a given constant, or an other set of\nexpressions.\n\n```\n\"exactly one of a, b, and c holds\"\n[a, b, c] = 1\n\n\"there are strictly less true expressions in a, b, c than d, e, f\"\n[a, b, c] \u003c [d, e, f]\n```\n\nCounting comparison also allows us to specify optimization problems.\nExample: the max-clique problem can be described as a clique problem, such that\nfor all satisfiable cliques, the reported result is the largest.\n\n```\n-(a \u0026 f) \u0026\n-(a \u0026 g) \u0026\n\n-(b \u0026 d) \u0026\n-(b \u0026 e) \u0026\n\n-(c \u0026 e) \u0026\n-(c \u0026 g) \u0026\n\nforall _a,_b,_c,_d,_e,_f,_g # (\n    -(_a \u0026 _f) \u0026\n    -(_a \u0026 _g) \u0026\n    -(_b \u0026 _d) \u0026\n    -(_b \u0026 _e) \u0026\n    -(_c \u0026 _e) \u0026\n    -(_c \u0026 _g)\n) =\u003e [a,b,c,d,e,f,g] \u003e= [_a,_b,_c,_d,_e,_f,_g]\n```\n\n### Fixed points\n\nThe rsbdd language supports least-fixpoint (`lfp` / `mu`) and greatest-fixpoint (`gfp` / `nu`) operations to find a\nrespectively minimal or maximal solution by repeatedly applying a given transformer function until the solution is\nstable.\n\nOnly monotonic transformer functions are guaranteed to terminate. Termination of fixed point operations are not checked\nand will run indefinatedly if not handled correctly.\n\nIts basic properties are defined as follows.\n\n```\ngfp X # X           \u003c=\u003e true\nlfp X # X           \u003c=\u003e false\n\nnu X # ...          \u003c=\u003e gfp X # ...\nmu X # ...          \u003c=\u003e lfp X # ...\n\ngfp/lfp X # a       \u003c=\u003e a\ngfp/lfp X # true    \u003c=\u003e true\ngfp/lfp X # false   \u003c=\u003e false\n```\n\n### Parse-tree display\n\nAdding the `-p {path}` argument to `rsbdd` constructs a graphviz graph of the parse-tree. This can be used to for\nintrospection of the intended formula, or for reporting purposes. An example of the parse-tree output\nfor `exists b,c # a | (b ^ c)` is displayed below.\n\n![parse tree](docs/images/parsetree.svg)\n\n### Experimental and/or upcoming features\n\nCurrently the RsBDD language relies heavily on logical primitives. Integer arithmetic could be expressed by manually\nintroducing the primitive 'bits' of a number. Rewrite rules could significantly simplify this process by introducting\ndomains other than boolean variables. Embedding rewrite rules in the BDD could prove to be a challenge.\n\n## Examples\n\n### Example 1: transitivity of the `\u003e=` operator\n\n```\n([a1,a2,a3,a4] \u003e= [b1,b2,b3,b4] \u0026 [b1,b2,b3,b4] \u003e= [c1,c2,c3,c4]) =\u003e [a1,a2,a3,a4] \u003e= [c1,c2,c3,c4]\n```\n\n### Example 2: the 4 queens problem\n\nThe famous n-queens problem can be expressed efficiently in the RsBDD language.\nThe example below shows a 4-queens variant, which can be solved in roughly 15 milliseconds. The library contains a\ngenerator for arbitrary n-queens problems.\nAt this point, the largest verified problem size is n=8, which reports all solutions in less than 20 minutes on modern\nhardware.\nThe explosive nature of the problem makes n=9 an infeasable problem. Further optimizations (such as multi-processor\nparallellism, or vertex ordering) could decrease the run-time in the future.\n\n```\n\"every row must contain exactly one queen\"\n[_0x0, _0x1, _0x2, _0x3] = 1 \u0026\n[_1x0, _1x1, _1x2, _1x3] = 1 \u0026\n[_2x0, _2x1, _2x2, _2x3] = 1 \u0026\n[_3x0, _3x1, _3x2, _3x3] = 1 \u0026\n\n\"every column must contain exactly one queen\"\n[_0x0, _1x0, _2x0, _3x0] = 1 \u0026\n[_0x1, _1x1, _2x1, _3x1] = 1 \u0026\n[_0x2, _1x2, _2x2, _3x2] = 1 \u0026\n[_0x3, _1x3, _2x3, _3x3] = 1 \u0026 \n\n\"every diagonal must contain at most one queen\"\n[_0x0] \u003c= 1 \u0026\n[_0x1, _1x0] \u003c= 1 \u0026\n[_0x2, _1x1, _2x0] \u003c= 1 \u0026\n[_0x3, _1x2, _2x1, _3x0] \u003c= 1 \u0026\n[_1x3, _2x2, _3x1] \u003c= 1 \u0026\n[_2x3, _3x2] \u003c= 1 \u0026\n[_3x3] \u003c= 1 \u0026\n\n\"the other diagonal\"\n[_0x3] \u003c= 1 \u0026\n[_0x2, _1x3] \u003c= 1 \u0026\n[_0x1, _1x2, _2x3] \u003c= 1 \u0026\n[_0x0, _1x1, _2x2, _3x3] \u003c= 1 \u0026\n[_1x0, _2x1, _3x2] \u003c= 1 \u0026\n[_2x0, _3x1] \u003c= 1 \u0026\n[_3x0] \u003c= 1\n```\n\nRunning this example with the following arguments yields a truth-table showing the queen configuration(s) on a 4x4 chess\nboard.\n\n```bash\nrsbdd -i examples/4_queens.txt -t -ft\n```\n\n| _0x0  | _0x1  | _0x2  | _0x3  | _1x0  | _1x1  | _1x2  | _1x3  | _2x0  | _2x1  | _2x2  | _2x3  | _3x0  | _3x1  | _3x2  | _3x3  | *    |\n|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|------|\n| False | False | True  | False | True  | False | False | False | False | False | False | True  | False | True  | False | False | True |\n| False | True  | False | False | False | False | False | True  | True  | False | False | False | False | False | True  | False | True |\n\n## CLI Usage\n\n### rsbdd\n\n```\nA BDD-based SAT solver\n\nUsage: rsbdd [OPTIONS] [FILE]\n\nArguments:\n  [FILE]  The input file containing a logic formula in rsbdd format\n\nOptions:\n  -p, --parsetree \u003cPARSETREE\u003e            Write the parse tree in dot format to the specified file\n  -t, --truthtable                       Print the truth table to stdout\n  -d, --dot \u003cDOT\u003e                        Write the bdd to a dot graphviz file\n  -m, --model                            Compute a single satisfying model as output\n  -v, --vars                             Print all satisfying variables leading to a truth value\n  -f, --filter \u003cFILTER\u003e                  Only show true or false entries in the output [default: Any]\n  -c, --retain-choices \u003cRETAIN_CHOICES\u003e  Only retain choice variables when filtering [default: Any]\n  -b, --benchmark \u003cN\u003e                    Repeat the solving process n times for more accurate performance reports\n  -g, --plot                             Use GNUPlot to plot the runtime distribution\n  -e, --evaluate \u003cEVALUATE\u003e              Parse the formula as string\n  -o, --ordering \u003cORDERING\u003e              Read a custom variable ordering from file\n  -r, --export-ordering                  Export the automatically derived ordering to stdout\n  -h, --help                             Print help\n  -V, --version                          Print version\n\n```\n\n### max_clique_gen\n\n```\nConverts a graph into a max-clique specification\n\nUsage: max_clique_gen [OPTIONS] [INPUT] [OUTPUT]\n\nArguments:\n  [INPUT]   Input file graph in csv edge-list format\n  [OUTPUT]  The output rsbdd file\n\nOptions:\n  -u, --undirected  Use undirected edges (test for both directions in the set-complement operation)\n  -a, --all         Construct a satisfiable formula for all cliques\n  -h, --help        Print help\n  -V, --version     Print version\n\n```\n\n### random_graph_gen\n\n```\nGenerates a random edge list formatted graph\n\nUsage: random_graph_gen [OPTIONS] [VERTICES] [EDGES]\n\nArguments:\n  [VERTICES]  The number of vertices in the output graph\n  [EDGES]     The number of edges in the output graph\n\nOptions:\n  -o, --output \u003cFILE\u003e   The output filename (or stdout if not provided)\n  -u, --undirected      Use undirected edges (test for both directions in the set-complement operation)\n      --complete        Construct a complete graph\n  -d, --dot             Output in dot (GraphViz) format\n      --convert \u003cFILE\u003e  If this argument is provided, the provided edge-list will be used to generate a graph\n  -c, --colors \u003cN\u003e      Generate a graph-coloring problem with N colors\n  -h, --help            Print help\n  -V, --version         Print version\n\n```\n\n### n_queens_gen\n\n```\nGenerates n-queen formulae for the SAT solver\n\nUsage: n_queens_gen [OPTIONS] [OUTPUT]\n\nArguments:\n  [OUTPUT]  The output rsbdd file\n\nOptions:\n  -n, --queens \u003cQUEENS\u003e  The number of queens [default: 4]\n  -h, --help             Print help\n  -V, --version          Print version\n\n```\n\n### sudoku_gen\n\n```\nGenerates a random edge list formatted graph\n\nUsage: sudoku_gen [OPTIONS] [INPUT] [OUTPUT]\n\nArguments:\n  [INPUT]   The input sudoku file\n  [OUTPUT]  The output rsbdd file\n\nOptions:\n  -r, --root \u003cN\u003e  The root value of the puzzle. Typically the square root of the largest possible number [default: 3]\n  -h, --help      Print help\n  -V, --version   Print version\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbeurskens%2Frsbdd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimbeurskens%2Frsbdd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbeurskens%2Frsbdd/lists"}