1 Introduction

Model-constructing satisfiability (MCSAT) [19, 20, 24] is an alternative to the CDCL \((\mathcal T)\) scheme [28] for Satisfiability Modulo Theories (SMT). While CDCL \((\mathcal T)\) interfaces a CDCL SAT solver [23] with black-box decision procedures, MCSAT integrates first-order reasoning into CDCL directly. Like CDCL, MCSAT alternates between search and conflict analysis. In the search phase, MCSAT assigns values to first-order variables and propagates unit consequences of these assignments. If a conflict occurs during search, e.g., when the domain of a first-order variable is empty, MCSAT enters conflict analysis and learns an explanation, which is a symbolic representation of what was wrong with the assignments causing the conflict. As in CDCL, the learned clause triggers backtracking from which search can resume. Decision procedures based on MCSAT have demonstrated strong performance in theories such as non-linear real [24] and integer arithmetic [19]. These theories are relatively well-behaved and provide features such as quantifier elimination and interpolation—the building blocks of conflict resolution in MCSAT.

We describe an MCSAT decision procedure for the theory of bitvectors (\(\mathcal B\mathcal V_{}\)). In contrast to arithmetic, the complexity of \(\mathcal B\mathcal V_{}\) in terms of syntax and semantics, combined with the lack of word-level interpolation and quantifier elimination, makes the development of \(\mathcal B\mathcal V_{}\) decision procedures (MCSAT or not) very difficult. The state-of-the art \(\mathcal B\mathcal V_{}\) decision procedures are all based on a “preprocess and bitblast” pipeline [12, 22, 25]: they reduce the \(\mathcal B\mathcal V_{}\) problems to a pure SAT problem by reducing the word-level semantics to bit-level semantics. Exceptions to the bitblasting approach do exist, such as [4, 16], which generally do not perform as well as bitblasting except on small classes of crafted examples, and the MCSAT approach of [30], which we discuss below and in the conclusion.

An MCSAT decision procedure must provide two theory-specific reasoning mechanisms.

First, the procedure must maintain a set of values that are feasible for each variable. This set is updated during the search. It is used to propagate variable values and to detect a conflict when the set becomes empty. Finding a suitable representation for domains is a key step in integrating a theory into MCSAT. We represent variable domains with Binary Decision Diagrams (BDDs) [5]. BDDs can represent any set of bitvector values. By being canonical, they offer a simple mechanism to detect when a domain becomes a singleton—in which case MCSAT can perform a theory propagation—and when a domain becomes empty–in which case MCSAT enters conflict analysis. In short, BDDs offer a generic mechanism for proposing and propagating values, and for detecting conflicts. In contrast, previous work by Zeljić et al. [30] represents bitvector domains using intervals and patterns, which cannot represent every set of bitvector values precisely; they over-approximate the domains.

Second, once a conflict has been detected, the procedure must construct a symbolic explanation of the conflict. This explanation must rule out the partial assignment that caused the conflict, but it is desirable for explanations to generalize and rule out larger parts of the search space. For this purpose, previous work [30] relied on incomplete abstraction techniques (replace a value by an interval; extend a value into a larger set by leaving some bits unassigned), and left open the idea of using interpolation to produce explanations. Instead of aiming for a uniform, generic explanation mechanism, we take a modular approach. We develop efficient word-level explanation procedures for two useful fragments of \(\mathcal B\mathcal V_{}\), based on interpolation. Our first fragment includes bitvector equalities, extractions, and concatenations where word-level explanations can be constructed through model-based variants of classic equality reasoning techniques (e.g., [4, 9, 10]). Our second fragment is a subset of linear arithmetic where explanations are constructed by interval reasoning in modular arithmetic. When conflicts do not fit into either fragment, we build an explanation by bitblasting and extracting an unsat core. Although this fallback produces theory lemmas expressed at the bit-level, it is used only as a last resort. In addition, this bitblasting-based procedure is local and limited to constraints that are relevant to the current conflict; we do not apply bitblasting to the full problem.

Section 2, is an overview of MCSAT. It also presents the BDD approach and general considerations for conflict explanation. Section 3 describes our interpolation algorithm for equality with concatenation and extraction. Section 4 presents our interpolation method for a fragment of linear bitvector arithmetic. Section 5 presents the normalization technique we apply to conflicts in the hope of expressing them in that bitvector arithmetic fragment. Section 6 presents an evaluation of the approach, which we implemented in the Yices 2 solver [11].Footnote 1

2 A General Scheme for Bitvectors

By \(\mathcal B\mathcal V_{} \), we denote the theory of quantifier-free fixed-sized bitvectors, a.k.a. QF_BV in SMT-LIB [1]. A first-order term u of \(\mathcal B\mathcal V_{} \) is sorted as either a Boolean or a bitvector of a fixed length (a.k.a. bitwidth), denoted \({\left| u\right| }\). Its set of variables (a.k.a. uninterpreted constants) is denoted \( \mathsf{var}^{}(u)\). This paper only uses a few \(\mathcal B\mathcal V_{} \) operators. The concatenation of bitvector terms t and u is denoted \(t\circ u\); the binary predicates \(<^\mathsf{u}\), \(\le ^\mathsf{u}\) denote unsigned comparisons, and \(<^\mathsf{s}\), \(\le ^\mathsf{s}\) denote signed comparisons. In such comparisons, both operands must have the same bitwidth. If n is the bitwidth of u, and l and h are two integer indices such that \(0 \le l < h \le n\), then \(u[h{\,\!:\!\,}l]\), extracts \(h{-}l\) bits of u, namely the bits at indices between l and \(h{-}1\) (included). We write \(u[{\,\!:\!\,}l]\), \(u[h{\,\!:\!\,}]\), and \(u[l]\) as abbreviations for \(u[n{\,\!:\!\,}l]\), \(u[h{\,\!:\!\,}0]\), and \(u[l{+}1{\,\!:\!\,}l]\), respectively. Our convention is to have bitvector indices start from the right-hand side, so that bit 0 is the right-most bit and \(0011[2{\,\!:\!\,}]\) is 11. We use standard notations for bitvector arithmetic, which coincides with arithmetic modulo \(2^w\) where w is the bitwidth. We sometimes use integer constants e.g., 0, 1, \(-1\) for bitvectors when the bitwidth is clear. We use the standard (quantifier-free) notions of literal, clause, cube, and formula [29].

A model of a \(\mathcal B\mathcal V_{} \) formula \(\varPhi \) is an assignment that gives a bitvector (resp. Boolean) value to all bitvector (resp. Boolean) variables of \(\varPhi \), in such a way that \(\varPhi \) evaluates to true, under the standard interpretation of Boolean and bitvector symbols. To simplify the presentation, we assume in this paper that there are no Boolean variables, although they are supported in our implementation.

2.1 MCSAT Overview

MCSAT searches for a model of an input quantifier-free formula by building a partial assignment—maintained in a trail—and extends the concepts of unit propagation and consistency to first-order terms and literals [19, 20, 24]. Reasoning is implemented by theory-specific plugins, each of which has a partial view of the trail. In the case of \(\mathcal B\mathcal V_{} \), the bitvector plugin sees in the trail an assignment \(\mathcal {M}\) of the form \(x_1\mapsto v_1,\ldots ,x_n\mapsto v_n\) that gives values to bitvector variables, and a set of bitvector literals \(L_1,\ldots ,L_t\), called constraints, that must be true in the current trail. MCSAT and its bitvector plugin maintain the invariant that none of the literals \(L_i\) evaluates to false under \(\mathcal {M}\); either \(L_i\) is true or some variable of \(L_i\) has no value in \(\mathcal {M}\). To maintain this invariant, they detect unit inconsistencies: We say that literal \(L_i\) is unit in y if y is the only unassigned variable of \(L_i\), and that a trail is unit inconsistent if there is a variable y and a subset \(\{ C_1,\ldots , C_m\}\) of \(\{ L_1,\ldots , L_t \}\), called a conflict, such that every \(C_j\) is unit in y and the formula \(\exists y \bigwedge _{i\,=\,1}^mC_i\) evaluates to false under \(\mathcal {M}\). In such a case, y is called the conflict variable and \(C_1,\ldots ,C_m\) are called the conflict literals.

When such a conflict is detected, the current assignment, or partial model, \(\mathcal {M}\) cannot be extended to a full model; some values assigned to \(x_1,\ldots , x_n\) must be revised. As in CDCL, MCSAT backtracks and updates the current assignment by learning a new clause that explains the conflict. This new clause must not contain other variables than \(x_1,\ldots ,x_n\) and it must rule out the current assignment. For some theories, this conflict explanation can be built by quantifier elimination. More generally, we can build an explanation from an interpolant.

Definition 1 (Interpolant)

A clause I is an interpolantFootnote 2 for formula F at model \(\mathcal {M}\) assigning values to \(x_1,\ldots , x_n\), if (1) \(F \Rightarrow I\) is valid (in \(\mathcal B\mathcal V_{}\)), (2) The variables in I are in \(\{x_1,\ldots , x_n\}\cap \mathsf{var}^{}(F)\), and (3) I evaluates to false in \(\mathcal {M}\).

Given an interpolant I for the conjunction \(\bigwedge _{i\,=\,1}^mC_i\) of the conflict literals (or equivalently, for \(\exists y\bigwedge _{i\,=\,1}^mC_i\)) at the current model \(\mathcal M\), the conflict explanation is clause \(\left( \bigwedge _{i\,=\,1}^mC_i\right) \Rightarrow I\). Our main goal is constructing such interpolants in \(\mathcal B\mathcal V_{}\).

2.2 BDD Representation and Conflict Detection

To detect conflicts, we must keep track of the set of feasible values for every unassigned variable y. These sets are frequently updated during search so an efficient representation is critical. The following operations are needed:

  • updating the set when a new constraint becomes unit in y,

  • detecting when the set becomes empty,

  • selecting a value from the set.

For \(\mathcal B\mathcal V_{}\), Zeljić et al. [30] represent sets of feasible values using both intervals and bit patterns. For example, the set defined by the interval [0000, 0011] and the pattern ???1 is the pair \(\{ 0001, 0011 \}\) (i.e., all bitvectors in the interval whose low-order bit is 1). This representation is lightweight and efficient but it is not precise. Some sets are not representable exactly. We use Binary Decision Diagrams (BDD) [5] over the bits of y. The major advantage is that BDDs provide an exact implementation of any set of values for y. Updating sets of values amounts to computing the conjunction of BDDs (i.e., set intersection). Checking whether a set is empty and selecting a value in the set (if it is not), can be done efficiently by, respectively, checking whether the BDD is false, and performing a top-down traversal of the BDD data structure. There is a risk that the BDD representation explodes but this risk is reduced in our context since each BDD we build is for a single variable (and most variables do not have too many bits). We use the CUDD package [8] to implement BDDs.

2.3 Baseline Conflict Explanation

Given a conflict as described previously, the clause \((x_1 {\,\not \simeq _{}\,}v_1)\vee \cdots \vee (x_n {\,\not \simeq _{}\,}v_n)\), which is falsified by model \(\mathcal M\) only, is an interpolant for \(\bigwedge _{i\,=\,1}^mC_i\) at \(\mathcal {M}\) according to Definition 1. This gives the following trivial conflict explanation:

$$ C_1 \wedge \cdots \wedge C_m \Rightarrow (x_1 {\,\not \simeq _{}\,}v_1) \vee \cdots \vee (x_n {\,\not \simeq _{}\,}v_n) $$

We seek to generalize model \({\mathcal M}\) with a formula that rules out bigger parts of the search space than just \({\mathcal M}\). A first improvement is replacing the constraints by a core \(\mathcal {C}\), that is, a minimal subset of \(\{C_1,\ldots ,C_n\}\) that evaluates to false in \({\mathcal M}\).Footnote 3

To produce the interpolant I, we can bitblast the constraints \(C_1, \ldots , C_m\) and solve the resulting SAT problem under the assumptions that each bit of \(x_1, \ldots , x_n\) is true or false as indicated by the values \(v_1, \ldots , v_n\). Since the SAT problem encodes a conflict, the SAT solver will return an unsat core, from which we can extract bits of \(v_1, \ldots , v_n\) that contribute to unsatisfiability. This generalizes \({\mathcal M}\) by leaving some bits unassigned, as in [30].

This method is general. It works whatever the constraints \(C_1,\ldots ,C_m\), so we use it as a default procedure. The bitblasting step focuses on constraints that are unit in y, which typically leads to a much smaller SAT problem than bitblasting the whole problem from the start. However, the bitblasting approach can still be costly and it may produce weak explanations.

Example 1

Consider the constraints \(\lbrace x_1 {\,\not \simeq _{}\,}x_2, x_1 {\,\simeq _{}\,}y, x_2 {\,\simeq _{}\,}y \rbrace \) and the assignment \(x_1 \mapsto 1001, x_2 \mapsto 0101\). The bitblasting approach might produce explanation \( (x_1 {\,\simeq _{}\,}y \wedge x_2 {\,\simeq _{}\,}y) \Rightarrow (x_1[3]\Rightarrow x_2[3])\). After backtracking, we might similarly learn that \((x_2[3]\Rightarrow x_1[3])\). In this way, it will take eight iterations to learn enough information to represent the high-level explanation:

$$ (x_1 {\,\simeq _{}\,}y \wedge x_2 {\,\simeq _{}\,}y) \Rightarrow x_1{\,\simeq _{}\,}x_2. $$

A procedure that can produce \((x_1{\,\simeq _{}\,}x_2)\) directly is much more efficient.

3 Equality, Concatenation, Extraction

Our first specialized interpolation mechanism applies when constraints \(\mathcal {C} = \lbrace C_1,\ldots , C_m \rbrace \) belong to the following grammar:

where e ranges over any bitvector terms such that \(y\not \in \mathsf{var}^{}(e)\). Without loss of generality, we can assume that \(\mathcal {C}\) is a core. We split \(\mathcal {C}\) into a set of equalities and a set of disequalities .

Slicing. Our first step rewrites \(\mathcal {C}\) into an equivalent sliced form. This computes the coarsest-base slicing [4, 9] of equalities and disequalities in \(\mathcal {C}\). The goal of this rewriting step is to split the variables into slices that can be treated as independent terms. The terms in coarsest-base slicing are either of the form \(y[h{\,\!:\!\,}l]\) (slices), or are evaluable terms e with \(y\not \in \mathsf{var}^{}(e)\).

Example 2

Consider the constraints \(E = \lbrace x_1[4{\,\!:\!\,}0] {\,\simeq _{}\,}x_1[8{\,\!:\!\,}4], y[6{\,\!:\!\,}2] {\,\simeq _{}\,}y[4{\,\!:\!\,}0] \rbrace \) and \(\lbrace y[4{\,\!:\!\,}0] {\,\not \simeq _{}\,}x_1[8{\,\!:\!\,}4] \rbrace \) over variables y of length 6, and \(x_1\) of length 8. We cannot treat \(y[6{\,\!:\!\,}2]\) and \(y[4{\,\!:\!\,}0]\) as independent terms because they overlap. To break the overlap, we introduce slices: \(y[6{\,\!:\!\,}4]\), \(y[4{\,\!:\!\,}2]\), and \(y[2{\,\!:\!\,}0]\). Equality \(y[6{\,\!:\!\,}2] {\,\simeq _{}\,}y[4{\,\!:\!\,}0]\) is rewritten to \((y[6{\,\!:\!\,}4] {\,\simeq _{}\,}y[4{\,\!:\!\,}2]) \wedge (y[4{\,\!:\!\,}2] {\,\simeq _{}\,}y[2{\,\!:\!\,}0])\). Disequality \(y[4{\,\!:\!\,}0] {\,\not \simeq _{}\,}x_1[8{\,\!:\!\,}4]\) is rewritten to \((y[4{\,\!:\!\,}2] {\,\not \simeq _{}\,}x_1[8{\,\!:\!\,}6])\vee (y[2{\,\!:\!\,}0] {\,\not \simeq _{}\,}x_1[6{\,\!:\!\,}4])\). The final result is

$$ \begin{array}{c} {E}_{s} = \{\ x_1[4{\,\!:\!\,}2] {\,\simeq _{}\,}x_1[8{\,\!:\!\,}6]\ ,\ x_1[2{\,\!:\!\,}0] {\,\simeq _{}\,}x_1[6{\,\!:\!\,}4]\ ,\ y[6{\,\!:\!\,}4] {\,\simeq _{}\,}y[4{\,\!:\!\,}2]\ ,\ y[4{\,\!:\!\,}2] {\,\simeq _{}\,}y[2{\,\!:\!\,}0] \ \}, \\ {D}_{s} = \{\ (y[4{\,\!:\!\,}2] {\,\not \simeq _{}\,}x_1[8{\,\!:\!\,}6])\vee (y[2{\,\!:\!\,}0] {\,\not \simeq _{}\,}x_1[6{\,\!:\!\,}4]) \ \}. \end{array} $$

Explanations. After slicing, we obtain a set \({E}_{s}\) of equalities and a set \({D}_{s}\) that contains disjunctions of disequalities. We can treat each slice as a separate variable, so the problem lies within the theory of equality on a finite domain.

figure a

We first analyze the conflict with equality reasoning against the model, as shown in Algorithm 1. We construct the E-graph \(\mathcal G\) from \({E}_{s}\) [10], while also taking into account the partial model \(\mathcal {M}\) that triggered the conflict. The model can evaluate terms e such that \(y\not \in \mathsf{var}^{}(e)\) to values , and those can be the source of the conflict. To use the model for evaluating terms, we maintain two invariants during E-graph construction:

  1. 1.

    If a component contains an evaluable term c, then the representative of that component is evaluable.

  2. 2.

    Two evaluable terms \(c_1\) and \(c_2\) in the same component must evaluate to the same value, otherwise this is the source of the conflict.

The E-graph construction can detect and explain basic conflicts between the equalities in E and the current assignment.

Example 3

Let \(r_1\), \(r_2\), \(r_3\) be bit ranges of the same width. Let E be such that \({E}_{s} = \lbrace x_1[r_1]{\,\simeq _{}\,}y[r_3],x_2[r_2]{\,\simeq _{}\,}y[r_3]\rbrace \), and let \(D = \emptyset \). Consider the model \(\mathcal M:= x_1 \mapsto 0\ldots 0, x_2 \mapsto 1\ldots 1\). Then, produces the conflict clause \(E\Rightarrow x_1[r_1]{\,\simeq _{}\,}x_2[r_2]\).

If the E-graph construction does not raise a conflict, then \(\mathcal M\) is compatible with the equalities in \({E}_{s}\). Since \(\mathcal {C}\) conflicts with \(\mathcal M\), the conflict explanation must involve \({D}_{s}\). To obtain an explanation, we decompose each disjunct \(C \in {D}_{s}\) into \(\left( C_{{E}_{s}}\vee C_{\mathcal M}\vee C_\mathsf{interface}\vee C_\mathsf{free} \right) \) as follows.

  • \(C_{{E}_{s}}\) contains disequalities \(t_1{\,\not \simeq _{}\,}t_2\) such that \(t_1\) and \(t_2\) have the same E-graph representatives; such disequalities are false because of the equalities in \({E}_{s}\).

  • \(C_{\mathcal M}\) contains disequalities \(t_1{\,\not \simeq _{}\,}t_2\) such that \(t_1\) and \(t_2\) have distinct representatives \(t'_1\) and \(t'_2\) with \([\![{t'_1}]\!]_{{\mathcal M}}=[\![{t'_2}]\!]_{{\mathcal M}}\); these are false because of \(\mathcal M\).

  • \(C_\mathsf{interface}\) contains disequalities \(t_1 {\,\not \simeq _{}\,}t_2\) such that \(t_1\) and \(t_2\) have distinct representatives \(t_1'\) and \(t_2'\), \(t_1'\) is evaluable and \(t_2'\) is a slice; we can still satisfy \(t_1{\,\not \simeq _{}\,}t_2\) by picking a good value for y; we say \(t_1'\) is an interface term.

  • \(C_\mathsf{free}\) contains disequalities \(t_1{\,\not \simeq _{}\,}t_2\) such that \(t_1\) and \(t_2\) have distinct slices as representatives; we can still satisfy \(t_1{\,\not \simeq _{}\,}t_2\) by picking a good value for y.

The disjuncts in \({D}_{s}\) take part in the conflict either when (i) one of the clauses in \({D}_{s}\) is false because \(C_\mathsf{interface}\) and \(C_\mathsf{free}\) are both empty; or (ii) the finite domains are too small to satisfy the disequalities in \(C_\mathsf{interface}\) and \(C_\mathsf{free}\), given the values assigned in \(\mathcal M\). In either case, we can produce a conflict explanation with Algorithm 2.

figure c

In a type (i) conflict, the algorithm produces an interpolant \(C^\mathsf{rep}_{\mathcal M}\) that is derived from a single element of \({D}_{s}\). Because we assume that \(\mathcal {C}\) is a core, a type (i) conflict can happen only if \({D}_{s}\) is a singleton. Here is how the algorithm behaves on such a conflict:

Example 4

Let \(r_1\) and \(r_2\) be bit ranges of the same length, let \(r_3\), \(r_4\), \(r_5\) be bit ranges of the same length. Assume \({E}_{s}\) contains

$$\{\ x_1[r_1]{\,\simeq _{}\,}y[r_1]\ ,\ x_2[r_2]{\,\simeq _{}\,}y[r_2]\ ,\ y[r_3]{\,\simeq _{}\,}y[r_5]\ ,\ y[r_4]{\,\simeq _{}\,}y[r_5]\ \},$$

and assume \({D}_{s}\) is the singleton \(\{\ (y[r_1]{\,\not \simeq _{}\,}y[r_2]\vee y[r_3]{\,\not \simeq _{}\,}y[r_4])\ \}\). Let \(\mathcal M\) map \(x_1\) and \(x_2\) to \(0\ldots 0\) and assume \(y[r_5]\) is the E-graph representative for component

$$\begin{aligned} \{\ y[r_3], y[r_4], y[r_5]\ \}. \end{aligned}$$

The unique clause of \({D}_{s}\) contains two disequalities:

  • The first one, \(y[r_1]{\,\not \simeq _{}\,}y[r_2]\), belongs to \(C_{\mathcal M}\) because the representatives of \(y[r_1]\) and \(y[r_2]\), namely \(x_1[r_1]\) and \(x_2[r_2]\), both evaluate to \(0\ldots 0\).

  • The second one, \(y[r_3]{\,\not \simeq _{}\,}y[r_4]\), belongs to \(C_{{E}_{s}}\) because the representatives of \(y[r_3]\) and \(y[r_4]\) are both \(y[r_5]\),

As \(C_\mathsf{interface}\) and \(C_\mathsf{free}\) are empty, Algorithm 2 outputs \(E\wedge D \Rightarrow x_1[r_1]{\,\not \simeq _{}\,}x_2[r_2]\).

For a conflict of type (ii), the equalities and disequalities that hold in \(\mathcal M\) between the interface terms make the slices of y require more values than there exist. So the produced conflict clause includes (the negation of) all such equalities and disequalities. An example can be given as follows:

Example 5

Assume E (and then \({E}_{s}\)) is empty and assume \({D}_{s}\) is

$$\{\ x_2[0]{\,\not \simeq _{}\,}x_2[1]\vee y[0]{\,\not \simeq _{}\,}y[1]\ ,\ x_1[0]{\,\not \simeq _{}\,}y[0]\ ,\ x_1[1]{\,\not \simeq _{}\,}y[1]\ \}$$

Let \(\mathcal M\) map \(x_1\) and \(x_2\) to 00. Then behaves as follows:

  • In the first clause, call it C, the first disequality is in \(C_{\mathcal M}\), as the two sides are in different components but evaluate to the same value; so \(C_0\) becomes \(\{\ x_2[0]{\,\not \simeq _{}\,}x_2[1]\ \}\); the second disequality features two slices and is thus in \(C_\mathsf{free}\); The clause is potentially satisfiable and we move to the next clause.

  • The second clause contains a single disequality that cannot be evaluated (since \(y[0]\) is not evaluable in \(\mathcal {M}\)). Term \(x_1[0]\) is added to S. The clause is potentially satisfiable so we move to the next clause.

  • The third clause of \({D}_{s}\) is similar. It contains a single disequality that cannot be evaluated. The interface term \(x_1[1]\) is added to S.

Since all clauses of \({D}_{s}\) have been processed, the conflict is of type (ii). Indeed, \(y[0]\) must be different from 0 because of the second clause, \(y[1]\) must also be different from 0 because of the third clause, but \(y[0]\) and \(y[1]\) must be different from each other because of the first clause. Since both \(y[0]\) and \(y[1]\) have only one bit, there are only two possible values for these two slices, so the three constrains are in conflict. Algorithm 2 produces the conflict clause

$$D \Rightarrow (\ x_2[0]{\,\not \simeq _{}\,}x_2[1]\vee x_1[0]{\,\not \simeq _{}\,}x_1[1]\ ).$$

The disequality \(x_2[0]{\,\not \simeq _{}\,}x_2[1]\) is necessary because, if it were true in \(\mathcal M\), we would not have to satisfy \(y[0]{\,\not \simeq _{}\,}y[1]\) and therefore \(y\leftarrow 11\) would work. Disequality \(x_1[0]{\,\not \simeq _{}\,}x_1[1]\) is also necessary because, if it were true in \(\mathcal M\), say with \(x_1\leftarrow 01\) (resp. \(x_1\leftarrow 10\)), then \(y\leftarrow 11\) (resp. \(y\leftarrow 00\)) would work.

Correctness of the method relies on the following lemma, whose proof can be found in [15].

Lemma 1 (The produced clauses are interpolants)

  1. 1.

    If Algorithm 1 reaches line 7, \(t'_1{\,\simeq _{}\,}t'_2\) is an interpolant for \(E\wedge D\) at \(\mathcal M\).

  2. 2.

    If Algorithm 2 reaches line 7, \(C^\mathsf{rep}_{\mathcal M}\) is an interpolant for \(E\wedge D\) at \(\mathcal M\).

  3. 3.

    If it reaches line 14, \(C_0\vee C_{\ne } \vee C_=\) is an interpolant for \(E\wedge D\) at \(\mathcal M\).

4 A Linear Arithmetic Fragment

Our second specialized explanation mechanism applies when constraints \(\mathcal {C} = \lbrace C_1,\ldots , C_m \rbrace \) belong to the following grammar:

where \(e_1\) and \(e_2\) range over evaluable bitvector terms (i.e., \(y\not \in \mathsf{var}^{}(e_1)\cup \mathsf{var}^{}(e_2)\)), and \(0_k\) is 0 on k bits. We can represent variable y as the term \(y[{\left| y\right| }{\,\!:\!\,}]\). This fragment of bitvector arithmetic is linear in y and there can be only one occurrence of y in terms. Constraints in Sect. 3 are then outside this fragment in general.

Let \(\mathcal A\) be \(\exists y (C_1\wedge \cdots \wedge C_m )\), and \({\mathcal M}\) be the partial model involved in the conflict. The interpolant for \(\mathcal A\) at model \({\mathcal M}\) is (roughly) produced as follows:

  1. 1.

    For each constraint \(C_i\), \(1\le i\le m\), featuring a (necessarily unique) lower-bits extract \(y[w_i{\,\!:\!\,}]\), we compute a condition cube \(c_i\) satisfied by \(\mathcal M\) and a forbidden interval \(I_i\) of the form \(\mathbf{[ }l_i\,{;}\,u_i\mathbf{[ }\), where \(l_i\) and \(u_i\) are evaluable terms, such that \(c_i \Rightarrow (C_i\Leftrightarrow (y[w_i{\,\!:\!\,}]\notin I_i))\) is valid.

  2. 2.

    We group the resulting intervals \((I_i)_{1\,\le \,i\,\le \,m}\) according to their bitwidths: if \(\mathcal S_w\) is the set of intervals forbidding values for \(y[w{\,\!:\!\,}]\), \(1\le w\le {\left| y\right| }\), then under condition \(\bigwedge _{i\,=\,1}^m c_i\) formula \(\mathcal A\) is equivalent to \(\exists y (\bigwedge _{w\,=\,1}^{{\left| y\right| }}\ (\ y[w{\,\!:\!\,}]\notin \bigcup _{I\,\in \,\mathcal S_w} I\ ))\).

  3. 3.

    We produce a series of constraints \(d_1\),..., \(d_p\) that are satisfied by \(\mathcal M\) and that are inconsistent with \(\bigwedge _{w\,=\,1}^{{\left| y\right| }}\ (\ y[w{\,\!:\!\,}]\notin \bigcup _{I\,\in \,\mathcal S_w} I\ )\). The interpolant will be \((\bigwedge _{i\,=\,1}^m c_i \wedge \bigwedge _{i\,=\,1}^p d_i) \Rightarrow \bot \): it is implied by \(\mathcal A\), and evaluates to false in \({\mathcal M}\).

Table 1. Creating the forbidden intervals

4.1 Forbidden Intervals

An interval takes the form \(\mathbf{[ }l\,{;}\,u\mathbf{[ }\), where the lower bound l and upper bound u are evaluable terms of some bitwidth w, with l included and u excluded. The notion of interval used here is considered modulo \(2^w\). We do not require \(l \le ^uu\) so an interval may “wrap around” in \(\mathbb {Z}/2^w\mathbb {Z}\). For instance, the interval \(\mathbf{[ }1111\,{;}\,0001\mathbf{[ }\) contains two bitvector values, namely, 1111 and 0000. If l and u evaluate to the same value, then we consider \(\mathbf{[ }l\,{;}\,u\mathbf{[ }\) to be empty (as opposed to the full domain, which we denote by \(\mathsf{full}^{w}\) or just \(\mathsf{full}^{}\)). Notation \(t\in I\) stands for literal \(\top \) if I is \(\mathsf{full}^{}\) and literal \(t{-}l <^u u{-}l\) if I is \(\mathbf{[ }l\,{;}\,u\mathbf{[ }\). The value in model \(\mathcal M\) of an evaluable term e (resp. evaluable cube c, interval I) is denoted \([\![{e}]\!]_{{\mathcal M}}\) (resp. \([\![{c}]\!]_{{\mathcal M}}\), \([\![{I}]\!]_{{\mathcal M}}\)).

Given a constraint C with unevaluable term t, we produce an interval \(I_C\) of forbidden values for t according to the rules of Table 1. A side condition literal \(c_C\) identifies when the lower and upper bounds would coincide, in which case the interval produced is either empty or full. For every row of the table, the formula \(c_C \Rightarrow ( C \Leftrightarrow t\notin I_C)\) is valid in \(\mathcal B\mathcal V_{}\). Given a partial model \(\mathcal {M}\), we convert C to such an interval by selecting the row where \([\![{c_C}]\!]_{{\mathcal M}}=\mathsf{true}\).

Example 6

  1. 6.1

    Assume \(C_1\) is literal \(\lnot (x_1\le ^\mathsf{u}y)\) and \({\mathcal M}=\{x_1\mapsto 0000\}\). Then line 4 of Table 1 applies, and \(I_{C_1}\) is interval \(\mathsf{full}^{}\) with condition \(x_1{\,\simeq _{}\,}0\).

  2. 6.2

    Assume \(C_1\) is \(\lnot (y {\,\simeq _{}\,}x_1)\), \(C_2\) is \((x_1 \le ^\mathsf{u}x_3 + y)\), \(C_3\) is \(\lnot (y - x_2 \le ^\mathsf{u}x_3 + y)\), and \({\mathcal M}=\{x_1\mapsto 1100,x_2\mapsto 1101,x_3\mapsto 0000\}\). Then by line 5, \(I_{C_1} = \mathbf{[ }x_1\,{;}\,x_1+1\mathbf{[ }\) with trivial condition \((0{\,\not \simeq _{}\,}-1)\), by line 3, \(I_{C_2} = \mathbf{[ }-x_3\,{;}\,x_1-x_3\mathbf{[ }\) with condition \((x_1{\,\not \simeq _{}\,}0)\), and by line 1, \(I_{C_3} = \mathbf{[ }x_2\,{;}\,-x_3\mathbf{[ }\) with condition \((-x_2{\,\not \simeq _{}\,}x_3)\).

Fig. 1.
figure 1

Transforming the forbidden intervals

Given the supported grammar, term t contains a unique subterm of the form \(y[w{\,\!:\!\,}]\). We transform \(I_C\) into an interval of forbidden values for \(y[w{\,\!:\!\,}]\) by applying procedure \(\textsf {forbid}(\,t\,,\,I_C\,,\,c_C\,)\) shown in Fig. 1, which proceeds by recursion on t. Its specification is given below, and correctness is proved by induction on t.

Lemma 2 (Correctness of forbidden intervals)

Assuming cube c is true in \(\mathcal {M}\), then \(\textsf {forbid}(\,t\,,\,I\,,\,c\,)\) returns a triple \((w, I', c')\) such that \(c'\) is a cube that is true in \(\mathcal {M}\), and both \(c'\Rightarrow c\) and \(c'\Rightarrow (t\notin I\Leftrightarrow y[w{\,\!:\!\,}]\notin I')\) are valid in \(\mathcal B\mathcal V_{}\).

Running \(\textsf {forbid}(\,t_{C_i}\,,\,I_{C_i}\,,\,c_{C_i}\,)\) for all constraints \(C_i\), \(1\,{\le }\,i\,{\le } m\), produces a family of triples \((w_i,I'_i,c'_i)_{1\,\le \,i\,\le \,m}\) such that, for each i, formula \(c'_i\Rightarrow (C_i \Leftrightarrow (y[w_i{\,\!:\!\,}]\notin I'_i))\) is valid in \(\mathcal B\mathcal V_{}\) and \(c'_i\) is true in \(\mathcal M\).

4.2 Interpolant

First, assume that one of the triples obtained above is of the form \((w,\mathsf{full}^{},c)\), coming from constraint C. As the interval forbids the full domain of values for \(y[w{\,\!:\!\,}]\), we produce conflict clause \(C\wedge c\Rightarrow \bot \). This formula is an interpolant for \(\mathcal A\) at \(\mathcal M\). This is illustrated in Example 7.1.

Example 7

  1. 7.1

    In Example 6.1 where \(C_1\) is literal \(\lnot (x_1\le ^\mathsf{u}y)\) and \({\mathcal M}=\{x_1\mapsto 0000\}\), the interpolant for \(\lnot (x_1\le ^\mathsf{u}y)\) at \({\mathcal M}\) is \((x_1{\,\simeq _{}\,}0)\Rightarrow \bot \).

  2. 7.2

    Example 6.2 does not contain a full interval. Model \({\mathcal M}\) satisfies the three conditions \(c_1:= (0{\,\not \simeq _{}\,}-1)\), \(c_2:= (x_1{\,\not \simeq _{}\,}0)\) and \(c_3:= (-x_2{\,\not \simeq _{}\,}x_3)\), and the intervals \(I_{1} = \mathbf{[ }x_1\,{;}\,x_1+1\mathbf{[ }\), \(I_{2} = \mathbf{[ }-x_3\,{;}\,x_1-x_3\mathbf{[ }\), and \(I_{3} = \mathbf{[ }x_2\,{;}\,-x_3\mathbf{[ }\), evaluate to \([\![{I_1}]\!]_{{\mathcal M}} = \mathbf{[ }1100\,{;}\,1101\mathbf{[ }\), \([\![{I_2}]\!]_{{\mathcal M}} = \mathbf{[ }0000\,{;}\,1100\mathbf{[ }\), and \([\![{I_3}]\!]_{{\mathcal M}} = \mathbf{[ }1101\,{;}\,0000\mathbf{[ }\), respectively. Note how \(\bigcup _{i\,=\,1}^3[\![{I_i}]\!]_{{\mathcal M}}\) is the full domain.

Fig. 2.
figure 2

Intervals collected from \(C_1\wedge \cdots \wedge C_m\)

Assume now that no interval is full (as in Example 7.2). We group the triples (wIc) into different layers characterized by their bitwidths w: I will henceforth be called a w-interval, restricting the feasible values for \(y[w{\,\!:\!\,}]\), and \(c_I\) denotes its associated condition in the triple. Ordering the groups of intervals by decreasing bitwidths \(w_1> w_2> \cdots > w_j\), as shown in Fig. 2, \(\mathcal S_j\) denotes the set of produced \(w_j\)-intervals. The properties satisfied by the triples entail that

$$ \mathcal A \wedge ({\bigwedge \nolimits _{i\,=\,1}^j}{\bigwedge \nolimits _{I\in \mathcal S_i}}c_I) \Rightarrow \mathcal B $$

is valid, where \(\mathcal B\) is \(\exists y \bigwedge _{i\,=\,1}^j (y[w_i{\,\!:\!\,}]\notin \bigcup _{I\in \mathcal S_i} I)\). And formula \((\bigwedge _{i\,=\,1}^j\bigwedge _{I\in \mathcal S_i}c_I) \Rightarrow \mathcal B\) is false in \(\mathcal M\). To produce an interpolant, we replace \(\mathcal B\) by a quantifier-free clause.

The simplest case is when there is only one bitwidth \(w=w_1\): the fact that \(\mathcal B\) is falsified by \(\mathcal M\) means that \(\bigcup _{I\in \mathcal S_1}[\![{I}]\!]_{{\mathcal M}}\) is the full domain \(\mathbb {Z}/2^w\mathbb {Z}\). Property “\(\bigcup _{I\in \mathcal S_1}{I}\) is the full domain” is then expressed symbolically as a conjunction of constraints in the bitvector language. To compute them, we first extract a sequence \(I_1, \ldots , I_q\) of intervals from the set \(\mathcal S_1\), originating from a subset \(\mathcal C\) of the original constraints \((C_i)_{i=1}^m\), and such that the sequence \([\![{I_{1}}]\!]_{{\mathcal M}},\ldots ,[\![{I_q}]\!]_{{\mathcal M}}\) of concrete intervals leaves no “hole” between an interval of the sequence and the next, and goes round the full circle of domain \(\mathbb {Z}/2^w\mathbb {Z}\): the sequence forms a circular chain of linking intervals. This chain can be produced by a standard coverage extraction algorithm (see, e.g., [15]). Formula \(\mathcal B := \exists y (y[w{\,\!:\!\,}]\notin \bigcup _{I\in \mathcal S_1} I)\) is then replaced by \((\bigwedge _{i\,=\,1}^q u_i\in I_{i+1})\Rightarrow \bot \), where \(u_i\) is the upper bound of \(I_i\) and \(I_{q+1}\) is \(I_1\). Each interval has its upper bound in the next interval (\(u_i\in I_{i+1}\)), i.e., intervals do link up with each other. The conflict clause is then

$$ (\mathcal C \wedge (\bigwedge \nolimits _{i\,=\,1}^q c_{I_i}) \wedge (\bigwedge \nolimits _{i\,=\,1}^q u_i\in I_{i+1})) \Rightarrow \bot $$

Example 8

For Example 7.2, the coverage-extraction algorithm produces the sequence \(I_1,I_3,I_2\), i.e., \(\mathbf{[ }x_1\,{;}\,x_1{+}1\mathbf{[ }, \ \mathbf{[ }x_2\,{;}\,-x_3\mathbf{[ }, \ \mathbf{[ }-x_3\,{;}\,x_1{-}x_3\mathbf{[ }\). The linking constraints are then \(d_3:= (x_1{+}1)\in I_3\), \(d_2:= ({-}x_3)\in I_2\), and \(d_1:= (x_1{-}x_3)\in I_1\), and the interpolant is \(d_3\wedge d_2\wedge d_1\Rightarrow \bot \).Footnote 4

figure e

When several bitwidths are involved, the intervals must “complement each other” at different bitwidths so that no value for y is feasible. For a bitwidth \(w_i\), the union of the \(w_i\)-intervals in model \({\mathcal M}\) may not necessarily cover the full domain (i.e., \(\bigcup _{I\in \mathcal S_i}[\![{I}]\!]_{{\mathcal M}}\) may be different from \(\mathbb {Z}/2^{w_{i}}\mathbb {Z}\)). The coverage can leave “holes”, and values in that hole are ruled out by constraints of other bitwidths. To produce the interpolant, we adapt the coverage-extraction algorithm into Algorithm 3, which takes as input the sequence of sets \((\mathcal S_1,\ldots ,\mathcal S_j)\) as described in Fig. 2, and produces the interpolant’s constraints \(d_1,\ldots , d_p\), collected in set \(\textsf {output}\). The algorithm proceeds in decreasing bitwidth order, starting with \(w_1\), and calling itself recursively on smaller bitwidths to cover the holes that the current layer leaves uncovered (termination of that recursion is thus trivial). For every hole that \(\bigcup _{I\in \mathcal S_1}[\![{I}]\!]_{{\mathcal M}}\) leaves uncovered, it must determine how intervals of smaller bitwidths can cover it.

Algorithm 3 relies on the following ingredients:

  • returns an interval among \(\mathcal S\) whose concrete version \([\![{I}]\!]_{{\mathcal M}}\) has maximal length;

  • \(I\textsf {.upper}\) denotes the upper bound of an interval I;

  • returns an interval \(I\in \mathcal S\) that furthestextends a according to \({\mathcal M}\) (technically, an interval I that \(\le ^\mathsf{u}\)-maximizes \([\![{I\textsf {.upper}-a}]\!]_{{\mathcal M}}\) among those intervals I such that \([\![{a}]\!]_{{\mathcal M}}\in [\![{I}]\!]_{{\mathcal M}}\)).

  • If no interval in \(\mathcal S\) covers a in \(\mathcal M\), outputs the lower bound l of an interval in \(\mathcal S\) that \(\le ^\mathsf{u}\)-minimizes \([\![{l-a}]\!]_{{\mathcal M}}\).

Algorithm 3 proceeds by successively moving a concrete bitvector value \(\textsf {baseline}\) around the circle \(\mathbb {Z}/2^{w_1}\mathbb {Z}\). The baseline is moved when a symbolic reason why it is a forbidden value is found, in a while loop that ends when the baseline has gone round the full circle. If there is at least one interval in \(\mathcal S_1\) that covers \(\textsf {baseline}\) in \({\mathcal M}\) (l. 6), the call to succeeds, and \(\textsf {output}\) is extended with condition \(c_I\) and \((\textsf {baseline} \in I)\) (l. 8). If not, a hole has been discovered, whose extent is given by (l. 11). If the hole is bigger than \(2^{w_2}\) (i.e., \(2^{w_2}\le ^\mathsf{u}[\![{\textsf {next}{-}\textsf {baseline}}]\!]_{{\mathcal M}}\)), then the intervals of layers \(w_2\) and smaller must rule out every possible value for \(y[w_2{\,\!:\!\,}]\), and the \(w_1\)-intervals were not needed (l. 17). If on the contrary the hole is smaller (i.e., \([\![{\textsf {next}{-}\textsf {baseline}}]\!]_{{\mathcal M}}<^\mathsf{u}2^{w_2}\)), then the \(w_1\)-interval \(\mathbf{[ }\textsf {baseline}\,{;}\,\textsf {next}\mathbf{[ }\) is projected as a \(w_2\)-interval \(I:= \mathbf{[ }{\textsf {baseline}[w_2{\,\!:\!\,}]}\,{;}\,{\textsf {next}[w_2{\,\!:\!\,}]}\mathbf{[ }\) that needs to be covered by the intervals of bitwidth \(w_2\) and smaller. This is performed by a recursive call on bitwidth \(w_2\) (l. 14); the fact that only hole I needs to be covered by the recursive call, rather than the full domain \(\mathbb {Z}/2^{w_{2}}\mathbb {Z}\), is implemented by adding to \(\mathcal S_2\) in the recursive call the complement \(\mathbf{[ }{\textsf {next}[w_2{\,\!:\!\,}]}\,{;}\,{\textsf {baseline}[w_2{\,\!:\!\,}]}\mathbf{[ }\) of I. The result of the recursive call is added to the \(\textsf {output}\) variable, as well as the fact that the hole must be small. The final interpolant is \((\bigwedge _{d\,\in \,\textsf {output}}d)\Rightarrow \bot \). An example of run on a variant of Example 6.2 is given in [15].

Fig. 3.
figure 3

Rewriting rules

5 Normalization

As implemented in Yices 2, MCSAT processes a conflict by first computing the conflict core with BDDs, and then normalizing the constraints using the rules of Fig. 3. In the figure, u, \(u_1\) and \(u_2\) stand for any bitvector terms, is the sign-extension of u with k bits, and \(\text {bvnot}(u)\) is the bitwise negation of u. The bottom left rule is applied with lower priority than the others (as upper-bits extraction distributes over \(\circ \) but not over \(+\)) and only if exactly one of \(\{u_1,u_2\}\) is evaluable (and not 0). In the implementation, \(u[{\left| u\right| }{\,\!:\!\,}0]\) is identified with u, \(\circ \) is associative, and \(+,{\times }\) are subject to ring normalization. This is helped by the internal (flattened) representation of concatenations and bitvector polynomials in Yices 2. Normalization allows the specialized interpolation procedure to apply at least to the following grammar:Footnote 5

where \(\lessdot \in \{\le ^\mathsf{u},<^\mathsf{u},\le ^\mathsf{s},<^\mathsf{s},{\,\simeq _{}\,}\}\). Rewriting can often help further, by eliminating occurrences of the conflict variable (thus making more subterms evaluable) and increasing the chances that two unevaluable terms \(t_1\) and \(t_2\) become syntactically equal in an atom \(e_1 {+} t_1 \lessdot e_2 {+} t_2\).Footnote 6 Finally, we cache evaluable terms to avoid recomputing conditions of the form \(y\notin \mathsf{var}^{}(e)\). These conditions are needed to determine whether the specialized procedures apply to a given conflict core.

Fig. 4.
figure 4

Evaluation of the MCSAT solver and the effect of different explainer combinations and propagation. Each curve shows the number of benchmarks that the solver variant can solve against the time.

6 Experiments

We implemented our approach in the MCSAT solver within Yices 2 [11]. To evaluate its effectiveness, and the impact of the different modules, we ran the MCSAT solver with different settings on the 41,547 QF_BV benchmarks available in the SMT-LIB library [1]. We used a three-minute timeout per instance. Each curve in Fig. 4 shows the number of solved instances for each solver variant; all: the procedures of Sects. 3 and 4, with the bitblasting baseline when these do not apply; bb: only the bitblasting baseline; bb+eq: procedure of Sect. 3 plus the baseline; bb+arith: procedure of Sect. 4 plus the baseline; all-prop is the same as all but with no propagation of bitvector assignments during search. For reference, we also included the version of the Yices 2 MCSAT solver that entered the 2019 SMT competitionFootnote 7, marked as smtcomp2019.

The solver combining all explainer modules solved 33,236 benchmarks before timeout, 14,174 of which are solved by pure simplification, and 19,062 of which actually rely on MCSAT explanations. 14,313 of those are solved without ever calling the default bitblasting baseline (only the dedicated explainers of Sects. 3 and 4 are used), while the other 4,749 instances are solved by a combination of the three explainers.

The results show that both equality and arithmetic explainers contribute to the effectiveness of the overall solver, individually and combined. A bit more than half of the problem instances involving MCSAT explanations are fully within the scope of the two dedicated explainers. Of course these explainers are still useful beyond that half, in combination with the bitblasting explainer. The results also show that the eager MCSAT value propagation mechanism introduced in [19] is important for effective solving in practice.

For comparison, we also ran two solvers CDCL \((\mathcal T)\) solvers based on bitblasting on the same benchmarks and with the same timeout. We picked Yices 2 [11] (version 2.6.1) and Boolector [27] (version 3.2.0) and we used the same backend SAT solver for both, namely CaDiCaL [6]. Yices 2 solved 40,962 instances and Boolector solved 40,763 instances. We found 794 instances in the SMTLib benchmarks where our MCSAT solver was faster than Boolector by more than 2 sec. The and instances are trivial for MCSAT (solved in less than 0.25 sec. each), while Boolector hit our 3-minute timeout on all instances and all but 3 ones. The instances are trivial for MCSAT (solved in less than 0.03 sec.) while Boolector ran out of memory in our experimentation (except for one instance). Instances with a significant runtime difference in favour of MCSAT are among and (MCSAT is systematically better), (MCSAT is almost systematically better), , , , and . MCSAT is almost systematically faster on and faster on more than half of .

Using an alternative MCSAT approach to bitvector solving, Zeljić et al. reported that their solver could solve 23704 benchmarks from a larger set of 49971 instances with a larger timeout of 1200 s [30].Footnote 8 We have not managed to reproduce the results of Zeljić’s solver on our Linux server for direct comparison.

To debug the implementation of our explainers, every conflict explanation that is produced when solving in debug mode is sent on-the-fly to (non-MCSAT) Yices 2, which checks the validity of the clause by bitblasting. In debug mode, every normalization we perform with the rules of Sect. 5 is also sent to Yices 2 to prove the equality between the original term and the normalized term. Performance benchmarking was only done after completing, without any red flag, a full run of MCSAT in debug mode on the 41,547 QF_BV benchmarks instances.

7 Discussion and Future Work

The paper presents ongoing work on building an MCSAT solver for the theory of bitvectors. We have presented two main ideas for the treatment of \(\mathcal B\mathcal V_{} \) in MCSAT, that go beyond the approach proposed by Zeljić et al. [30].

First, by relying on BDDs for representing feasible sets, our design keeps the main search mechanism of MCSAT generic and leaves fragment-specific mechanisms to conflict explanation. The explanation mechanism is selected based on the constraints involved in the conflict. BDDs are also used to minimize the conflicts, which increases the chances that a dedicated explanation mechanism can be applied. BDDs offer a propagation mechanism that differs from those in [30] in that the justification for a propagated assignment is computed lazily, only when it is needed in conflict analysis. Computing the conflict core at that point effectively recovers justification of the propagations.

Second, we propose explanation mechanisms for two fragments of the theory: the core fragment of \(\mathcal B\mathcal V_{} \) that includes equality, concatenation and extraction; and a fragment of linear arithmetic. Compared to previous work on coarsest-base slicing, such as [4], our work applies the slicing on the conflict constraints only, rather than the whole problem. This should in general make the slices coarser, which we expect to positively impact efficiency. Our work on explaining arithmetic constraints is novel, notwithstanding the mechanisms studied by Janota and Wintersteiger [17] that partly inspired our Table 1 but addressed a smaller fragment of arithmetic outside of the context of MCSAT.

We have implemented the overall approach in the Yices 2 SMT solver. Experiments show that the overall approach is effective on practical benchmarks, with all the proposed modules adding to the solver performance. MCSAT is not yet competitive with bitblasting, but we are making progress. The main challenge is devising efficient word-level explanation mechanisms that can handle all or a least a large fragment of \(\mathcal B\mathcal V_{}\). Finding high-level interpolants in \(\mathcal B\mathcal V_{}\) is still an open problem and our work on MCSAT shows progress for some fragments of the bitvector theory. For MCSAT to truly compete with bitblasting, we will need interpolation methods that cover larger classes of constraints.

A key step in that direction is to extend the bitvector arithmetic explainer so that it handles multiplications by constants, then multiplication by evaluable terms, and, finally, arbitrary multiplications. Deeper integration of fragment-specific explainers could potentially help explaining hybrid conflicts that involve constraints from different fragments. To complement the explainers that we are developing, we plan to further explore the connection between interpolant generation and the closely related domain of quantifier elimination, particularly those techniques by John and Chakraborty [18] for the bitvector theory. The techniques by Niemetz et al. [26] for solving quantified bitvector problems using invertibility conditions could also be useful for interpolant generation in MCSAT.

Future work also includes relating our approach to the report by Chihani, Bobot, and Bardin [7], which aims at lifting the CDCL mechanisms to the word level of bitvector reasoning, and therefore seems very close to MCSAT. Finally, we plan to explore integrating our MCSAT treatment of bitvectors with other components of SMT-solvers, whether in the context of MCSAT or in different architectures. An approach for this is the recent framework of Conflict-Driven Satisfiability (CDSAT) [2, 3], which precisely aims at organizing collaboration between generic theory modules.