MonoSAT is a SAT Modulo Theory solver for monotonic theories, over Booleans and bitvectors. It supports a wide set of graph predicates (including reachability, shortest paths, maximum s-t flow, minimum spanning tree, and acyclicity constraints). MonoSAT supports reasoning about graphs that are either directed or undirected (including graphs that may have cycles). Edges may (optionally) have constant or Bitvector weights. MonoSAT also has experimental support for constraints on finite state machines - see FiniteStateMachines for details.
MonoSAT can be used from the command line, or as a Python 3 library. See the installation instructions below; see also the tutorial.
To see further examples of use cases for MonoSAT, and details on the (very simple) input file format that MonoSAT accepts, see FORMAT.
MonoSAT requires CMake (version 2.7 or higher).
From the root directory, build and install MonoSAT with:
$cmake .
$make
$sudo make install
MonoSAT requires C++11 support, zlib, and GMP >= 5.1.3. Tested on Ubuntu 14.04 and 16.04, with g++ 4.8.2 or higher, and with Clang 3.5. The Python library requires Python 3.3+.
If you get compilation errors along the lines of "error: could not convert ‘x’ from ‘__gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘bool’", then you likely need to install a more recent version of GMP, with C++ support enabled.
If you build MonoSAT without using the provided cmake/makefiles, it is critically important to compile with NDEBUG
set (i.e., -DNDEBUG
), as otherwise many very expensive debugging assertions will be enabled.
You will need to first install GMP:
$brew install gmp
MonoSAT will, by default, compile statically linked binaries and dynamically linked libraries. In most cases, you can then continue the cmake installation as above.
However, in some cases brew might not add the GMP libraries to the library path, in which case MonoSAT compilation may fail during linking. You can check where brew installed GMP with:
$brew --prefix gmp
If brew installed GMP to /opt/local/lib/gmp, then you may need to modify the MonoSAT compilation instructions as follows:
$cmake .
$DYLD_LIBRARY_PATH=/opt/local/lib LIBRARY_PATH=/opt/local/lib make
$sudo make install
You will need to first install GMP, which you can do via pkg or ports:
$pkg install gmp
If you intend to include the Java library (see below), you'll also need a JDK and you'll need to set your JAVA_HOME environment variable:
$pkg install openjdk8
$export JAVA_HOME=/usr/local/openjdk8
To install the Python library (system-wide) on your system's default Python version:
$cmake -DPYTHON=ON .
$make
$sudo make install
MonoSAT also has support for Cython bindings, which are about 30% faster but require you to have a wokring installation of cython:
$cmake -DPYTHON=ON -DCYTHON=ON .
$make
$sudo make install
To install MonoSAT in an alternative python version (or in a virtual env or a non-standard location), first build MonoSAT as normal, then cd into 'src/monosat/api/python', and then use setup.py
to install the Python library manually, eg:
$cd src/monosat/api/python
$sudo python3.6 setup.py install -f
Above, -f
ensures that if you have previously installed a version of the monosat library, it will be overwritten cleanly with the new version.
See the tutorial and tutorial.py for instructions on using the Python library.
To compile the Java library, you need to build MonoSAT with Java bindings enabled. You will also need an installed JDK, version 1.8 or higher:
$cmake -DJAVA=ON .
$make
This should generate monosat.jar
in MonoSAT's root directory.
To use MonoSAT from Java, you will need to include the jar in your classpath.
You will also need to ensure that Java can find MonoSAT's dynamic library, for example:
java -Djava.library.path=path/to/libmonosat.so -cp path/to/monosat.jar mypacakge.MyMainClass
On OSX, you would instead use path/to/libmonosat.dylib
See Tutorial.java for instructions on using the Java library.
The recommended way to use MonoSAT is as a library, via the Python or Java bindings. However, it is also possible to call MonoSAT from the command line. MonoSAT is based on MiniSat 2, and supports many of the same calling conventions:
$monosat [-witness|-witness-file=filename] input_file.gnf
Where input_file.gnf is a file in GNF format (a very simple extension of DIMACS CNF format to support graph, bitvector, and finite state machine predicates). Use -witness
to print the solution (if one exists) to stdout, or -witness-file
to save it to file.
MonoSAT includes a very large set of configuration options - most of which you should stay away from unless you know what you are doing or want to explore the internals of MonoSAT (also, some of those configuration options might lead to buggy behaviour). Two options that often have a large impact on performance are -decide-theories
and -conflict-min-cut
:
$monosat -decide-theories -conflict-min-cut input_file.gnf
The -decide-theories
option will cause the solver to make heuristic decisions that try to satisfy the various SMT predicates, which will often lead to improved performance, but can be pathologically bad in some common cases, and so is disabled by default. -conflict-min-cut
will cause the solver to use a much slower, but more aggressive, clause learning strategy for reachability predicates; it may be useful for small, dificult instances.
MonoSAT implements a generalization of the circuit routing heuristics described in Routing Under Constraints; you can activate them using the '-ruc' command line option. Thse can greatly improve performance on instances that use multiple reachability constraints. See examples/python/routing/router.py
for an example usage.
MonoSAT is written in C++. Core SAT solver functionality is in the core/
and simp/
directories; in particular, note core/Config.cpp
, which is a central listing of all the configuration options available to MonoSAT.
The graph and finite state machine theory solvers can be found in graph/
and fsm/
. Many of the graph algorithsms used by MonoSAT are collected in dgl/
(for 'Dynamic Graph Library').
dgl/
incldudes C++ implementations of several dynamic graph algorithms (as well as some more common graph algorithms), and is well-optimized for medium sized (<20,000 nodes, < 100,000 edges), sparse graphs. The algorithms in dgl are designed for the case where the set of possible edges (and nodes) is fixed and known in advance (or only changes infrequently), and from that fixed set of possible edges many subsets of edges will subsequently be selected to be included in or excluded from the graph. 'dgl' supports templated edge weights and edge capacities, and has been tested successfully with integers, floats, and GMP arbitrary precision rationals.
- Reachability/Shortest Path
- Ramalingam-Reps dynamic single-source shortest paths algorithm (with improvements described in Buriol et al. 2008)
- Thorup's dynamic connectivity algorithm (for undirected graphs)
- Dijkstra's algorithm
- DFS/BFS
- Minimum Spanning Tree
- Spira and Pan's dynamic minimum spanning tree algorithm
- Kruskal's algorithm
- Prim's algorithm
- Maximum s-t Flow
- Kohli and Torr's dynamic variant of Kolmogorov and Boykov's maximum flow algorithm.
- Edmonds-Karp algorithm (including a dynamic variant)
- Dinitz's algorithm (including the dynamic tree variant)
- And many supporting algorithms and data structures, including:
- Pearce and Kelly's `PK' algorithm for dynamic topological sort in DAGs
- Euler Tree
- Link Cut Tree
- Tarjan's SCC
- Splay Tree
- Disjoint Set
The majority of MonoSAT is released under the MIT license (as documented in individual source files).
However, by default MonoSAT links some GPLv2 sources (found in src/monosat/dgl/alg/dyncut/
).
If built with these sources, the resulting binary is licensed as a whole under the GPLv2.
MonoSAT can be built without including any GPL licensed sources, in which case it retains the MIT license. To build MonoSAT without using GPL sources, use: ''' $cmake -DGPL=OFF '''
MonoSAT was made possible by the use of several open-source projects, including the afore-mentioned MiniSat, as well as a high-performance dynamic maximum-flow algorithm by Pushmeet Kohli and Philip Torr, Emil Stefanov's implementation of Disjoint Sets, and a Link-Cut Tree implementation by Daniel Sleator.
- Bayless, S., Bayless, N., Hoos, H. H., Hu, A.J. "SAT Modulo Monotonic Theories", Proceedings of the 29th AAAI Conference on Artificial Intelligence (2015)
- Klenze, T., and Bayless, S., and Hu, A.J. "Fast, Flexible, and Minimal CTL synthesis via SMT", International Conference on Computer Aided Verification (2016)
- Nadel, A. "Routing under Constraints." Formal Methods in Computer-Aided Design FMCAD (2016)
- Bayless, S., Hoos, H. H., and Hu, A.J. "Scalable, high-quality, SAT-based Multi-Layer Escape Routing", Proceedings of the 35th International Conference on Computer-Aided Design (2016)
- Bayless, S. "SAT Modulo Monotonic Theories." PhD thesis, University of British Columbia (2017)
- Bayless, S., Kodirov, N., Beschastnikh, N., Hoos, H. H., Hu, A.J. "Scalable Constraint-Based Virtual Data Center Allocation", International Joint Conference on Artificial Intelligence (2017)
If you would like your publication listed here, please contact Sam Bayless.
If you want to cite MonoSAT, please cite our 2015 AAAI paper:
@article{monosat2015,
author = {Sam Bayless and Noah Bayless and Holger H. Hoos and Alan J. Hu},
title = {{SAT Modulo Monotonic Theories}},
booktitle = {Proceedings of the 29th AAAI Conference on Artificial Intelligence},
year = {2015}
}
- Buriol, Luciana S., Mauricio GC Resende, and Mikkel Thorup. "Speeding up dynamic shortest-path algorithms." INFORMS Journal on Computing 20.2 (2008): 191-204.
- Dijkstra, Edsger W. "A note on two problems in connexion with graphs." Numerische mathematik 1.1 (1959): 269-271
- Dinitz, Y. "Algorithm for solution of a problem of maximum flow in a network with power estimation". Doklady Akademii nauk SSSR 11: 1277–1280 (1970)
- Edmonds, Jack, and Richard M. Karp. "Theoretical improvements in algorithmic efficiency for network flow problems." Journal of the ACM (JACM) 19.2 (1972): 248-264
- Kohli, Pushmeet, and Philip HS Torr. "Efficiently solving dynamic markov random fields using graph cuts." Computer Vision, 2005. ICCV 2005. Tenth IEEE International Conference on. Vol. 2. IEEE, 2005
- Korduban, D. "Incremental Maximum Flow in Dynamic graphs." Theoretical Computer Science Stack Exchange. http://cstheory.stackexchange.com/q/10186, 2012
- Kruskal, Joseph B. "On the shortest spanning subtree of a graph and the traveling salesman problem." Proceedings of the American Mathematical society 7.1 (1956): 48-50
- Prim, Robert Clay. "Shortest connection networks and some generalizations." Bell system technical journal 36.6 (1957): 1389-140
- Ramalingam, Ganesan, and Thomas Reps. "An incremental algorithm for a generalization of the shortest-path problem." Journal of Algorithms 21.2 (1996): 267-305.
- Sleator, Daniel D., and Robert Endre Tarjan. "A data structure for dynamic trees." Proceedings of the thirteenth annual ACM symposium on Theory of computing. ACM, 1981.
- Spira, Philip M., and A. Pan. "On finding and updating spanning trees and shortest paths." SIAM Journal on Computing 4.3 (1975): 375-380.
- Thorup, Mikkel. "Near-optimal fully-dynamic graph connectivity." Proceedings of the thirty-second annual ACM symposium on Theory of computing. ACM, 2000.
- Pearce, David J., and Kelly, Paul H. J. "A Dynamic Topological Sort Algorithm for Directed Acyclic Graphs", 2006