CSB (Count and Sample on Bitvectors) is an approximate model counting and almost-uniform sampling tool aimed at solving constraints of bitvectors.
To learn more about CSB, please have a look at our SMT Workshop '24 paper.
CSB uses STP as its frontend and is built on top of that. For counting it uses ApproxMC (with Arjun). For sampling, it uses UniGen.
For a quick install:
sudo apt install git cmake bison flex libboost-all-dev python3 perl build-essential python3-distutils-extra zlib1g-dev libboost-program-options-dev libboost-serialization-dev libgmp-dev libmpfr-dev
git clone https://github.com/meelgroup/csb
cd csb
./scripts/deps/setup-staticdeps.sh
mkdir build && cd build
cmake -DSTATICCOMPILE=ON ..
cmake --build .
The samples should be uniform in practice. Run with an SMT-LIB2 file:
./csb -s --ns 10 --seed 6 myproblem.smt2
The samples are generated with theoretical guarantees on uniformity. But this procedure might be slower than uniform-like sampler.
./csb -u --ns 10 --seed 6 myproblem.smt2
Change seed value to get different samples. Refer to this post to know more about uniform, almost-uniform and uniform like samplers.
Run with an SMT-LIB2 file:
./csb -c myproblem.smt2
The SMT-LIB2 format is the recommended file format, because it is parsed by all modern bitvector solvers. Only quantifier-free bitvectors and arrays are implemented from the SMT-LIB2 format.
CSB supports projection variables for counting and sampling. Variables can be designated as projection variables using the proj-var
keyword. Each proj-var
command can include one or more variables and multiple proj-var
commands are supported. Projection variables can be declared at any point in the file, provided they are specified after the variable declaration and before the proj-var
command. Here is an example of extending the SMT-LIB2 format to include projection variables.
(set-logic QF_BV)
(declare-const a (_ BitVec 6))
(declare-const b (_ BitVec 6))
(declare-const c (_ BitVec 6))
(declare-const d (_ BitVec 6))
(proj-var a b)
(proj-var d)
(assert (bvult a #b001010))
(assert (bvult b #b011110))
(assert (= (bvadd c d) #b001000))
(check-sat)
CSB converts bitvector constraints into SAT using STP, integrating with ApproxMC or UniGen based on specific needs of counting or sampling. The benchmarks used for evaluating CSB in the SMT workshop paper are available here.
Please refer to STP/UniGen/ApproxMC for the respective authors.