Boolector can be used as stand-alone SMT solver which reads either BTOR and SMT-LIB 1.2. Furthermore, Boolector provides a public API in order to use Boolector as backend in other tools.
First of all, the user has to create a boolector instance by calling boolector_new. This instance is needed by all other functions. After creating an instance, the rewrite level of the rewriting engine can be set by boolector_set_rewrite_level and/or model generation can be enabled by boolector_enable_model_gen. Then, the user can build expressions of bit-vectors and arrays. As the design of Boolector was motivated by real hardware, we do not distinguish between the type 'boolean' and the type 'bit-vector of bit-width one'. After building expressions the user can assert them by boolector_assert. The resulting instance can be decided by boolector_sat. If model generation has been enabled and the instance is satisfiable, the user can obtain assignments to bit-vectors resp. arrays by boolector_bv_assignment resp. boolector_array_assignment. The assignments are not limited to variables. They can be obtained for arbitrary expressions. Finally, Boolector supports incremental usage with assumptions analogously to MiniSAT. The incremental usage can be enabled by boolector_enable_inc_usage. Assumptions can be added by boolector_assume.
Already during construction of the expression DAG, rewriting is performed. This rewriting should simplify the DAG already during construction. When boolector_sat is called, Boolector starts an extra rewriting phase to simplify the DAG. The rewrite level can be configured by boolector_set_rewrite_level.
Boolector internally uses a set of base operators. The set is documented in BTOR: Bit-Precise Modelling of Word-Level Problems for Model Checking. Many operators that are available in the API are rewritten as combination of base operators internally. For example, two's complement is rewritten as one's complement and addition of 1. This behavior is not influenced by the rewrite level.
The functions of Boolector's public interface are guarded by public assertions. Public assertions are always enabled. They check if the functions have been correctly called by the user. If not, then an error message is printed out and 'abort' is called. For example, we call boolector_var and pass NULL as symbol name. Then, we obtain the following error message:
[boolector] boolector_var: 'symbol' must not be NULL
This is not a bug. The user has violated the pre-conditions of the function, and therefore Boolector aborts.