{"id":13646889,"url":"https://github.com/crillab/gophersat","last_synced_at":"2026-02-04T12:40:11.230Z","repository":{"id":46204781,"uuid":"104997433","full_name":"crillab/gophersat","owner":"crillab","description":"gophersat, a SAT solver in Go","archived":false,"fork":false,"pushed_at":"2024-06-22T20:32:23.000Z","size":19211,"stargazers_count":373,"open_issues_count":9,"forks_count":23,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-10T15:18:27.808Z","etag":null,"topics":["artificial-intelligence","boolean-formulas","constraint-satisfaction-problem","constraints","pseudo-boolean-solver","sat-solver"],"latest_commit_sha":null,"homepage":null,"language":"Go","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/crillab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"codemeta.json","zenodo":null}},"created_at":"2017-09-27T09:11:15.000Z","updated_at":"2025-03-06T08:13:12.000Z","dependencies_parsed_at":"2023-11-24T14:24:44.272Z","dependency_job_id":"78ff535d-46c6-43e1-a90a-0ee9de110151","html_url":"https://github.com/crillab/gophersat","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crillab%2Fgophersat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crillab%2Fgophersat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crillab%2Fgophersat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crillab%2Fgophersat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crillab","download_url":"https://codeload.github.com/crillab/gophersat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250136793,"owners_count":21380891,"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":["artificial-intelligence","boolean-formulas","constraint-satisfaction-problem","constraints","pseudo-boolean-solver","sat-solver"],"created_at":"2024-08-02T01:03:13.505Z","updated_at":"2026-02-04T12:40:06.211Z","avatar_url":"https://github.com/crillab.png","language":"Go","funding_links":[],"categories":["Go","Solvers"],"sub_categories":["SAT Solvers"],"readme":"# Gophersat, a SAT and pseudo-boolean solver written in Go\n\n![Status](https://img.shields.io/badge/status-stable-green.svg?style=plastic)\n[![GitHub tag](https://img.shields.io/github/tag/crillab/gophersat.svg)](https://github.com/crillab/gophersat)\n![license](https://img.shields.io/github/license/crillab/gophersat.svg)\n[![GoReport](https://goreportcard.com/badge/github.com/crillab/gophersat)](https://goreportcard.com/report/github.com/crillab/gophersat)\n[![GoDoc](https://godoc.org/github.com/crillab/gophersat?status.svg)](https://godoc.org/github.com/crillab/gophersat)\n[![Build Status](https://travis-ci.org/crillab/gophersat.svg?branch=master)](https://travis-ci.org/crillab/gophersat)\n\n![gophersat logo](https://raw.githubusercontent.com/crillab/gophersat/master/gophersat.png)\n\nThis is Gophersat, a SAT and pseudo-boolean solver written purely in Go. \nGophersat was developed by the [CRIL (Centre de Recherche en Informatique\nde Lens)](http://www.cril.fr) at the Artois University \u0026 CNRS. It is\nreleased under the MIT license. Gophersat is rather efficient, i.e on\ntypical SAT benchmarks it runs about 2 to 5 times slower than top-level\nsolvers (namely, [glucose](http://www.labri.fr/perso/lsimon/glucose/) or\n[minisat](http://minisat.se/)) from which it is strongly inspired.\nIt can also solve MAXSAT problems, and pseudo-boolean decision and optimization problems.\n\n\n## Version 1.4: Cutting-planes\n\nGophersat's last stable version is version 1.4. It includes the optional cutting-planes solving strategy.\n\nSome problems, such as the famous pigeonhole problem, take a very-long time to solve using pure logical reasoning.\n\nThe pigeonhole problem can be expressed this way: is it possible to put n pigeons in m pigeonholes, where m = n-1, without putting several pigeons in the same hole and putting all pigeons in a hole? The answer is obvious: if you have 4 pigeons in 3 holes, you can't put them all in a different hole. But how do you *prove* this? A SAT or PB solver will prove it by trying all possible combinations, and the number of possible combinations grows exponentially. So, trying to solve the problem with n=20 is not feasible in practice, despite the problem having an obvious answer.\n\nSome PB solvers implement an alternative strategy: the cutting-planes strategy. It won't be described in detail in this document, but this stategy can be extremely efficient on some problems, such as the pigeonhole problem which cannot be solved efficiently by pure logical reasoning, but will be slower on most problems.\n\nIt is now possible to use the cutting-planes with Gophersat. Just use the `-cp` command-line option. So, instead of calling:\n\n    gophersat problem.opb\n\nJust call:\n\n    gophersat -cp problem.opb\n\n\n## Version 1.3\n\nGophersat's last stable version is version 1.3. It is a minor update, adding the ability to access the underlying solver when dealing with MAXSAT problems.\n\n\n## Version 1.2: Explainable AI: UNSAT certification, MUS extraction\n\nGophersat version 1.2 includes a way to understand UNSAT instances, both by providing RUP certificates when a problem is UNSAT and by providing the ability to extract unsatisfiable subsets of the formula. A vew bugs were also corected, and the support for incremental SAT solving was improved.\n\nTo learn more about these functionalities, you can check the [tutorial about UNSAT certificates and MUSes](mus.md).\n\nTo generate a certificate with the gophersat executable, simply call:\n\n    gophersat -certified problem.cnf\n\nThe certificate will then be printed on the standard output, using the RUP notation. The certificate is generated on the fly, so be aware that a partial, useless certificate will be generated even if the problem is actually satisfiable. This is common practice in the community, and although the generated clauses are useless noise, in practice this is not a problem.\n\nTo extract a MUS from an UNSAT instance, just call:\n\n    gophersat -mus problem.cnf\n\nThe MUS will the be printed on the standard output. If the problem is not UNSAT, an error message will be displayed.\n\nFor the moment, these facilities are only available for pure SAT problems (i.e not pseudo-boolean problems).\n\n\n## Version 1.1\n\nSince its version 1.1, Gophersat includes a new, more efficient core solver for pure SAT problems\nand a package dealing with MAXSAT problems. It also includes a new API for optimization and model counting,\nwhere new models are written to channels as soon as they are found.\n\n### About version numbers in Gophersat\n\nSince version 1.0, Gophersat's API is considered stable, meaning that the API is guaranteed to stay backwards-compatible\nuntil a major version shift. In other words, if your program works with version 1.0 of gophersat, it\nwill still work with version 1.1 or above, but not necessarily with versions above 2.0.\n\nNote that, by \"still working\", we only mean \"will compile and produce the same output\", not \"will have the\nsame performance memory-wise or time-wise\". This is an important distinction: during minor version upgrades,\nnew heuristics or data types can be introduced, meaning some given problems could be solved faster or slower\nthan previously.\n\n## How do I install it?\n\n`go get github.com/crillab/gophersat \u0026\u0026 go install\ngithub.com/crillab/gophersat`\n\n### Solving SAT problems\n\nGophersat can be used as a standalone solver (reading DIMACS CNF files) or as a library in any go program.\n\nTo solve a DIMACS file, you can call gophersat with the following syntax:\n\n    gophersat --verbose file.cnf\n\nwhere `--verbose` is an optional parameters that makes the solver display informations during the solving process.\n\nGophersat is also able to read and solve more general boolean formulas,\nnot only problems represented in the user-unfriendly DIMACS format.\nIt also deals natively with cardinality constraints, i.e clauses that must have at least\nn literals true, with n \u003e 1.\n\n### Solving pseudo-boolean problems\n\nGophersat can be used as a standalone solver (reading OPB files) or as a library in any go program.\n\nTo solve a pseudo-boolean problem (whether a decision one or an optimisation one), you can call gophersat with the\nfollowing syntax:\n\n    gophersat --verbose file.opb\n\nwhere `--verbose` is an optional parameters that makes the solver display informations during the solving process.\n\nFor the moment, it can only solve the so-called DEC-SMALLINT-LIN problems and OPT-SMALLINT-LIN,\ni.e decision problems (is there a solution or not), for linear constraints (a sum of weighted literals)\non small integers (n \u003c 2^30), or optimization problems (what is the best solution, minimizing a given cost function),\nfor linear constraints on small integers.\n\n### Solving MAXSAT problems\n\nThanks to the `maxsat`package, Gophersat can now solve MAXSAT problems.\n\nTo solve a weighted MAXSAT problem, you can call gophersat with the following syntax:\n\n    gophersat --verbose file.wcnf\n\nwhere `--verbose` is an optional parameters that makes the solver display informations during the solving process.\nThe file is supposed to be represented in (the WCNF format)[http://www.maxsat.udl.cat/08/index.php?disp=requirements].\n\n## What is a SAT solver? What is the SAT problem?\nSAT, which stands for *Boolean Satisfiability Problem*, is the canonical\nNP-complete problem, i.e a problem for which there is no known solution that does\nnot take exponential time in the worse case. In a few words, a SAT solver tries to find,\nfor a given propositional formula, an assignment\nfor all its variables that makes it true, if such an assignment exists.\n\nWhile it's trivial to implement a SAT solver using a naïve algorithm, such\nan implementation would be very inefficient in practice. Gophersat\nimplements state-of-the-art features and is thus quite efficient, making\nit usable in practice in Go programs that need an efficient inference\nengine.\n\nAlthough this is not always the best decision for practical reasons, any\nNP-complete problem can be translated as a SAT problem and solved by\nGophersat. Such problems include the Traveling Salesman Problem,\nconstraint programming, Knapsack problem, planning, model checking,\nsoftware correctness checking, etc.\n\nMore about the SAT problem can be found on [wikipedia's article about\nSAT](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem).\n\nYou can also find information about how to represent your own boolean\nformulas so they can be used by gophersat in the [tutorial \"SAT for\nnoobs\"](examples/sat-for-noobs.md).\n\n## What is MAXSAT?\n\nMAXSAT is the optimization equivalent of the SAT decision problem. While a pure SAT solver will either return a\nmodel satisfying all clauses or UNSAT if no such model exists, a MAXSAT solver will return a model that satisfies\nas many clauses as possible.\n\n### Partial and weighted MAXSAT\n\nThere are extensions to MAXSAT.\n\n**Partial MAXSAT** means that, although we want to satisfy as many clauses as possible,\nsome clauses (called *hard clauses*) *must* be satisfied, not matter what. A partial MAXSAT problem can thus be\ndeclared unsatisfiable.\n\nFor instance, generating a timetable for a school is a partial MAXSAT problem: there are both soft (we want to have as little classes as possible that start after 4 PM, for instance)\nand hard (two teachers cannot be in two different places at the same time) constraints.\n\n**Weighted MAXSAT** means that clauses are associated with a cost: although optional, some clauses are deemed more important than others. For instance, if clause C1 has a cost of 3 and clauses C2 and C3 both have a cost of 1, a solution satisfying C1 but neither C2 nor C3 will be considered better than a solution satisfying both C2 and C3 but not C1, all other things being equal.\n\n**Partial weighted MAXSAT** means that there are both soft and hard clauses in the problem, and soft clauses are weighted. In this regard, \"pure\" MAXSAT is a particular case of the more generic partial weighted MAXSAT: a \"pure\" MAXSAT problem is a partial weighted MAXSAT problem where all clauses are soft clauses associated with a weight of 1.\n\n## What about pseudo-boolean problems?\nPseudo-boolean problems are, in a way, a generalization of SAT problems: any propositional clause\ncan be written as a single pseudo-boolean constraint, but representing a pseudo-boolean constraint\ncan require an exponential number of propositional clauses.\n\nA (linear) pseudo-boolean expression is an expression like:\n\n    w1 l1 + w2 x2 + ... + wn xn ≥ y\n\nwhere `y` and all `wi` are integer constants and all `li` are boolean literals.\n\nFor instance, for the following expression to be true\n\n    2 ¬x1 + x2 + x3 ≥ 3\n\nthe boolean variable `x1` must be false, and at least one of `x2` and `x3` must be true.\nThis is equivalent to the propositional formula\n\n    ¬x1 ∧ (x2 ∨ x3)\n\nPseudo-boolean expressions are a generalization of propositional clauses: any clause\n\n    x1 ∨ x2 ∨ ... ∨ xn\n\ncan be rewritten as\n\n    x1 + x2 + ... + xn ≥ 1\n\nThe description of a pseudo-boolean problem can be exponentially smaller than its\npropositional counterpart, but solving a psudo-boolean problem is still NP-complete.\n\nGophersat solves both decision problems (is there a solution at all to the problem),\nand optimization problem.\nAn optimization problem is a pseudo-boolean problem associated with a cost function,\ni.e a sum of terms that must be minimized.\nRather than just trying to find a model that satisfies the given constraints,\ngophersat will then try to find a model that is guaranteed to both satisfy the constraints\nand minimize the cost function.\n\nDuring the search for that optimal solutions, gophersat will provide suboptimal solutions\n(i.e solutions that solve all the constraints but are not yet guaranteed to be optimal)\nas soon as it finds them, so the user can either get a suboptimal solution in a given time limit,\nor wait longer for the guaranteed optimal solution.\n\n## Is Gophersat fast? Why use it at all?\nYes and no. It is much faster than naïve implementations, fast enough to be used on real-world problems, but slower than\ntop-level, highly optimised, state-of-the-art solvers.\n\nGophersat is not aiming at being the fastest SAT/PB solver available. The\ngoal is to give access to SAT and PB technologies to gophers, without resorting\nto interfaces to solvers written in other languages (typically C/C++).\n\nHowever, in some cases, interfacing with a solver written in another\nlanguage is the best choice for your application. If you have lots of\nsmall problems to solve, Gophersat will be the fastest alternative. For\nbigger problems, if you want to have as little dependencies as possible\nat the expense of solving time, Gophersat is good too. If you need to\nsolve difficult problems and don't mind using cgo or use an external\nprogram, Gophersat is probably not the best option.\n\nThere are a few other SAT solvers in Go, mainly go-sat and gini.\nGini's performance is pretty much on par with Gophersat, although a little slower\non average, according to tests we ran.\n\nGophersat is also providing cool features not always available with other solvers\n(a user-friendly input format, for instance), so it can be used as a tool for\ndescribing and solving NP-hard problems that can easily be reduced to a SAT/PB problem.\n\n## Do I have to represent my SAT problem as CNF? Am I forced to use the unfriendly DIMACS format?\nNo. The `bf` (for \"boolean formula\") package provides facilities to\ntranslate any boolean formula to CNF.\n\n## Can I know how many solutions there are for a given formula?\nThis is known as model counting, and yes, there is a function for that: `solver.Solver.CountModels`.\n\nYou can also count models from command line, with\n\n    gophersat --count filename\n\nwhere filename can be a .opb or a .cnf file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrillab%2Fgophersat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrillab%2Fgophersat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrillab%2Fgophersat/lists"}