
Modern SAT solvers: fast, neat and underused - ScottWRobinson
https://codingnest.com/modern-sat-solvers-fast-neat-underused-part-1-of-n/
======
hardmath123
Yes! SAT solvers are an amazing secret weapon for solving tricky problems.
I've been collecting some fun examples of solver-aided programming here:
[https://github.com/kach/recreational-
rosette](https://github.com/kach/recreational-rosette) (also, not in that
repo, but still interesting: [https://github.com/kach/tower-of-
power](https://github.com/kach/tower-of-power)).

------
Karrot_Kream
I wanted to mention Z3, which is one of the most user friendly yet advanced
solvers I know. It's actually an SMT solver, so can solve a few more things
than only SAT problems.

~~~
ris
As cool as Z3 is, I wish it didn't become so incredibly slow once soft
constraints are introduced. I guess it's inevitable to an extent...

~~~
OscarCunningham
What are soft constraints?

~~~
kilburn
Hard constraints are constraints that cannot be violated for the allocation to
be valid (i.e.: to be a solution).

Soft constraints are constraints that incur some cost/penalty when violated.

Then the problem objective changes from "find an allocation that is a
solution" (SAT) to "find the minimal cost solution (if one exists)" (Weighted
SAT / Constraint Optimization).

For instance:

\- SAT problem (a,b are binary):

Hard constraint: a = b

Solutions: a=0,b=0 and a=1,b=1

\- Constraint optimization:

Hard constraint: a = b

Soft constraint: cost(a,b) = a+b

Optimal solution: a=0,b=0 with cost 0. The allocation a=1,b=1 is a solution
because it fulfills the hard constraints, but it is not optimal because it's
cost (2) is larger than the cost of another solution (0).

~~~
tomp
Looks like you want to integrate a SAT/SMT solver with a convex optimisation
engine :)

------
bojanz
A great related article is the introduction to PubGrub, the new solver
algorithm for Dart's package manager. I especially liked the focus on better
error messages, which can get pretty cryptic in other package managers.

[https://medium.com/@nex3/pubgrub-2fb6470504f](https://medium.com/@nex3/pubgrub-2fb6470504f)

The official docs are a rare learning resource, but require a bit more time to
digest.

[https://github.com/dart-
lang/pub/blob/master/doc/solver.md](https://github.com/dart-
lang/pub/blob/master/doc/solver.md)

------
glalonde
Yup, had some great success getting solutions to real instances of NP complete
problems. Nice thing is that SAT solvers all have basically the same
interfaces, you can serialize the problems easily so it is super easy to try
lots of solvers out. It's fun to think about problems in terms of SAT, you can
build huge logic networks with hundreds of thousands of clauses and solve them
in seconds. Solve integer optimizations with binary encodings. cool stuff.
Unfortunately, it is super sensitive and hard to control, so if you want
particular properties of your answer that are "nice to haves" but not
required, it is hard to encode. Some problems will be solved instantly, some
will never be solved with any amount of cpu time, so it is hard to have it in
the loop of something that needs to always work unless your problems are
really well constrained.

~~~
egaeus
It sounds like you are trying to solve a partial maxsat problem. Partial
maxsat uses two sets of clauses, hard and soft clauses. The hard clauses must
be satisfied and the soft clauses are "nice to haves." The goal for the solver
is to satisfy all the hard clauses and as many as the soft clauses as
possible.

Pysat is a python package for that provides efficient SAT solver APIs and
encodings, including a partial maxsat solver.
[https://pysathq.github.io/docs/html/index.html](https://pysathq.github.io/docs/html/index.html)

RC2 partial maxsat algorithm:
[https://pysathq.github.io/docs/html/api/examples/rc2.html](https://pysathq.github.io/docs/html/api/examples/rc2.html)

------
Patrick_Devine
Definitely agree that they are criminally underused. I used to work for a
large virtualization company, and used a SAT solver to walk an extremely
complex dependency graph. We had originally been using a simple hill climbing
algorithm and the SAT solver absolutely trounced it in terms of performance.

The biggest problem though, was when I would describe how we were using SAT to
solve the graph, I generally would get extremely puzzled looks. Most other
engineers have no exposure to them whatsoever.

~~~
analognoise
A hill climbing algorithm doesn't make any sense to me for a dependency graph,
it doesn't fit the domain at all.

Is there a canonical reference you'd recommend to understand this problem or a
paper I could look at that was similar to this implementation?

~~~
Jugglerofworlds
Sometimes discrete graph theory problems can be relaxed into a continuous
space where gradient descent can be used. If you want a concrete example of
how this happens, take a look at the "Continuous Optimization" section in the
"Thirty Years of Graph Matching in Pattern Recognition" paper (graph/subgraph
isomorphism).

~~~
analognoise
Thank you, I will investigate this.

------
shaklee3
Maybe it's just me, but I feel the same way about MIPS solvers as well. The
amount of optimization that has gone into these solvers over decades, and the
kind of problems they're solving is staggering. Yet, you never hear about them
since operations research is not as sexy as deep learning.

~~~
StreakyCobra
I experimented with MIPS before, mainly for side projects, and I found them
amazing for easily solving optimization problems. Reading this article, I felt
the logic used for constructing the Sudoku solver is quite close to what I
would have done for MIPS: one constraint for one number per row, one
constraint for the columns, one constraint for the 3x3 boxes, etc…

I am wondering if MIPS and SAT relate together somehow?

~~~
shaklee3
You can solve SAT problems using linear programming, I believe. I don't know
if the free SAT solvers would compare to a commercial LP solver like gurobi or
cplex.

~~~
nhaehnle
Integer programming, not linear programming. Linear programming (without the
integrality constraint) is in P, so you cannot use it to solve general SAT
problems, which are NP-complete (unless a major and highly surprising
theoretical breakthrough is found).

The free SAT solvers are very good, and _much_ better than commercial IP
solvers at solving problems that are a natural fit for SAT. (Obviously, you
can encode any IP as an SAT formula and vice versa, and the IP solvers are
better at solving the problems where you actually have meaningful arithmetic.)

~~~
shaklee3
Thanks for clearing that up!

------
DoctorOetker
I think music composers could benefit from composing software: i.e. they might
specify different "facets" of a score, such as Parson code (next note
frequency higher, lower, or equal to previous note) for melodic relationships,
harmonical relationships between simultaneous notes, melodical relationships
between a note in a variation of an earlier bar and a corresponding note in
the same position of the earlier bar (i.e. the melodic relationship between
the expected and actual surprising note) etc...

~~~
bbeonx
I am writing a Z3 music composer right now actually. Just as a toy project but
the idea is solid: you have a passage that you need to harmonize? Here are
three different versions that conform to the rules of fuxian counterpoint, etc

~~~
hardmath123
Hehe, I worked on one of these last year when I took a music theory class! You
might enjoy this: [https://github.com/kach/recreational-
rosette/tree/master/mus...](https://github.com/kach/recreational-
rosette/tree/master/music)

~~~
bbeonx
Oh cool. Yeah, I looked around from "Music Composition Constraint
Solving/SMT/Z3" stuff and didn't find anything which was surprising. I'll take
a look at Rosette too, I've heard of it a couple times but never dug in

------
lorenzhs
If you're interested in cutting-edge research SAT solvers, have a look at the
annual SAT competition:
[http://satcompetition.org/](http://satcompetition.org/) \- source code is
available for all of them.

------
cosmic_ape
For those hearing about SAT solvers for the first time, its worth mentioning
that they are the basic component of hardware (and software) formal
verification systems.

This is probably the largest practical application domain, which also drives
most of the academic development.

~~~
logicchains
>they are the basic component of hardware (and software) formal verification
systems.

They are _a_ component. It's quite possible to perform formal verification
without them, for instance the CompCert verified C compiler, or the DeepSpec
end-to-end verification project:
[https://deepspec.org/main](https://deepspec.org/main). SAT solvers generally
have poor support for constructive logic, the kind of logic used in theorem
provers based on dependent types like Coq. Systems based on classical logic
like HOL integrate better with SAT solvers, but the lack of dependent types
makes a lot of things much cumbersome to prove, especially if one wants proofs
that can be extracted to programs.

~~~
dranov
> SAT solvers generally have poor support for constructive logic, the kind of
> logic used in theorem provers based on dependent types like Coq.

Arguably, this is no longer the case. FStar [1] has dependent types, monadic
effects, refinement types and a weakest precondition calculus (i.e. a richer
type system than Coq) and uses the Z3 SMT solver to discharge many proof
obligations. I've been using FStar recently and it works surprisingly well.

[1] - [https://www.fstar-lang.org/](https://www.fstar-lang.org/)

~~~
tom_mellior
> > SAT solvers

> Z3 SMT solver

You are comparing different things.

------
rurban
I work a lot with sat solvers, but with using in a proper language. Either
cbmc for C (not Klee, not Z3 as these require extensive translations to
obscure languages), or picat for a proper functional language with support for
normal non-functional coding styles.

The sudoku sample is a few lines there, and it used to win many CSP contests.
[http://www.hakank.org/picat/sudoku_pi.pi](http://www.hakank.org/picat/sudoku_pi.pi)

cbmc is esp. nice to autocreate proper test cases.

~~~
rurban
Have to add to obvious ones: prolog. Almost every prolog comes now with a sat
solver.

With prolog it's usually easiest to formulate a problem. Efficient solutions
are a bit of a black art though:
[https://www.metalevel.at/prolog/horror](https://www.metalevel.at/prolog/horror)

------
domoritz
Answer set programming with clingo
([https://potassco.org](https://potassco.org)) is a super powerful and user
friendly way to constraint programming.

~~~
probably_wrong
I used that to build my initial fantasy soccer team, it wasn't too hard to
pick up amd the results were quite good. The team ended up performing very
badly in real life, but that's not Clingo's fault.

------
petters
I often think of SAT as the assembly language of discrete optimization.

I specify my problems in a higher-level DSL and a library then "compiles" it
to SAT, where many solvers are available.

~~~
nhaehnle
You should look into integer linear programs. They are a much useful "DSL" for
discrete optimization. You get a lot of insight into flow problems from
studying their LPs, for example, and it's very easy and efficient to solve
flow problems with additional constraints using ILPs. Also, the state of the
art for solving TSP and related hard path-finding problems uses techniques
from integer linear programming.

~~~
petters
You are correct. (I am very familiar with LP as well)

------
drdrey
OP complains that they are underused in industry, and goes on to show how to
solve sudoku. That is not going to help me in my day to day job, can someone
come up with a more pragmatic example where we could apply solvers?

~~~
jwilk
From the article:

 _As an example, the often-talked-about dependency management problem, is also
NP-Complete and thus translates into SAT, and SAT could be translated into
dependency manager. The problem our group worked on, generating key and lock
cuttings based on user-provided lock-chart and manufacturer-specified
geometry, is also NP-complete._

------
tphan
Composer, the defacto package manager for PHP, uses a SAT solver. It's pretty
interesting looking at the code!

~~~
blattimwind
... and also a frequent source of performance and memory issues.

~~~
spdionis
Considering it's only a problem when updating dependencies and how good and
reliable the result is, it's totally worth it.

Worst case in extremely big projects you just add some swap and let it run for
a while, the time required is still in the order of tens of minutes.

Compare that to hours long c++ build times.

------
zschoche
if a problem is NP-hard does not mean that each instance is hard to solve.
From my experience many instances appearing in practice are easy to solve even
if there very large. The problem with these instances is that it takes to much
space to write done the SAT-formual. So you do not even get to the point where
you would run the solver. But a simple problem specific search tree algorithm
has no problem with solving it. Bottom line, if you really need to solve a NP-
hard problem then you might want to look for fixed-parameter tractable
algorithms.

~~~
DoctorOetker
Given 2 NP-hard problems and a transformation that translates (in polynomial
time) any instance of NP-hard problem type 1 into an instance of NP-hard
problem type 2, and if type 1 has a known fixed parameter tractable algorithm,
can we "translate" the fixed parameter from type 1 to an equiproblematic
parameter in type 2?

~~~
ColinWright
That's not the point (as I understand it). The point is that many instances of
NP-Hard problems are, in truth, easily solved.

To give an accessible example, consider the problem of finding a factor of an
integer. I know this isn't NP-Hard, but it's something most people can easily
think about.

If you choose a random large integer, odds are it has a small factor. 50% of
the time it's divisible by 2, and most numbers (in a very real sense) or
divisible by 2, 3, 5, or 7.

So most of the time a randomly chosen number is easy to find a factor of. In a
similar way, most real-world instances of NP-Hard problems are actually easy
to find a solution for. The proportion of difficult instances shrinks as the
instance size increases[0]. Specifically, if you have an instance of SAT
generated from a real-world situation, the likelihood is that it's not
actually that hard, so even if it's large, an off-the-shelf SAT solver might
be able to dash off a solution.

So when confronted by an NP-Hard problem don't just instantly give up. Choose
an algorithm that has a go, and there's a good chance you'll get a solution.

[0] There are formal, unproven conjectures about this.

~~~
DoctorOetker
Yes I understood this, but thanks for making sure anyway...

That still does not answer my question. I see and understand the _utility_ of
fixed parameter tractability.

This naturally made me wonder about the proofs that a certain problem type P'
is NP-hard (by being able to transform problem from P' to known NP-hard
problem P and back): can these translations be used to deduce the relevant
fixed parameter for NP-hard problems if one of the 2 problem types (P' or P)
has a known fixed parameter tractable algorithm...

I.e. you did not answer my question at all, you just reiterated basic
complexity theory

~~~
ColinWright
OK, then I don't understand your question. I'm not an expert, so perhaps I'm
not in a position to understand, let alone answer, but it's worth clarifying
in case someone else can step in.

Suppose we have two problems, A and B. We have polynomial time transforms
between them, so they are considered "equally difficult".

In reading and re-reading the thread it appears that you (pl) are talking
about having a "fixed parameter tractable algorithm" for one of the problems,
say problem A, and you (sng) are asking if the transform then provides an
equivalent fixed parameter tractable algorithm for B.

If that's the case then I don't know enough to answer, but my feeling is
"probably not in general".

If that's not what you're asking then you might like to be more specific.

In either case I suspect I can't add anything useful.

~~~
DoctorOetker
Your last comment indicates you _do_ understand my question! so I upvote it :)

Not sure what you mean with _pl_ and _sng_ in "you (pl)" and "you (sng)"

Most fantastic would of course be a general method so that given as inputs the
transforms between problem types, and the known fixed parameter, and fixed
parameter tractable algorithm, gives as output the new fixed parameter, and a
new fixed parameter tractable algorithm for the new fixed parameter.

I assume we do not have such a general method, so similarily interesting would
be data points for constructing such a method: examples of deducing the fixed
parameter for a problem domain, given the fixed parameter (and tractable
algorithm) from those of a different problem type.

With enough examples perhaps a general method can be guessed.

~~~
ColinWright
> _Your last comment indicates you do understand my question! so I upvote it
> :)

OK, cool, thanks!

> _Not sure what you mean with pl and sng in "you (pl)" and "you (sng)"*

"Plural" and "Singular" \- in English I can't make it clear that in some cases
I'm talking about you and previous speakers, and in other cases I'm talking
only about you. Other languages make it easier to make the distinction, in
English it must be inferred, or made explicit.

> _Most fantastic would of course be a general method so that given as inputs
> the transforms between problem types, and the known fixed parameter, and
> fixed parameter tractable algorithm, gives as output the new fixed
> parameter, and a new fixed parameter tractable algorithm for the new fixed
> parameter._

I feel like that's a lot to ask, but we are beyond my expertise.

> _I assume we do not have such a general method ... With enough examples
> perhaps a general method can be guessed._

I have no intuition about this at all, so I'll stand aside and let others with
greater knowledge comment, if they're around.

~~~
zschoche
Okay let (P,k) be a parameterized problem which admits a fixed-parameter
algorithm with respect to k. That means you have an algorithm which runs in
f(k)n time, where n is the input size and f is a function only depending on k
(for example (2^k)*n). Hence, if your real-world instances have always a small
k then you can solve arbitrary large instances. Note that one problem can have
a lot of different parameters and not all admitting such an algorithm (unless
the world is very different than we believe). Now let (P’,h) be another
parameterized problem and you have a polynomial time reduction from P’ to P.
Then, this reduction gives you a fixed-parameter algorithm for P’ with respect
to h if the value of k in the reductions depends only on h and nothing else.

------
rwmj
SAT solvers are used by DNF and Zypper (respectively Fedora's and OpenSUSE's
package managers).

~~~
blattimwind
Allegedly Windows Update runs on one as well, which is said to be the reason
why "update rollups" are needed to keep the system fast (and also the reason
why Windows 7 updating has been extremely slow for years).

------
whaaswijk
One industry where SAT solvers get used frequently is in Electronic Design
Automation. One comment already mentions its use in hardware/software
verification. It turns out we can also use them to find efficient
representations of Boolean functions (and therefore electronic circuits). This
also generalizes to the synthesis of quantum logic circuits. They truly are
amazingly versatile tools.

------
tylerhou
Site isn't working for me; here's an archive link:

[https://web.archive.org/web/20180804000124/https://codingnes...](https://web.archive.org/web/20180804000124/https://codingnest.com/modern-
sat-solvers-fast-neat-underused-part-1-of-n/)

------
kjeetgill
Does anyone with good knowledge of the space want to chime in on the state of
the open source ecosystem? In particular, what are the canonical libraries for
Java, C/C++, python, go etc. ecosystems? Does everyone just use Minisat or Z3
bindings in their language?

------
QML
What does this mean for NP-complete problems? Is the term “fast” only
applicable to this small Sudoku board, or are solvers optimized to the point
where something like O(2^256) doesn’t take that much time to run?

~~~
yaantc
It's impossible to create a solver that is efficient on any and all NP-
complete problems. That applies to any solver.

Still, it is possible to create efficient solvers for some subset of the NP-
complete problem space. They will work fine on some problem exhibiting the
proper "shape" / internal structure. What that is is often hard to tell...

So in practice using SAT solvers (or SMT, or constraint, or MIP ones...) has
some empirical side to it. It can work extremely well in some cases: it's
possible to solve problems with 10s of millions of Boolean variables for
example. It can also fail (time out). That depends a lot on the problem type
and the solver heuristics. It's common in this area to try different solvers,
and be happy if one gets a result in reasonable time. So there can be magic,
but also some frustration.

As a practical example, SMT solvers are used for software formal proof. It's
typical for those tools (like Frama C) to try several solvers. If any find a
proof, you're good and the proof is for free (no human work needed). If none
work, it's up to the engineer to reshape the problem to "help" the solver, or
bite the bullet and deal with the proof (semi) manually with coq or a similar
tool.

All this being said, modern solvers are really powerful. If it's a human scale
problem solvable "by hand" with lots of work, a solver should deal with it
very quickly.

~~~
adrianN
Technically we don't know whether it's impossible to create an efficient
solver.

------
platz
how does this compare with google's OR-Tools?

------
mathgenius
Do any of these have python interfaces?

~~~
yaantc
Z3 has a python interface. This said, SMT is an extension of SAT, and you're
likely to use a SMT solver even for "just" SAT problems. Most SMT solvers
support the SMT-LIB [1] file format, which is easy to generate from python. It
also lets you switch engine easily.

Also, there are other kinds of interesting solvers. For constraint problems,
one can check minizinc [2]. A bit like SMT-LIB, it's a language to describe
constraint problems that is supported by many solvers. It's commonly used with
gecode [3]. For many problems using minizinc will be much easier than trying
to convert the problem in SAT (or even SMT) format.

Happy hacking, it's a fascinating domain!

[1] [http://smtlib.cs.uiowa.edu/](http://smtlib.cs.uiowa.edu/) [2]
[http://www.minizinc.org/](http://www.minizinc.org/) [3]
[http://www.gecode.org/](http://www.gecode.org/)

~~~
marcogario
In pySMT, we have been working on making the simplicity of the z3 python
interface available to other solvers both through SMT-LIB interfaces, but also
native API integration for SMT/SAT solvers and OBDDs.

We are always glad to get more feedback!

[https://github.com/pysmt/pysmt](https://github.com/pysmt/pysmt)

~~~
philipov
In looking over whether the license would be amenable to distribution as part
of a game, I noticed that your github page links to pysmt.org at the top, but
that's only a redirect back to the github page :p

~~~
marcogario
Eheh, we tried for some time to come up with a good webpage. At the end of the
day, this is a library for developers, and as such we decided that the Github
page is the most meaningful place to start. We put a lot of work in the main
README, with revisions after each release, and we have a readthedocs for
detailed documentation. Nevertheless, the github page gives you also other
insights on what is the development status of the library (currently active
but not daily), and areas of targeted improvement.

Re the licensing, pySMT is open-source and distributed under APACHE 2.0 .

------
dingo_bat
Very interesting. I have no formal CS training so this is really eye-opening
to me.

------
DoctorOetker
Actually these SAT solvers and model checkers seem like a valid niche for
blockchain and a true bit protocol: as an average user of these (i.e. enough
that you run it multiple times a day, but not so often that you have a full
pipeline of scheduled problems to check) you can have it run on problemms of
others (generating coin) and then when you are done interpreting the results
of a previous run and reformulating your own problem, you can use your coin to
solve your problem quicker...

