{"id":45601633,"url":"https://github.com/timbeurskens/gobdd","last_synced_at":"2026-02-23T14:40:35.721Z","repository":{"id":48083730,"uuid":"331324639","full_name":"timbeurskens/gobdd","owner":"timbeurskens","description":"An ROBDD \u0026 CDCL based SAT solver","archived":false,"fork":false,"pushed_at":"2021-12-11T13:55:01.000Z","size":368,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-21T11:03:20.180Z","etag":null,"topics":["bdd","boolean-algebra","cdcl","cnf","cnf-clauses","sat","sat-solver","smtlib","tseitin-transformation"],"latest_commit_sha":null,"homepage":"https://timbeurskens.github.io/gobdd/","language":"Go","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}},"created_at":"2021-01-20T14:04:55.000Z","updated_at":"2021-12-11T13:55:04.000Z","dependencies_parsed_at":"2022-08-12T18:11:04.925Z","dependency_job_id":null,"html_url":"https://github.com/timbeurskens/gobdd","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/timbeurskens/gobdd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Fgobdd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Fgobdd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Fgobdd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Fgobdd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timbeurskens","download_url":"https://codeload.github.com/timbeurskens/gobdd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timbeurskens%2Fgobdd/sbom","scorecard":{"id":885584,"data":{"date":"2025-08-11","repo":{"name":"github.com/timbeurskens/gobdd","commit":"a54f9de084bb9392347df6b444a0d87a9ed97d3b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/timbeurskens/gobdd/go.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/timbeurskens/gobdd/go.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T09:54:44.608Z","repository_id":48083730,"created_at":"2025-08-24T09:54:44.608Z","updated_at":"2025-08-24T09:54:44.608Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29745898,"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":["bdd","boolean-algebra","cdcl","cnf","cnf-clauses","sat","sat-solver","smtlib","tseitin-transformation"],"created_at":"2026-02-23T14:40:34.936Z","updated_at":"2026-02-23T14:40:35.713Z","avatar_url":"https://github.com/timbeurskens.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoBDD: Binary Decision Diagram implementation in Go\n\n[![Go](https://github.com/timbeurskens/gobdd/actions/workflows/go.yml/badge.svg)](https://github.com/timbeurskens/gobdd/actions/workflows/go.yml)\n\nThis project attempts to implement a simple boolean satifiability solver in Go using Reduced-ordered Binary Decision Diagrams.\nUsers can define their boolean equations and apply the BDD transformation to get a ROBDD (in Graphviz Dot format).\nAdditional testing methods are available to test for tautologies, contradictions and equivalence.\nEquations in CNF can be solved by applying the Conflict-Driven Clause-Learning (CDCL) method.\nThe Tseitin transformation can be applied to non-CNF formulas to get an equation in CNF which is satisfiable iff the original equation is satisfiable.\nTautology and contradiction testing for the CDCL output is not (yet) supported.\n\nThe current (BDD) based method is very inefficient and contains some problems. The N-queens problem can be solved for N=6 in roughly 6 minutes.\nModel-search in both ROBDD-based and CDCL methods is supported by this framework.\n\n## Contents\n\n- [Operators](#operators)\n  - [Boolean](#boolean)\n  - [Numeric](#numeric)\n- [Transformations](#transformations)\n  - [Unary](#unary)\n  - [Normalize](#normalize)\n  - [DeMorgan](#demorgan)\n  - [NNF](#nnf)\n  - [Tseitin](#tseitin)\n  - [CNF](#cnf)  \n- [Solvers](#solvers)\n  - [BDD](#bdd)\n  - [CDCL](#cdcl)\n- [Examples](#examples)\n  - [Tautology test for p or not p](#example-tautology-test-for-p-or-not-p)\n  - [N-queens graphical BDD model](#example-n-queens-graphical-bdd-model)\n  - [CDCL SAT solving](#example-cdcl-sat-solving)\n  - [CDCL after applying the Tseitin transformation](#example-cdcl-after-applying-the-tseitin-transformation)\n  - [Prime decomposition](#example-prime-decomposition) \n- [Known issues](#known-issues)\n\n## Operators\n\n### Boolean\n\nThe core building blocks of expressions are boolean operators, constants, and variables.\nVariables can be constructed using the `Var(str)` function, whereas constants are either identified by `TrueConst` and `FalseConst`, or constructed using `Cons(bool)`.\n\n| Operation             | Symbol | Function signature                |\n|-----------------------|:------:|-----------------------------------|\n| Negation              | ¬      | Not(Expression)                   |\n| Conjunction           | ∧      | And(Expression...)                |\n| Disjunction           | ∨      | Or(Expression...)                 |\n| Exclusive disjunction | ⊗     | Xor(Expression...)                |\n| Implication           | →      | Implies(Expression, Expression)   |\n| Bi-implication        | ⟷     | Biimplies(Expression, Expression) |\n\n### Numeric\n\nThe package \"Numerics\" contains arithmetic operations on numeric types, suitable for solving in the SAT-solvers implemented in the algorithms package.\nThis version currently only supports numerics of the \"Naturals\" class: whole numbers greater than, and including zero.\nIntegers, fractionals and fixed-point classes could be added in later versions.\nSolving numeric equations requires a significant amount of computing power.\nThe current CDCL implementation is not suitable for computing multiplications within reasonable time windows.\n\n| Operation             | Symbol* | Function signature                |\n|-----------------------|:-------:|-----------------------------------|\n| Equality              | =       | Equals(Number, Number)            |\n| Shift                 | ≪      | Shift(Number, int)                |\n| Addition              | +       | Add(Number, Number, Number)       |\n| Multiplication        | ×       | Mult(Number, Number, Number)      |\n\n*Contrary to boolean operations, symbols displayed in the numeric operations table will not be used in any of the produced diagrams by the tool.\nNumeric operations are immediately translated to their boolean counterpart and will be displayed as such.\n\n## Transformations\n\n### Unary\n\nThe BDD algorithm (`FromExpression`) assumes only binary operators exist in the given expression.\nIf the expression contains any unary operators (negations), the expression can be corrected with the `PruneUnary(Expression)` function.\nThe unary elimination algorithm recursively replaces all negations in the subtree according to the following rule:\n\n![formula](https://render.githubusercontent.com/render/math?math=\\neg%20a%20\\equiv%20a%20\\implies%20\\bot)\n\n```verbose\nNot(a) = Implies(a, false)\n```\n\n### Normalize\n\nThe `Normalize` transformation replaces all operators that are not a conjunction, disjunction or negation to an equivalent expression only containing conjunctions, disjunctions, or negations.\nThe following ruleset is applied:\n\n```verbose\na    ≡ a\n¬a   ≡ ¬a\na∧b  ≡ a∧b\na∨b  ≡ a∨b\na⊗b ≡ (a∨b)∧¬(a∧b)\na→b  ≡ ¬a∨b\na⟷b ≡ (¬a∨b)∧(¬b∨a)\n```\n\n### DeMorgan\n\nThe De Morgan transformation is applied on [normalized](#normalize) expressions to recursively move all negations to the leafs: variables and/or constants.\nThe transformation applies the following ruleset:\n\n```verbose\n¬⊤     ≡ ⊥\n¬⊥     ≡ ⊤\n¬a     ≡ ¬a\n¬(a∧b) ≡ ¬a∨¬b\n¬(a∨b) ≡ ¬a∧¬b\n```\n\n### NNF\n\nAn expression can be converted to negation-normal form such that the result is equivalent and only contains conjunctions, disjunctions and negations.\nAll negations in the resulting expression are pushed to the leafs. The NNF transformation first applies the [normalization](#normalize) transformation, after which a [DeMorgan](#demorgan) transformation is applied to push negations to the leafs.\n\n### Tseitin\n\nThe Tseitin transformation converts an expression in [negation-normal form](#nnf) to a SAT equivalent expression in conjunction-normal form (CNF), suitable for the [CDCL](#cdcl) solver.\n\n### CNF\n\n## Solvers\n\n### BDD\n\n### CDCL\n\nConflict-driven clause-learning is a CNF-based SAT solving technique.\n\n## Examples\n\n### Example: tautology test for p or not p\n\n```go\nb := Bench{T: t}\np := Var(\"p\")\n\nb.AssertTautology(\n    \"p or not p is a tautology\",\n    algorithm.FromExpression(\n        Or(p, Not(p)),\n    ),\n)\n```\n\n### Example: N-queens graphical BDD model\nThe image below shows the generated decision diagram for a 4x4 n-queens solution.\nFor any node, \"true\" edges are solid and \"false\" edges are dotted.\nA variable p_{x}_{y} determines whether a queen should be placed on tile (x,y).\nThis model is found by solving the following expression:\n\n```text\n(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\n(true ∧ ((((false ∨ p_0_0) ∨ p_0_1) ∨ p_0_2) ∨ p_0_3)) ∧ ((((false ∨ p_1_0) ∨ p_1_1) ∨ p_1_2) ∨ p_1_3)) ∧ \n((((false ∨ p_2_0) ∨ p_2_1) ∨ p_2_2) ∨ p_2_3)) ∧ ((((false ∨ p_3_0) ∨ p_3_1) ∨ p_3_2) ∨ p_3_3)) ∧ \n((((false ∨ p_0_0) ∨ p_1_0) ∨ p_2_0) ∨ p_3_0)) ∧ ((((false ∨ p_0_1) ∨ p_1_1) ∨ p_2_1) ∨ p_3_1)) ∧ \n((((false ∨ p_0_2) ∨ p_1_2) ∨ p_2_2) ∨ p_3_2)) ∧ ((((false ∨ p_0_3) ∨ p_1_3) ∨ p_2_3) ∨ p_3_3)) ∧ \n(( ¬ p_0_1) ∨ ( ¬ p_0_0))) ∧ (( ¬ p_0_2) ∨ ( ¬ p_0_0))) ∧ (( ¬ p_0_2) ∨ ( ¬ p_0_1))) ∧ (( ¬ p_0_3) ∨ \n( ¬ p_0_0))) ∧ (( ¬ p_0_3) ∨ ( ¬ p_0_1))) ∧ (( ¬ p_0_3) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_1_1) ∨ ( ¬ p_1_0))) ∧ \n(( ¬ p_1_2) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_1_2) ∨ ( ¬ p_1_1))) ∧ (( ¬ p_1_3) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_1_3) ∨ \n( ¬ p_1_1))) ∧ (( ¬ p_1_3) ∨ ( ¬ p_1_2))) ∧ (( ¬ p_2_1) ∨ ( ¬ p_2_0))) ∧ (( ¬ p_2_2) ∨ ( ¬ p_2_0))) ∧ \n(( ¬ p_2_2) ∨ ( ¬ p_2_1))) ∧ (( ¬ p_2_3) ∨ ( ¬ p_2_0))) ∧ (( ¬ p_2_3) ∨ ( ¬ p_2_1))) ∧ (( ¬ p_2_3) ∨ \n( ¬ p_2_2))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_3_0))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_3_0))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_3_1))) ∧ \n(( ¬ p_3_3) ∨ ( ¬ p_3_0))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_3_1))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_3_2))) ∧ (( ¬ p_1_0) ∨ \n( ¬ p_0_0))) ∧ (( ¬ p_2_0) ∨ ( ¬ p_0_0))) ∧ (( ¬ p_2_0) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_3_0) ∨ ( ¬ p_0_0))) ∧ \n(( ¬ p_3_0) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_3_0) ∨ ( ¬ p_2_0))) ∧ (( ¬ p_1_1) ∨ ( ¬ p_0_1))) ∧ (( ¬ p_2_1) ∨ \n( ¬ p_0_1))) ∧ (( ¬ p_2_1) ∨ ( ¬ p_1_1))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_0_1))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_1_1))) ∧ \n(( ¬ p_3_1) ∨ ( ¬ p_2_1))) ∧ (( ¬ p_1_2) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_2_2) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_2_2) ∨ \n( ¬ p_1_2))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_1_2))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_2_2))) ∧ \n(( ¬ p_1_3) ∨ ( ¬ p_0_3))) ∧ (( ¬ p_2_3) ∨ ( ¬ p_0_3))) ∧ (( ¬ p_2_3) ∨ ( ¬ p_1_3))) ∧ (( ¬ p_3_3) ∨ \n( ¬ p_0_3))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_1_3))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_2_3))) ∧ (( ¬ p_1_0) ∨ ( ¬ p_0_1))) ∧ \n(( ¬ p_1_1) ∨ ( ¬ p_0_0))) ∧ (( ¬ p_1_1) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_1_2) ∨ ( ¬ p_0_1))) ∧ (( ¬ p_1_2) ∨ \n( ¬ p_0_3))) ∧ (( ¬ p_1_3) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_2_0) ∨ ( ¬ p_0_2))) ∧ (( ¬ p_2_0) ∨ ( ¬ p_1_1))) ∧ \n(( ¬ p_2_1) ∨ ( ¬ p_0_3))) ∧ (( ¬ p_2_1) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_2_1) ∨ ( ¬ p_1_2))) ∧ (( ¬ p_2_2) ∨ \n( ¬ p_0_0))) ∧ (( ¬ p_2_2) ∨ ( ¬ p_1_1))) ∧ (( ¬ p_2_2) ∨ ( ¬ p_1_3))) ∧ (( ¬ p_2_3) ∨ ( ¬ p_0_1))) ∧ \n(( ¬ p_2_3) ∨ ( ¬ p_1_2))) ∧ (( ¬ p_3_0) ∨ ( ¬ p_0_3))) ∧ (( ¬ p_3_0) ∨ ( ¬ p_1_2))) ∧ (( ¬ p_3_0) ∨ \n( ¬ p_2_1))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_1_3))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_2_0))) ∧ (( ¬ p_3_1) ∨ ( ¬ p_2_2))) ∧ \n(( ¬ p_3_2) ∨ ( ¬ p_1_0))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_2_1))) ∧ (( ¬ p_3_2) ∨ ( ¬ p_2_3))) ∧ (( ¬ p_3_3) ∨ \n( ¬ p_0_0))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_1_1))) ∧ (( ¬ p_3_3) ∨ ( ¬ p_2_2)))\n```\n\n![n-queens model](/doc/images/bdd.dot.png)\n\n### Example: CDCL SAT solving\n\n```go\nbe := bdd_test.Bench{T: t}\na := operators.Var(\"a\")\n\nsat, _ := CDCL(operators.CNF{\n    operators.NClause{a.Negate(), a.Negate()},\n    operators.NClause{a, a},\n})\n\nbe.Assert(\"a xor a is unsat\", !sat)\n```\n\n### Example: CDCL after applying the Tseitin transformation\n\n```go\nbe := bdd_test.Bench{T: t}\n\na, b := op.Var(\"a\"), op.Var(\"b\")\ne := op.Xor(a, b),\n\npruned := PruneUnary(e)\nnnf := NNF(e)\ncnf := TransformTseitin(nnf)\n\ncdclSat, _ := CDCL(cnf)\nresBdd := FromExpression(pruned)\n\nsatBdd := bdd.Sat(resBdd)\nbe.Assert(\"cdcl and bdd are SAT equivalent\", satBdd == cdclSat)\n```\n\n### Example: Prime decomposition\n\n```go\nbench := bdd_test.Bench{T: t}\n\n// prime1 and prime2 are invisible to the solver\nvar prime1, prime2 uint = 13, 7\n\n// feed the composite number\ncombined := prime1 * prime2\n\n// estimate the number of bits needed\nbits := int(math.Ceil(math.Log2(float64(combined))))\nbits = 2 + (bits-(bits/2))*2\n\nlog.Printf(\"Using %d bits for prime computation\", bits)\n\n// construct two arbitrary numbers: a and b\na, b := Variable(bits/2), Variable(bits/2)\n\n// construct a number c\nc := Constant(combined, bits)\n\none := Constant(1, bits/2)\n\nexprEq := operators.And(\n    // a != 1\n    operators.Not(Equals(a, one)),\n    // b != 1\n    operators.Not(Equals(b, one)),\n)\n\n// c == a * b\nexprMul := Mult(a, b, c)\n\n// a * b == c and c == number to test\nexpr := operators.And(exprEq, exprMul)\n\n// prepare the expression tree\nexpr = algorithm.PruneUnary(expr)\n\n// run bdd algorithm\ntree := algorithm.FromExpression(expr)\n\nbench.AssertSat(fmt.Sprintf(\"%d is a composed number\", combined), tree)\n\nif bdd.Sat(tree) {\n    if model, ok := bdd.FindModel(tree); ok {\n        aResolv, err := a.Resolve(model)\n        if err != nil {\n            t.Error(err)\n        }\n        bResolv, err := b.Resolve(model)\n        if err != nil {\n            t.Error(err)\n        }\n        t.Logf(\"Prime-decomposition of %d: %d x %d\", combined, aResolv, bResolv)\n\n        if aResolv * bResolv != combined {\n            t.Error(\"a and b are not a valid decomposition of the original number\")\n        }\n    } else {\n        t.Fatal(\"Could not construct model of non-prime number\")\n    }\n}\n```\n\nOutput:\n\n```verbose\n\u003e RUN TestPrimeDecomposition\n\u003e Using 10 bits for prime computation\n\u003e Prime-decomposition of 91: 13 x 7\n\u003e PASS: TestPrimeDecomposition (4.45s)\n```\n\n## Known issues\n\n- RoBDD solving does not always return unique solutions. This problem can be resolved by replacing all named variables with integer variables to ensure a unique variable ordering.\n- CDCL solving is far from optimal and often needs to traverse the entire search space. Earlier elimination of clauses should be possible when using better suitable data structures.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbeurskens%2Fgobdd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimbeurskens%2Fgobdd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbeurskens%2Fgobdd/lists"}