Splr is a pure Rustic modern SAT solver, based on Glucose 4.1. It adopts various research results on SAT solvers:
Many thanks to SAT researchers.
Please check ChangeLog about recent updates.
Though Splr comes with ABSOLUTELY NO WARRANTY, I'd like to show some results.
Just run cargo install splr --features cli
after installing the latest cargo.
Two executables will be installed:
splr
-- the solverdmcr
-- a very simple model checker to verify a satisfiable assignment set which was generated by splr
.Splr is a standalone program, taking a CNF file. The result will be saved to a file, which format is defined by SAT competition 2011 rules.
plain
$ splr tests/sample.cnf
sample.cnf 250,1065 |time: 0.14
#conflict: 8481, #decision: 9686, #propagate: 18146
Assignment|#rem: 243, #ass: 1, #elm: 6, prg%: 2.8000
Clause|Remv: 6952, LBD2: 42, Binc: 0, Perm: 1056
Stabilize|#RST: 24, #BLK: 138, #STB: 2, #CNC: 86
EMA|tLBD: 1.6450, tASG: 2.9712, eMLD: 6.6816, eCCC: 0.7302
Conflict|eLBD: 8.70, cnfl: 10.67, bjmp: 9.84, /ppc: 2.14
misc|elim: 1, cviv: 0, #vbv: 0, /cpr: 353.38
Strategy|mode: Initial search phase before a main strategy
Result|file: ./.ans_sample.cnf
s SATISFIABLE: tests/sample.cnf
plain
$ cat .ans_sample.cnf
c This file was generated by splr-0.5.0 for tests/sample.cnf
c
c CNF file(sample.cnf), #var: 250, #cls: 1065
c #conflict: 8481, #decision: 9686, #propagate: 18146,
c Assignment|#rem: 243, #fix: 1, #elm: 6, prg%: 2.8000,
c Clause|Remv: 6952, LBD2: 42, Binc: 0, Perm: 1056,
c Restart|#RST: 24, #BLK: 138, #STB: 2, #CNC: 86,
c EMA|tLBD: 1.6450, tASG: 2.9712, eMLD: 6.6816, eCCC: 1,
c Conflict|eLBD: 8.70, cnfl: 10.67, bjmp: 9.84, /ppc: 2.1396,
c misc|elim: 1, cviv: 0, #vbv: 0, /cpr: 353.38,
c Strategy|mode: Initial, time: 0.14,
c
s SATISFIABLE
v 1 2 3 4 -5 6 7 -8 -9 10 11 -12 -13 -14 15 16 -17 18 ... 0
plain
$ dmcr tests/sample.cnf
A valid assignment set for tests/sample.cnf is found in .ans_sample.cnf.
If you want to certificate unsatisfiability, use splr --certificate
and recommend to use Grid.
plain
$ splr -c tests/unsat.cnf
unsat.cnf 83,570 |time: 0.00
#conflict: 0, #decision: 0, #propagate: 0
Assignment|#rem: 19, #ass: 64, #elm: 0, prg%: 77.1084
Clause|Remv: 0, LBD2: 0, Binc: 126, Perm: 135
Restart|#RST: 0, #BLK: 0, #STB: 0, #CNC: 0
EMA|tLBD: NaN, tASG: NaN, eMLD: 0.0000, eCCC: 0.0000
Conflict|eLBD: 0.00, cnfl: 0.00, bjmp: 0.00, /ppc: NaN
misc|elim: 0, cviv: 0, #vbv: 0, /cpr: NaN
Strategy|mode: Initial search phase before a main strategy
Result|file: ./.ans_unsat.cnf
Certificate|file: proof.out
s UNSATISFIABLE: tests/unsat.cnf
plain
$ egrep -v '^[cs]' < proof.out > proof.drat
```plain $ gratgen tests/unsat.cnf proof.drat -o proof.grat c sizeof(cdbt) = 4 c sizeof(cdbt*) = 8 c Using RAT run heuristics c Parsing formula ... 0ms c Parsing proof (ASCII format) ... 0ms c Forward pass ... 0ms c Starting Backward pass c Single threaded mode c Waiting for aux-threads ...done c Lemmas processed by threads: 0 mdev: nan c Finished Backward pass: 0ms c Writing combined proof ... 0ms s VERIFIED c Timing statistics (ms) c Parsing: 1 c Checking: 0 c * bwd: 0 c Writing: 0 c Overall: 2 c * vrf: 2
c Lemma statistics c RUP lemmas: 0 c RAT lemmas: 0 c RAT run heuristics: 0 c Total lemmas: 0
c Size statistics (bytes) c Number of clauses: 981 c Clause DB size: 25372 c Item list: 15696 c Pivots store: 4096 ```
gratchk
plain
$ gratchk unsat tests/unsat.cnf proof.grat
gratchk unsat tests/unsat.cnf proof.grat gratchktests/unsat.cnf proof.grat
c Reading cnf
c Reading proof
c Done
c Verifying unsat
s VERIFIED UNSAT
$
Since 0.4.0, you can use Splr in your programs.
```rust use splr::*; use std::convert::TryFrom;
fn main() {
let v: Vec
```rust use splr::*; use std::{convert::TryFrom, env::args};
fn main() {
let cnf = args().nth(1).expect("takes an arg");
let assigns: Vec
fn run(cnf: &str, assigns: &[i32]) -> usize {
let mut solver = Solver::tryfrom(cnf).expect("panic at loading a CNF");
for n in assigns.iter() {
solver.addassignment(*n).expect("panic at assertion");
}
let mut count = 0;
loop {
match solver.solve() {
Ok(Certificate::SAT(ans)) => {
count += 1;
println!("s SATISFIABLE({}): {:?}", count, ans);
let ans = ans.iter().map(|i| -i).collect::
Since 0.4.1, Solver
has iter()
. So you can iterate on satisfiable 'solution: Vec<i32>
's as:
```rust
for (i, v) in Solver::try_from(cnf).expect("panic").iter().enumerate() { println!("{}-th answer: {:?}", i, v); } ```
| mnemonic | meaning |
| --------- |------- |
| #var
| the number of variables used in the given CNF file |
| #cls
| the number of clauses used in the given CNF file |
| time
| elapsed CPU time in seconds (or wall-clock time if CPU time is not available) |
| #conflict
| the number of conflicts |
| #decision
| the number of decisions |
| #propagate
| the number of propagates (its unit is literal) |
| #rem
| the number of remaining variables |
| #fix
| the number of asserted variables (which has been assigned a value at decision level zero) |
| #elm
| the number of eliminated variables |
| prg%
| the percentage of remaining variables / total variables
|
| Remv
| the number of learnt clauses which are not biclauses |
| LBD2
| the number of learnt clauses which LBDs are 2 |
| Binc
| the number of binary learnt clauses |
| Perm
| the number of given clauses and binary learnt clauses |
| #RST
| the number of restart |
| #BLK
| the number of blocking restart |
| #STB
| the number of restart in stabilization mode |
| #CNC
| the number of blocking restart in stabilization mode |
| tLBD
| the trend rate of learn clause's LBD |
| tASG
| the trend rate of the number of assigned variables |
| eMLD
| the EMA, Exponential Moving Average, of Maximum LBD of Dependency graphs |
| eCCC
| the EMA, Exponential Moving Average, of activity-based Conflict Correlation Coefficients |
| eLBD
| the EMA, Exponential Moving Average, of learn clauses' LBDs |
| eMLD
| the EMA, Exponential Moving Average, of learn clauses' LBDs |
| cnfl
| the EMA of decision levels at which conflicts occur |
| bjmp
| the EMA of decision levels to which backjumps go |
| /ppc
| the number of propagations per conflict |
| elim
| the number of invocations of clause/var elimination |
| cviv
| the number of invocations of clause vivification |
| #vbv
| the number of vars which were asserted by clause vivification |
| /cpr
| the number of conflicts per restart |
| mode
| Selected strategy's id |
| time
| the elapsed CPU time in seconds |
Please check the help message.
```plain $ splr --help splr 0.5.0 Narazaki Shuji shujinarazaki@protonmail.com A modern CDCL SAT solver in Rust
USAGE:
splr [FLAGS] [OPTIONS]
FLAGS: -h, --help Prints help information -C, --no-color Disable coloring -q, --quiet Disable any progress message -c, --certify Writes a DRAT UNSAT certification file -l, --log Uses Glucose-like progress report -V, --version Prints version information
OPTIONS:
--ADP
ARGS:
```
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2020, Narazaki Shuji