Interpolating bit-vector formulas using uninterpreted predicates and Presburger arithmetic

The inference of program invariants over machine arithmetic, commonly called bit-vector arithmetic, is an important problem in verification. Techniques that have been successful for unbounded arithmetic, in particular Craig interpolation, have turned out to be difficult to generalise to machine arithmetic: existing bit-vector interpolation approaches are based either on eager translation from bit-vectors to unbounded arithmetic, resulting in complicated constraints that are hard to solve and interpolate, or on bit-blasting to propositional logic, in the process losing all arithmetic structure. We present a new approach to bit-vector interpolation, as well as bit-vector quantifier elimination (QE), that works by lazy translation of bit-vector constraints to unbounded arithmetic. Laziness enables us to fully utilise the information available during proof search (implied by decisions and propagation) in the encoding, and this way produce constraints that can be handled relatively easily by existing interpolation and QE procedures for Presburger arithmetic. The lazy encoding is complemented with a set of native proof rules for bit-vector equations and non-linear (polynomial) constraints, this way minimising the number of cases a solver has to consider. We also incorporate a method for handling concatenations and extractions of bit-vector efficiently.

A theory that has turned out notoriously difficult to handle in Craig interpolation is bounded machine arithmetic, commonly called bit-vector arithmetic. Decision procedures for bit-vectors are predominantly based on bit-blasting, in combination with sophisticated preprocessing and simplification methods, which implies that also extracted interpolants stay on the level of propositional logic and are difficult to map back to compact high-level bitvector constraints. An alternative interpolation approach translates bit-vector constraints to unbounded integer arithmetic formulas [16], but is limited to linear constraints and tends to produce integer formulas that are hard to solve and interpolate, due to the necessary introduction of additional variables and large coefficients to model wrap-around semantics correctly.
In this article, we introduce a new Craig interpolation method for bit-vector arithmetic, initially focusing on arithmetic bit-vector operations including addition, multiplication, and division. Like [16], we compute interpolants by reducing bit-vectors to unbounded integers; unlike in earlier approaches, we define a calculus that carries out this reduction lazily, and can therefore dynamically choose between multiple possible encodings of the bit-vector operations. This is done by initially representing bit-vector operations as uninterpreted predicates, which are expanded and replaced by Presburger arithmetic expressions on demand. The calculus also includes native rules for non-linear constraints and bit-vector equations, so that formulas can often be proven without having to resort to a full encoding as integer constraints. Our approach gives rise to both Craig interpolation and quantifier elimination (QE) methods for bit-vector constraints, with both procedures displaying competitive performance in our experiments.
Reduction of bit-vectors to unbounded integers has the additional advantage that integer and bit-vector formulas can be combined efficiently, including the use of conversion functions between both theories, which are difficult to support using bit-blasting. This combination is of practical importance in software verification, since programs and specifications often mix machine arithmetic with arbitrary-precision numbers; tools might also want to switch between integer semantics (if it is known that no overflows can happen) and bit-vector semantics for each individual program instruction. This is an extended version of a paper presented at FMCAD 2018 [17]. Compared to the conference version, this article considers an extended fragment of bit-vector logic, including also concatenation and extraction operations on bit-vectors, as well as bit-wise operators like bvor or bvnot. We show that the representation of concatenation and extraction using uninterpreted predicates is sufficient to obtain an interpolation procedure for the quantifier-free structural fragment of bit-vector logic, i.e., bit-vector constraints with only concatenation, extraction, and positive equations [18,19]. Bit-wise operations are handled via a direct translation to Presburger arithmetic akin to bit-blasting.
The contributions of the article are: a new calculus for non-linear integer arithmetic, which can eliminate quantifiers (in certain cases) and extract Craig interpolants (Sect. 3); a corresponding calculus for arithmetic bit-vector constraints (Sect. 4); the extension of the calculus to handle concatenation, extraction, and bit-wise operations (Sect. 5); an experimental evaluation using SMT-LIB and model checking benchmarks (Sect. 6).

Example 1: Interpolating arithmetic bit-vector operations
We start by considering one of the examples from [16], the interpolation problem A ∧ B defined by A = ¬bvule 8 (bvadd 8 (y 4 , 1), y 3 ) ∧ y 2 = bvadd 8 (y 4 , 1) B = bvule 8 (bvadd 8 (y 2 , 1), y 3 ) ∧ y 7 = 3 ∧ y 7 = bvadd 8 (y 2 , 1) where all variables range over unsigned 8-bit bit-vectors. The function bvadd 8 represents addition of two bit-vectors, while the predicate bvule 8 is the unsigned ≤ comparison. An interpolant for A ∧ B is a formula I such that the implications A ⇒ I and B ⇒ ¬I hold, and such that only variables common to A and B occur in I .
An eager encoding into Presburger arithmetic (linear integer arithmetic, LIA) would typically add variables to handle wrap-around semantics, e.g., mapping y 4 = bvadd 8 (y 4 , 1) to y 4 = y 4 + 1 − 2 8 σ 1 ∧ 0 ≤ y 4 < 2 8 ∧ 0 ≤ σ 1 ≤ 1. This yields a formula in Presburger arithmetic that exactly models the bit-vector semantics, and can be solved and interpolated using existing methods implemented in SMT solvers. Interpolants can be mapped back to a pure bit-vector formula if needed. However, additional variables and large coefficients tend to be hard both for solving and interpolation; the LIA interpolant presented in [16] for A ∧ B is the somewhat complicated formula I LIA = −255 ≤ y 2 − y 3 + 256 −1 y 2 256 . Our approach translates bit-vector formulas to our core language -an extension of Presburger arithmetic with constructs to express bit-vector domains, wrap-around semantics and operations that can be simplified in different ways, such as bvmul. For example, domain predicate in w (x) expresses that variable x belongs to the value range of a bit-vector of width w. Similarly, predicate ubmod w (x, y) expresses the unsigned wrap-around semantics without explicitly encoding it. Translating A and B to the core language yields: The core language enables a layered calculus that encodes predicates on a case by case basis, preferring simpler encodings whenever possible. In our example, rule bmod-split splits the ubmod 8 (y 2 + 1, c 2 ) into the only two relevant cases based on the bounds of y 2 implied by A core , B core : . . . , 0 ≤ c 2 < 256, y 2 + 1 = c 2 . . . , 0 ≤ c 2 < 256, y 2 + 1 = c 2 + 256 . . . , ubmod 8 (y 2 + 1, c 2 ) bmod-split Due to y 7 = 3 ∧ y 7 = c 2 , the cases reduce to y 2 = 2 and y 2 = 258, and immediately contradict A core , B core . When variable bounds are tight enough and there are only a few cases, case splits are more efficient than σ variables. However, that is not always the case and our calculus lazily decides how to handle each occurrence. Simpler proofs also lead to simpler and more compact interpolants; using our lazy approach, the final interpolant in the example is I LAZY = y 3 < y 2 , which is simple and avoids the division operator in I LIA . We will revisit this example in Sect. 4.4 and explain in greater detail how this interpolant is obtained.

Example 2: Interpolating structural bit-vector operations
We continue with a (reduced) example taken from [19], a formula of equalities between (slices of) bit-vectors of length 8: is the extraction of the slice of bits from uth down to lth (inclusive). In the previous example the bit-vector formula was translated to integer arithmetic, however this can sometimes be inefficient when dealing with structural bit-vector operations, e.g., extractions and concatenations. A direct translation to integer arithmetic has a hard time to isolate the conflict, since integer operations cannot capture extractions in a natural way. Instead, it is possible to split the bit-vectors into segments Given this decomposition of the bit-vectors, it is easy see the conflict x[5 : 2] = 5 = 6 = y[5 : 2] without a translation to integers. Interpolants can in this setting be extracted by referring to individual slices of bit-vectors, with the help of the extraction operator. In Sect. 5 we show how bit-vectors can be decomposed in this manner using an interpolating calculus.

Related work
Most SMT solvers handle bit-vectors using bit-blasting and SAT solving, and usually cannot extract interpolants for bit-vector problems. The exception is MathSAT [20], which uses a layered approach [16] to compute interpolants: MathSAT first tries to compute interpolants by keeping bit-vector operations uninterpreted; then using a restricted form of quantifier elimination; then by eager encoding into linear integer arithmetic (LIA); and finally through bit-blasting. Our approach has some similarities to the LIA encoding, but can choose simpler encodings thanks to laziness, and also covers non-linear arithmetic constraints.
A similarly layered approach, proposed in [21], can be used to compute function summaries in bounded model checking. When bounded model checking is able to prove (bounded) safety of a program, Craig interpolation can subsequently be used to extract function summaries; such summaries can later be useful to speed up other verification tasks. To handle bit-vector constraints in this context, [21] successively applies more and more precise overapproximations of bit-vectors: using uninterpreted functions, linear real arithmetic, and finally using precise bit-blasting. Interpolants are computed in the coarsest theory that was able to prove safety of a verification task.
Other related work has focused on interpolation for fragments of bit-vector logic. In [22], an algorithm is given for reconstructing bit-vector interpolants from bit-level interpolants, however restricted to the case of bit-vector equalities. An interpolation procedure based on a set of tailor-made (but incomplete) rewriting rules for bit-vectors is given in [23].
Looking more generally at model checking for finite-state systems formulated over the theory of bit-vectors (often called word-level model checking), lazy approaches to handle complex bit-vector operations have been proposed. In [24], an approximation method for model checking RTL designs is defined that instantiates complex bit-vector operations lazily. Initially, such operations are over-approximated by leaving the results unconstrained; when spurious counterexamples occur, the approximation is refined by adding additional constraints, or ultimately by precisely instantiating the operator. Such approaches are independent of the underlying finite-state model checking algorithm, and do not necessarily involve Craig interpolation, however.
The symbol t denotes terms of linear arithmetic. Substitution of a term t for a variable x in φ is denoted by [x/t]φ; we assume that variable capture is avoided by renaming bound variables as necessary. For simplicity, we sometimes write s = t as a shorthand of s − t = 0, inequalities s ≤ t and t ≥ s for s − t ≤ 0, and ∀c.φ as a shorthand of ∀x.[c/x]φ if c is a constant. The abbreviation true (false) stands for equality 0 = 0 (1 = 0), and the formula φ → ψ abbreviates ¬φ ∨ ψ. Semantic notions such as structures, models, satisfiability, and validity are defined as is common (e.g., [26]), but we assume that evaluation always happens over the universe Z of integers; bit-vectors will later be defined as a subset of the integers.

A sequent calculus for the base logic
For checking whether a formula in the base logic is satisfiable or valid, we work with the calculus presented in [25], a part of which is shown in Fig. 1. If Γ , Δ are finite sets of formulas, then Γ Δ is a sequent. A sequent is valid if the formula Γ → Δ is valid. Positions in Δ that are underneath an even/odd number of negations are called positive/negative; and vice versa for Γ . Proofs are trees growing upward, in which each node is labeled with a sequent, and each non-leaf node is related to the node(s) directly above it through an application of a calculus rule. A proof is closed if it is finite and all leaves are justified by an instance of a rule without premises. Soundness of the calculus implies that the root of a closed proof is a valid sequent.
In addition to propositional and quantifier rules in Fig. 1, the calculus in [25] also includes rules for equations and inequalities in Presburger arithmetic; the details of those rules are not relevant for this paper. The calculus is complete for quantifier-free formulas in the base logic, i.e., for every valid quantifier-free sequent a closed proof can be found. It is well-known that the base logic including quantifiers does not admit complete calculi [27], but as discussed in [25] the calculus can be made complete (by adding slightly more sophisticated quantifier For quantifier-free input formulas, proof search can be implemented in depth-first style following the core concepts of DPLL(T) [28]: rules with multiple premises correspond to decisions and explore the branches one by one; rules with a single premise represent propagation or rewriting; and logging of rule applications is used in order to implement conflict-driven learning and proof extraction. For experiments, we use the implementation of the calculus in Princess. 2

Quantifier elimination in the base logic
The sequent calculus can eliminate quantifiers in Presburger arithmetic, i.e., in the base logic without uninterpreted predicates, since the arithmetic calculus rules are designed to systematically eliminate constants. To illustrate this use case, suppose φ is a formula without uninterpreted predicates (P = ∅) and without constants c, but possibly containing variables x. Formula φ furthermore only contains ∀/∃ under an even/odd number of negations, i.e., all quantifiers are effectively universal. To compute a quantifier-free formula ψ that is equivalent to φ, we can construct a proof with root sequent φ, and keep applying rules until no further applications are possible in any of the remaining open goals {Γ i Δ i | i = 1, . . . , n}. In this process, rules ∃left and ∀right can introduce fresh constants, which are subsequently isolated and eliminated by the arithmetic rules. To find ψ, it is essentially enough to extract the constant-free formulas . The full calculus [25] is moreover able to eliminate arbitrarily nested quantifiers, and can be used similarly to prove validity of sequents with quantifiers. A recent independent evaluation [29] showed that the resulting proof procedure is competitive with state-of-the-art SMT solvers and theorem provers on a wide range of quantified integer problems.
The upper box presents a selection of interpolating rules for propositional logic, while the lower box shows rules for quantifiers. Parameter D stands for either L or R. The quantifier ∀ Rt denotes universal quantification over all constants occurring in t but not in Γ L ∪ Δ L ; likewise, ∃ Lt denotes existential quantification over all constants occurring in t but not in Γ R ∪ Δ R . In ∃left D , c is a constant that does not occur in the conclusion

Craig interpolation in the base logic
Given formulas A and B such that A ∧ B is unsatisfiable, Craig interpolation can determine a formula I such that the implications A ⇒ I and B ⇒ ¬I hold, and non-logical symbols in I occur in both A and B [30]. An interpolating version of our sequent calculus has been presented in [4,11], and is summarised in Fig. 2. To keep track of the partitions A, B, the calculus operates on labeled formulas φ L (with L for "left") to indicate that φ is derived from A, and similarly formulas φ R for φ derived from B. If Γ , Δ are finite sets of L/Rlabeled formulas, and I is an unlabeled formula, then Γ Δ I is an interpolating sequent.
Semantics of interpolating sequents is defined using the following projections: Δ R is valid, and 3. constants and predicates in I occur in both Γ L ∪ Δ L and Γ R ∪ Δ R . As a special case, note that the sequent A L , B R ∅ I is valid iff I is an interpolant of A ∧ B. Soundness of the calculus guarantees that the root of a closed interpolating proof is a valid interpolating sequent.
To solve an interpolation problem A ∧ B, a prover typically first constructs a proof of A, B ∅ using the ordinary calculus from Sect. 2.1. Once a closed proof has been found, it can be lifted to an interpolating proof: this is done by replacing the root formulas A, B with A L , B R , respectively, and recursively assigning labels to all other formulas as defined by the rules from Fig. 2. Then, starting from the leaves, intermediate interpolants are computed and propagated back to the root, leading to an interpolating sequent A L , B R ∅ I .

Solving non-linear constraints
We extend the base logic in three steps: in this section, symbols and rules are added to solve non-linear diophantine problems; a second extension is then done in Sect. 4 to handle arithmetic bit-vector constraints; and, finally, additional symbols to express structural bitvector constraints are introduced in Sect. 5. All constructions preserve the ability of the calculus to eliminate quantifiers (under certain assumptions) and derive Craig interpolants. For non-linear constraints, we assume that the set P of predicates contains a distinguished ternary predicate ×, with the intended semantics that the third argument represents the result of multiplying the first two arguments, i.e., ×(s, t, r ) ⇔ s · t = r . The predicate × is clearly sufficient to express arbitrary polynomial constraints by introducing a ×-literal for each product in a formula, at the cost of introducing a linear number of additional constants or existentially quantified variables. We make the simplifying assumption that × only occurs in negative positions; that means, top-level occurrences will be on the left-hand side of sequents. Positive occurrences can be eliminated thanks to the equivalence ¬ × (s, t, r ) ⇔ ∃x.(×(s, t, x) ∧ x = r ).

Calculus rules for non-linear constraints
We now introduce classes of calculus rules to reason about the ×-predicate. The rules are necessarily incomplete for proving that a sequent is valid, but they are complete for finding counterexamples: if φ is a satisfiable quantifier-free formula with × as the only predicate symbol, then it is possible to construct a proof for φ ∅ that has an open and unprovable goal in pure Presburger arithmetic (by systematically splitting variable domains, Sect. 3.1.4). The rule classes are: -Deriving Implied Equalities with Gröbner Bases: if implied linear equalities can be found using Buchberger's algorithm these can be added to the proof goal. -Interval Constraint Propagation: if new bounds for constants can be derived from existing bounds these can be added to the proof goal. -Cross-Multiplication of Inequalities:, if two terms are known to be non-negative, then the non-negativity of their product can be added to the proof goal. -Interval Splitting: as a last resort, the proof branch can be split by dividing the possible values for a constant or variable in half. -×-Elimination: if a occurrence of × is implied by other literals, it can be eliminated from the proof goal.

Deriving implied equalities with Gröbner bases
The first rule applies standard algebra methods to infer new equalities from multiplication literals. To avoid the computation of more and more complex terms in this process, we restrict the calculus to the inference of linear equations that can be derived through computation of a Gröbner basis. 3 Given a set {×(s i , t i , r i )} n i=1 of ×-literals and a set {e j = 0} m j=1 of linear equations, the generated ideal ) over rational numbers is the smallest set of rational polynomials that contains is closed under addition, and closed under multiplication with arbitrary rational polynomials [31]. Any f ∈ I corresponds to an equation f = 0 that logically follows from the literals, and can therefore be added to a proof goal: if f is linear, has integer coefficients, and f ∈ I To see how this rule can be applied practically, note that the subset of linear polynomials in I forms a rational vector space, and therefore has a finite basis. It is enough to apply ×eq for terms f 1 , . . . , f k corresponding to any such basis, since linear arithmetic reasoning (in the base logic) will then be able to derive all other linear polynomials in I . To compute a basis to a Gröbner basis using Buchberger's algorithm [32], and then apply Gaussian elimination to find linear basis polynomials (or directly by choosing a suitable monomial order).

Example 1
Consider the formula for the square of a sum: (x + y) 2 = x 2 + 2x y + y 2 . We can show its validity by rewriting it to normal form and constructing a proof.
Here, the ×eq-step is motivated by the fact that the Gröbner basis derived from Π contains the linear polynomial c 1 + 2c 2 + c 3 − c 4 , from which the desired equation can be derived using linear reasoning (using calculus rules not presented in this paper, see Sect. 2.1).

Interval constraint propagation (ICP)
Our main technique for inequality reasoning in the presence of ×-predicates is interval constraint propagation (ICP) [33]. ICP is a fixed-point computation on the lattice I S of functions mapping constants and variables S = C ∪ X to intervals I, and can efficiently approximate the value ranges of symbols. We define the lattice I of intervals and the lattice I S of interval assignments as follows; S → I represents the set of (total) functions from S = C ∪ X to I, and ⊥ is the distinguished bottom element of I S : We denote the (point-wise) join and meet on I S with , , respectively.
To define the fixed-point computation, we then introduce abstraction and concretisation functions that connect the lattice I S with the powerset lattice P(S → Z) of value assignments. The abstraction of a set V ∈ P(S → Z) of value assignments is the least element α(V ) of I S such that the interval α(V )(c) assigned to a symbol c ∈ S contains all values of c in V (or α(V ) = ⊥ if V is empty). The abstraction function α : P(S → Z) → I S is formally defined as follows: The concretisation γ (I ) of some interval assignment I ∈ I S is the set V of all value assignments that stay within the intervals specified by I . More formally, γ : The result of ICP can then be defined as the greatest fixed-point of a monotonic propagation function Prop : I S → I S on the lattice I S . Propagation can be defined separately for each formula occurring in a sequent; in particular, propagation Prop φ : I S → I S for a multiplication literal φ = ×(s, t, r ) is defined as: This means, propagation eliminates values from the intervals that are inconsistent with ×(s, t, r ). Propagation for equalities t = 0 and inequalities t ≤ 0 is defined similarly; in practice, also any monotonic over-approximation of Prop φ can be used instead of Prop φ , at the cost of more over-approximate results in the end.
Given a set {φ 1 , . . . , φ n } of formulas, the overall propagation function Prop = Prop {φ 1 ,...,φ n } is the meet of the individual propagators: The ICP rule assumes that a greatest fixed-point gfp Prop {φ 1 ,...,φ n } for equality, inequality, and multiplication literals φ 1 , . . . , φ n in a sequent has been computed, and adds resulting bounds for a constant c: Example 2 From two inequalities x ≥ 5 and y ≥ 5, the rule ×icp can derive (x +y) 2 ≥ 100: The slightly different problem x + y ≥ 10 → (x + y) 2 ≥ 100 cannot be proven in the same way, since ICP will not be able to deduce bounds for x or y from x + y ≥ 10.

Cross-multiplication of inequalities
While ICP is highly effective for approximating the range of constants, and quickly detecting inconsistencies, it is less useful for inferring relationships between multiple constants that follow from multiplication literals. We cover such inferences using a cross-multiplication rule that resembles procedures used in ACL2 [34]. The rule captures the fact that if s, t are both non-negative, then also the product s · t is non-negative. Like in Sect. 3.1.1, we prefer to avoid the introduction of new multiplication literals during proof search. By disallowing non-linear terms, we avoid the introduction of more and more complex terms and thus only add s · t ≥ 0 if the term s · t can be expressed linearly. For this, ) for the ideal induced by equations and ×-literals: The term f can practically be found by computing a Gröbner basis of I , and reducing the product s · t to check whether an equivalent linear term exists.

Interval splitting
If everything else fails, as last resort it can become necessary to systematically split over the possible values of a variable or constant c ∈ C ∪ X : The α ∈ Z can in principle be chosen arbitrarily in the rule, but in practice a useful strategy is to make use of the range information derived for ×icp: when no ranges can be tightened any further using ×icp, instead ×split can be applied to split one of the intervals in half.

×-Elimination
Finally, occurrences of × can be eliminated whenever a formula is subsumed by other literals in a goal, again writing Note that ×elim only eliminates non-linear ×-literals, whereas ×eq only introduces linear equations, so that the application of the two rules cannot induce cycles.

Quantifier elimination for non-linear constraints
Due to necessary incompleteness of calculi for Peano arithmetic, quantifiers can in general not be eliminated in the presence of the × predicate, even when considering formulas that do not contain uninterpreted predicates. By combining the QE approach in Sect. 2.2 with the rules for × that we have introduced, it is nevertheless possible to reason about quantified non-linear constraints in many practical cases, and sometimes even get rid of quantifiers. This is possible because the rules in Sect. 3.1 are not only sound, but even equivalence transformations: in any application of the rules, the conjunction of the premises is equivalent to the conclusion. Similarly as in [35], QE is always possible if sufficiently many constants or variables in a formula φ range over bounded domains: if there is a set B ⊆ C ∪ X of symbols with bounded domain such that in each literal ×(s, t, r ) either s or t contain only symbols from B. In this case, proof construction will terminate when applying the rule ×split only to variables or constants with bounded domain. This guarantees that eventually every literal ×(s, t, r ) can be turned into a linear equation using ×eq, and then be eliminated using ×elim, only leaving proof goals with pure Presburger arithmetic constraints. The boundedness condition is naturally satisfied for bit-vector formulas.

Craig interpolation for non-linear constraints
To carry over the Craig interpolation approach from Sect. 2.3 to non-linear formulas, interpolating versions of the calculus rules for the ×-predicate are needed. For this, we follow the approach used in [4] (which in turn resembles the use of theory lemmas in SMT in general): when translating a proof to an interpolating proof, we replace applications of the ×-rules with instantiation of an equivalent theory axiom QAx. Suppose a non-interpolating proof contains a rule application . . . .
in which Γ , Δ are the formulas assumed by the rule application, Γ , Δ are side formulas not required or affected by the application, and Γ 1 , Δ 1 , …, Γ n , Δ n are newly introduced formulas in the individual branches. The (unquantified) theory axiom Ax corresponding to the rule application expresses that the conjunction of the premises has to imply the conclusion; the quantified theory axiom QAx = def ∀S. Ax in addition contains universal quantifiers for all constants S ⊆ C occurring in Ax.
Ax and QAx are specific to the application of R: the axioms for two distinct applications of R will in general be different formulas. QAx is defined in such a way that it can simulate the effect of R (as in (1)). This is done by introducing QAx in the antecedent of a sequent, applying the rule ∀left to instantiate the axiom with the constants S and obtain Ax, and then applying propositional rules. The propositional rules ∨left and ¬left are used to eliminate implications → (which are short-hand for ¬, ∨), and the rule ∧right to eliminate the conjunction n i=1 : This construction leads to a proof using only the standard rules from Sect. 2.1, which can be interpolated as discussed earlier. Since QAx is a valid formula not containing any constants, it can be introduced in a proof at any point, and labelled QAx L or QAx R on demand.
The obvious downside of this approach is the possibility of quantifiers occurring in interpolants. The interpolating rules ∀left L/R (Fig. 2) have to introduce quantifiers ∀ Rt /∃ Lt for local symbols occurring in the substituted term t; whether such quantifiers actually occur in the final interpolant depends on the applied ×-rules, and on the order of rule application. For instance, with ×split it is always possible to choose the label of QAx so that no quantifiers are needed, whereas ×eq might mix symbols from left and right partitions in such a way that quantifiers become unavoidable. In our implementation we approach this issue pragmatically. We leave proof search unrestricted, and might thus sometimes get proofs that do not give rise to quantifier-free interpolants; when that happens, we afterwards apply QE to get rid of the quantifiers. QE is always possible for bit-vector constraints, see Sect. 4.4. 4

Solving bit-vector constraints
We now define the extension of the base logic to bit-vector constraints. The main idea of the extension is to represent bit-vectors of width w as integers in the interval {0, . . . , 2 w −1}, and to translate bit-vector operations to the corresponding operation in Presburger arithmetic (or possible the ×-predicate for non-linear formulas), followed by an integer remainder operation to map the result back to the correct bit-vector domain. Since the remainder operation tends to be a bottleneck for interpolation, we keep the operation symbolic and initially consider it as an uninterpreted predicate bmod b a . The predicate is only gradually reduced to Presburger arithmetic by applying the calculus rules introduced later in this section.
Formally, we introduce binary predicates We also introduce short-hand notations for the casts to the unsigned and signed bit-vector domains:

Translating bit-vector constraints to the core language
For the rest of the section, we use the base logic augmented with × and bmod b a -predicates as the core language to which bit-vector constraints are translated. For presentation, the translation focuses on a subset of the arithmetic bit-vector operations, BVOP a = {bvadd w , bvmul w , bvudiv w , bvneg w , ze w+w , bvule w , bvsle w }. An extension to bit-vector concatenation, extraction, and bit-wise functions is presented in Sect. 5. All operations are sub-scripted with the bit-width of the operands; the zero-extend function ze w+w maps bit-vectors of width w to width w + w . Semantics follows the FixedSizeBitVectors 5 theory of the SMT-LIB [36]. Other arithmetic operations, for instance bvsdiv w or bvsmod w , can be handled in the same way as shown here, though sometimes the number of cases to be considered is larger.
The translation from bit-vector constraints φ to core formulas φ core has two parts: first, BVOP a occurrences in a formula φ have to be replaced with equivalent expressions in the Rules translating bit-vector operations into the core language. The rules only apply in negative positions core language; second, since the core language only knows the sort of unbounded integers, type information has to be made explicit by adding domain constraints.
BVOP a Elimination. Like in Sect. 3, we assume that the bit-vector formula φ has already been brought into a flat form by introducing additional constants or quantified variables: the operations in BVOP a must not occur nested, and functions only occur in equations of the form f (s) = t in negative positions. The translation from φ to φ is then defined by the rewriting rules in Fig. 3. Since the rules for the predicates bvsle w and bvule w distinguish between positive and negative occurrences, we assume that rules are only applied to formulas in negation normal-form, and only in negative positions. The rules for bvadd w , bvneg w , ze w+w , and bvule w simply translate to the corresponding Presburger term, if necessary followed by remainder ubmod w . Multiplication bvmul w is mapped similarly to the ×-predicate defined in Sect. 3, adding an existential quantifier to store the intermediate product. Since rules are only applied in negative positions, the quantified variable can later be replaced with a Skolem constant. An optimised rule could be defined for the case that one of the factors is constant, avoiding the use of the ×-predicate. Translation of bvsle w maps the operands to a signed bit-vector domain {−2 w−1 , . . . , 2 w−1 − 1}, in which then the arithmetic inequality predicates ≤, > can be used. The rule for unsigned division bvudiv w distinguishes the cases that the divisor t is zero or positive (as required by SMT-LIB), and maps the latter case to standard integer division.
Domain constraints. Bit-vector variables/constants x of width w occurring in φ are interpreted as unbounded integer variables in φ core , which therefore has to contain explicit assumptions about the ranges of bit-vector variables. We use the abbreviation in where S ⊆ C ∪ X is the set of free variables and constants occurring in φ, w x is the bit-width of x ∈ S, and φ is the result of applying rules from Fig. 3 to φ. Similar constraints are used to express quantification over bit-vectors, for instance ∃x.

Example 3
Consider challenge/multiplyOverflow.smt2, a problem from SMT-LIB QF_BV containing a bit-vector formula that is known to be hard for most SMT solvers The final formula φ core is obtained by application of the rules in Fig. 3, and adding domain constraints:

Preprocessing and simplification
An encoded formula φ core tends to contain a lot of redundancy, in particular nested or unnecessary occurrences of the bmod b a predicates. As an important component of our calculus, and in line with the approach in other bit-vector solvers, we therefore apply simplification rules both during preprocessing and during the solving phase ("inprocessing"). The most important simplification rules are shown in Fig. 4. Our implementation in addition applies rules for Boolean and Presburger connectives, for instance to inline equations x = t or to propagate inequalities, not shown here.
The notation Π : φ φ expresses that formula φ can be rewritten to φ , given the set Π of formulas as context. The structural rules in the upper half of Fig. 4 define how formulas are traversed, and how the context Π is extended to Π, Lit when encountering further literals. We apply the structural rules modulo associativity and commutativity of ∧, ∨, and prioritise lit-∨-rw and lit-∧-rw over the other rules. Simplification is iterated until a fixed-point is reached and no further rewriting is possible. The connection between rewriting rules and the sequent calculus is established by the following rules: The lower half of Fig. 4 shows three of the bit-vector-specific rules. The bound-rw rule defines elimination of bmod b a -predicates that do not require any case splits; the definition of the rule assumes functions lbound(Π, s) and ubound(Π, s) that derive lower and upper bounds of a term s, respectively, given the current context Π. The two functions can be implemented by collecting inequalities (and possibly type information available for predicates) in Π to obtain an over-approximation of the range of s.
Rule coeff-rw reduces coefficients in bmod b a (s, r ) by adding a multiple of the modulus b − a to s. The rule assumes a well-founded order ≺ on terms to prevent cycles during simplification. One way to define such an order is to choose a total well-founded order ≺ on the union C ∪ X of variables and constants, extend ≺ to expressions α · x by sorting coefficients as 0 ≺ 1 ≺ −1 ≺ 2 ≺ · · · , and finally extend ≺ to arbitrary terms α 1 t 1 + · · · + α n t n as a multiset order [25].
The same order ≺ is used in bmod-rw, defining how bmod b a (s, r ) can be rewritten in the context of a second literal bmod b a (s , r ). The rule is useful to optimise the translation of nested bit-vector operations. Assuming bmod b a (s , r ), the value of s − r is known to be a multiple of b − a , and therefore k · (s − r ) is a multiple of b − a provided that b − a divides k · (b − a ). This implies that the truth value of bmod b a (s, r ) is not affected by adding k · (s − r ) to s.
Our implementation uses various further simplification rules, for instance to eliminate × or bmod b a whose result is never used; we skip those for lack of space.

Splitting rules for bmod b a
In general, formulas will of course also contain occurrences of bmod b a that cannot be eliminated just by simplification. We introduce two calculus rules for reasoning about such general literals bmod b a (s, r ). The first rule makes the assumption that lower and upper bounds of s are available, and are reasonably tight, so that an explicit case analysis can be carried out; the rule generalises bound-rw to the situation in which the factors l, u do not coincide: If the bounds l, u are too far apart, the number of cases created by bmod-split would become unmanageable, and it is better to choose a direct encoding of the remainder operation in Presburger arithmetic: where c is assumed to be a fresh constant. Rule bmod-const corresponds to the encoding chosen in [16]. In practice, it turns out to be advantageous to prioritise rule bmod-split over bmodconst, as long as the number of cases does not become too big. This is because each of the premises of bmod-split tends to be significantly simpler to solve (and interpolate) than the conclusion; in addition, splitting one bmod b a literal often allows subsequent simplifications that eliminate other bmod b a occurrences. We investigate experimentally in Sect. 6.1 how many applications of the rules bmod-split and bmod-const are needed to prove formulas satisfiable or unsatisfiable, and show that the numbers are surprisingly low, in particular in the unsatisfiable case.

Quantifier elimination and Craig interpolation
Since the bit-vector rules in this section are all equivalence transformations, QE for bit-vectors can be done exactly as described in Sect. 3.2. As the ranges of all symbols are now bounded, it is guaranteed that any formula will eventually be reduced to Presburger arithmetic, so that we obtain complete QE for (arithmetic) bit-vector constraints.
Similarly, the interpolation approach from Sect. 3.3 carries over to bit-vectors, with theory axioms being generated for each of the rules defined in this section. Since the translation of bit-vector formulas to the core language happens upfront, also interpolants are guaranteed to be in the core language, and can be mapped back to bit-vector formulas if necessary (e.g., as in [16]). Interpolants might contain quantifiers, in which case QE can be applied (as described in the first paragraph), so that we altogether obtain a complete procedure for quantifier-free interpolation of arithmetic bit-vector formulas.
In our implementation, we restrict the use of the simplification rules rw-left and rwright when computing proofs for the purpose of interpolation. Unrestricted use could quickly mix up the vocabularies of the individual partitions in an interpolation problem A ∧ B, and thus increase the likelihood of quantifiers in interpolants. Instead we simplify A, B separately upfront using rules in Fig. 4, and apply rw-left, rw-right only when the modified formula φ is a literal.

Example 6
We recall the example from Sect. 1.1, and show how our calculus finds the simpler interpolant I LIA = y 3 < y 2 for the interpolation problem A ∧ B. The core step is to turn the application of bmod-split into an explicit axiom; after slight simplifications, this axiom is: The axiom mentions all assumptions made by the rule, including the bounds 3 ≤ y 2 < 256 that determine the number of resulting cases (or, alternatively, the formulas c 1 > y 3 , y 2 = c 1 , c 2 ≤ y 3 , y 7 = 3, y 7 = c 2 from which the bounds derive). The axiom also includes domain constraints like in 8 (c 2 ) for occurring symbols, which later ensures that possible quantifiers in interpolants range over bounded domains. The quantified axiom is QAx = ∀y 2 , c 2 . Ax, and can be used to construct an interpolating proof: · · · * . . . .
We only show one of the cases, P, resulting from splitting the axiom Ax R using the rules from Fig. 2. The final interpolant I LAZY = y 3 < y 2 records the information needed from A core to derive a contradiction in the presence of y 2 + 1 = c 2 ; the branch is closed using standard arithmetic reasoning [11].

Interpolation in the presence of extract and concat
Two bit-vector operations which are more tricky to translate to integer arithmetic are the extraction of bits from a larger bit-vector, and the concatenation of two bit-vectors. This is formalised using the function bvextract [u,l] , which cuts out a slice of u − l + 1 consecutive bits, and the function bvconcat v+w forming a bit-vector of length v +w. We call the fragment of bit-vector logic containing only these operations, and positive equalities, the structural fragment of bit-vector theory.  The upper table  shows the situation with  bit-vectors of size 8, the lower  one with size 16   7  6  5  4  3  2 1 0 x [8] * * 1 0 1 1 * * y [8] 0 0 0 1 1 0 * * 15 14 13 12 11 10 9 ... x [16] * * 1 0 1 1 * . . . y [16] 0 0 0 1 1 0 * . . .

Example 7
Consider the following bit-vectors: where a bit-sequence [b n , . . . b 0 ] is represented by the number n i=0 b i 2 i . The following equations hold between those bit-vectors: While it is possible to translate extractions and concatenations to integer arithmetic, it is not always efficient. We show here that it can be more efficient to keep extractions abstract and only convert at need. This approach can also help to compute simpler interpolants.

Example 8
We consider the example from [19], a formula over the structural fragment, which we divide into two parts where the bit-vectors x, y are of width 8, and z is of width 6. The unsatisfiability of A ∧ B could be proved, as before, by translating the bit-vector constraints to our core language: Using the interpolation procedure presented in Sect. 4, we can compute the following interpolant: The conjunction is unsatisfiable due to the conflicting assignment of a small slice in x and y, as illustrated in Fig. 6. However, when translating to integer arithmetic the overall structure is lost, and the interpolant contains a lot of redundancy. The situation gets worse with increasing bit-widths. The same procedure now yields an interpolant of exponentially greater size: Fig. 7 Rules translating structural and bit-wise operations into the extended core language. As before, the rules are only applied in negative positions. Note that u, l, v, w are integer constants We will explain in the next sections how more succinct interpolants can be computed by eliminating the extraction operation only lazily.

The structural fragment
In [19], a polynomial fragment of the bit-vector theory is identified, consisting of formulas that only contain extractions, concatenations, and positive equalities. The satisfiability of formulas in the structural fragment is decidable in polynomial time by a congruence closure procedure over decomposed bit-vectors [18].

Definition 1
The structural fragment consists of bit-vector formulas of the form φ 1 ∧ φ 2 ∧ · · · ∧ φ n where each φ i is an equation constructed using bit-vector variables, concrete bitvectors, and the operators bvextract [u,l] and bvconcat v+w .
Note that a formula containing bvconcat v+w can be translated into an equi-satisfiable formula that only uses bvextract [u,l] . We illustrate the translation with an example, and introduce the formal rule in Fig. 7. Consider the formula φ[bvconcat v+w (s, t)] containing the concatenation of two bit-vectors. The concatenation can be eliminated by introducing an existentially quantified variable to represent the result of the concatenation; the relationship with the arguments is established using extraction terms: To define a formal calculus for the structural fragment, we introduce an extended core language by adding a further family P ex = {extr u l | u, l ∈ N, u ≥ l} of predicates representing extraction from bit-vectors. Semantically, extr u l (s, t) relates s and t if t is the result of extracting the bits u through l from s. This is formally expressed as the existence of two bit-vectors x, y such that t can be made equal to s by prepending x and appending y: (in l (y) ∧ s = x · 2 u+1 + t · 2 l + y) Note that the argument s is not bounded, which implies that the definition contains a bound for the lower slice y, but not for x. The rewriting rules in Fig. 7 define how extraction and concatenation are translated to the P ex predicates, following the same schema as in Sect. 4. As a side-effect of adding bvextract [u,l] and bvconcat w+v , and moving beyond the structural fragment, the calculus can also reason about the bit-wise operators BVOP bv = {bvnot, bvand, bvor, bvxor}, by extracting the individual bits of the operands and encoding the Boolean semantics using inequalities. The rewriting rules for such an encoding are given Fig. 7 as well, and are also used in our implementation.

Bit-vector decomposition
As demonstrated in Sect. 1.2, unsatisfiability of formulas can sometimes be proven by just focusing on the right slice of bit-vectors; the challenge lies in how to decompose the bitvectors to find the conflicts. Intuitively, there is no need to split apart bits which are never constrained individually. We follow the procedure described in [19], and use the notion of cut points for this reason. Cut points of a bit-vector variable determine the slices that need to be considered, and the points at which the bit-vectors might have to be decomposed, and are determine by the boundaries of extraction operations.
More formally, given a formula φ in the structural fragment over set S = C ∪ X of constants and variables, a cut point configuration is a function C : S → P(N) satisfying the following properties: -for each extr u l (s, t) literal, it is the case that: -for each equality s = t it is the case that C(s) = C(t).
The set of cut points for all bit-vectors can be obtained by a fix-point computation, which begins with all cut points from extractions, and then propagates using the equalities until all conditions hold.

Example 9
Translated to our extended core language, the constraints from Example 8 are: The extraction literals induce immediate cut points for x, y and z, respectively: {6, 0}, {8, 2}, and {6, 2}. Since x and z are related by the literal extr 5 0 (x, z), the cut point 2 needs to be added to the set for x as well; similarly, due to the equation x = y, also the cut points {6, 0} have to be added for y, and 8 for x. The alignment of the bit-vectors is illustrated in Fig. 8, and the complete sets of cut points after propagation are {8, 6, 2, 0}, {8, 6, 2, 0}, and {6, 2, 0}.
The axiom states that two extr-literals will yield the same result if the first arguments coincide, and if the same bits are extracted. Similar axioms for predicate consistency and functional consistency are used in [4]. To simplify presentation, we model the instantiation of (2) using the calculus rule extr-cc in Fig. 9; the figure also gives four interpolating versions of the rule, for the four possible combinations of L/R-labels. The L R/RL rules differ in the label used in their premises. The rules can be derived by instantiating (2) using either ∀left L or ∀left R , in a similar way as in Sect. 3.3. In practice, and in our implementation, the calculus rules are used as in classical SMT-style congruence closure: they are triggered when the first arguments of a pair of extr-literals have become equal.
Extraction operations can also be translated to arithmetic, which is needed to evaluate extraction from concrete numbers, and when constructing proofs for formulas that are not in the structural fragment (i.e., that combine extraction with other bit-vector operations). The rule extr-arith encodes an operation extr u l (s, r ) using a modulo constraint to eliminate bits above position u, and division to strip away bits below position l. We express the division by existentially quantifying the remainder. A more direct rule to perform evaluation is introduced in Sect. 5.4.

Example 10
We continue Example 9, and show how an interpolating proof can be constructed for the conjunction A core ∧ B core . The root sequent of the proof is A core L , B core R ∅. In the proof tree shown in Fig. 10, we first split the given formulas using Boolean rules. Then, the literal extr 5 0 (x, z) can be decomposed using our extr-split rule at the cut point 2, and congruence closure is applied to the literals extr 5 2 (z, c 1 ) and extr 5 2 (z, 11). We similarly decompose the literal extr 7 2 (y, 6) at cut point 6, and then use extr-arith to reduce extr 3 0 (6, c 2 ) to c 2 = 6. Finally, we need a second application of congruence closure, extr-cc L R , to relate the extractions from x and y.
The resulting interpolant is the formula ∃c.(extr 5 2 (x, c) ∧ c = 11). The quantifier in the formula stems from the application of extr-cc L R , which transfers the local symbol c 1 from L to R, and thus makes it shared. A quantifier is needed to eliminate the symbol again from the interpolant. However, as can be seen the quantifier naturally disappears when translating the interpolant back to functional notation, which yields the formula bvextract [5,2] (x) = 11 in the structural fragment.
It is quite easy to see that our calculus is sound and complete for formulas in the structural fragment. The calculus does not guarantee, however, that interpolants computed for formulas in the structural fragment are again in the structural fragment, or that interpolants are quantifier-free. This leads to the question whether the structural fragment is actually closed under interpolation, i.e., whether every unsatisfiability conjunction has an interpolant that is again in the fragment. The answer to this question is positive, and it turns out that our calculus can also be used to compute such interpolants, if the right strategy is used to construct proofs.

Theorem 1 The structural fragment is closed under interpolation.
Proof We give a simple proof that follows from the fact that our calculus can model bitblasting of bit-vector formulas, and builds on work on EUF interpolation in [3,4]. The existence of more compact interpolants, avoiding the need to blast to individual bits, can also be shown, but this is slightly more involved.
Suppose A ∧ B is an unsatisfiable conjunction in the structural fragment, and A core ∧ B core the translation to the (extended) core language. Further assume that x 1 , . . . , x m are the shared bit-vector constants of A, B, and that w 1 , . . . , w m are their bit-widths, respectively. This means that we are searching for an interpolant in the structural fragment that may only * . . . . c)), or in the structural fragment bvextract [5,2] (x) = 11.
This means that b j i /c j i is the name of the jth bit of x i in the L/R partition. Note that a formula I core is an interpolant of A core ∧ B core iff it is an interpolant of A core ∧ B core , because no shared symbols are added, and we can therefore work with the latter conjunction.
Without loss of generality, we further assume that even every local constant in A core and B core occurs as first argument of some extr u l -literal, and that every bit in such constants is extracted by some of the literals. This assumption can be ensured by adding further literals to the formulas, without changing the set of possible interpolants.
We then construct a proof for the root sequent A core L , B core R ∅in our interpolating calculus by systematically applying the calculus rules. Rules are applied likewise to the Land the R-formulas, so that we only mention the L-versions at this point for sake of brevity: -∧left L to split conjunctions, and ∃left L to eliminate quantifiers; extr-split L to split every occurring extr predicate down to the level of individual bits; extr-cc L L whenever two extracts extr j j (s, r ) L , extr j j (s, r ) L for the same bit occur, followed by arithmetic rules to close the left premise; this generates an equation r = r L ; extr-cc L L whenever two extracts extr j j (s, r ) L , extr j j (t, r ) L in combination with an equation s = t L occur, followed by an application of close L L to close the left premise; again, this generates an equation r = r L ; extr-arith L whenever an extract extr j j (α, r ) L from a concrete number α ∈ Z occurs, followed by arithmetic rules to simplify the generated formula to an equation r = 0 L or r = 1 L ; extr-arith L whenever an extract extr 0 0 (s, r ) L in combination with the domain constraint in 1 (s) occurs, i.e., when the single bit of a bit-vector of width 1 is extracted, followed by arithmetic rules to simplify the generated formula to an equation r = s L .
After those rule applications, we can focus on the obtained bit-level equations in the proof goal: on equations s = t D or s = α D in which s, t have width 1 (i.e., in 1 (s) and in 1 (t)) and α ∈ {0, 1}, with D ∈ {L, R}. By construction, the set of L-labelled bit-level equations is equi-satisfiable to the original formula A core , and the R-labelled equations are equi-satisfiable to B core , so that we can continue constructing a bit-level proof using the equations.
Since the conjunction A core ∧ B core is by assumption unsatisfiable, there are three possible cases: (i) the equations labelled with L are by themselves unsatisfiable, the interpolant is false, and the proof can be closed by applying arithmetic rules; (ii) symmetrically, the equations labelled with R are unsatisfiable, and the interpolant is true; or (iii) the equations are unsatisfiable only in combination.
In case (iii), there has to be a chain of equations, alternating between L-and R-equations, that witnesses unsatisfiability. There are several symmetric cases, of which we only consider one: In the other cases, the chain can start in R and end in L, or start and end in the same partition. From (3), it is easy to read off an interpolant for A ∧ B in the structural fragment by summarising the L-chains: Clearly, I follows from A, and I ∧ B is unsatisfiable due to (3).
To construct an interpolant mechanically in our calculus, there are several strategies. The simplest one is to apply the interpolating cut-rule cut RL to each the formulas extr l=2 , which yields an interpolant I core in the core language that corresponds to the structural interpolant I shown above.

A rewriting rule for constant extraction
Given an extraction extr u l (s, r ) and bounds on s, it is in some cases possible to determine value of extracted bits. For example, the longest prefix on which the lower and upper bound agree is guaranteed to be present in any consistent value of s. Therefore, extractions that overlap with that prefix yield some bit values of the extraction without knowing the exact value of s. We allow rewriting if the extraction operator falls entirely within the common prefix: (lbound(Π, s) xor ubound(Π, s)) where rem and div are the integer remainder and division, respectively. The rule extr-const allows in particular evaluation of extractions from constant bit-vectors.

Splitting of disequalities
As shown above, proofs can be closed by finding contradicting assignments to (a slice of) a bitvector. In general, formulas can also contain bit-vector disequalities, i.e., negative equalities between bit-vectors. As an optimisation, disequalities can be split using the notion of cut points as well. Given a formula with a disequality s = t, we extend the notion of cut point configurations (Sect. 5.2) by also propagating between s and t. For a cut point i ∈ C(s) = C(t), we can then replace the disequality with a disjunction of two disequalities, as expressed by the following rule: The constants c, d must be fresh and not occur in the conclusion in this rule.

Experiments
To evaluate the effectiveness of the approach, the procedures described in this article have been implemented in the Princess theorem prover 6 [25]. The implementation of the full SMT-LIB theory of bit-vectors in Princess is still an ongoing effort, and at this point includes fairly refined versions of the calculi for non-linear arithmetic (Sect. 3) and for arithmetic bit-vector operators (Sect. 4). The implementation of the calculus for the structural fragment (Sect. 5) has been added more recently, and still lacks many optimisations that could be applied. Support for bit-wise operations (like bvand) is also quite naïve at the moment, and simply bit-blasts each bit-wise operation separately by introducing bvextract [i,i] terms for the individual bits, as shown in Fig. 7. A more refined encoding would choose, for each sub-expression, whether the arithmetic encoding or bit-blasting should be applied, but this refinement is left for future work. The implementation also supports the SMT-LIB shift operators, which are handled by splitting over the possible values of the second argument. The SMT-LIB rotation operators are not supported yet; those operators are over-approximated as uninterpreted functions, which means that it might be possible to prove problems involving the operators unsatisfiable, but not satisfiable. All experiments were done on an AMD Opteron 2220 SE machine, running 64-bit Linux and Java 1.8. Runtime was limited to 10min wall clock time, and heap space to 2GB. We used Princess version 2019-10-02 for all experiments. Where runtimes are reported, we use wall clock time.
We evaluate the performance of our approach in three different ways: -Sect. 6.1: performance of satisfiability queries on quantifier-free bit-vector formulas (SMT-LIB QF_BV), in comparison to the state-of-the-art solvers Z3 4.8.0 [37] and CVC4 1.6 [38]. -Section 6.2: performance of satisfiability queries on bit-vector formulas with quantifiers (SMT-LIB BV), again with comparison to Z3 and CVC4. -Section 6.3: applicability of the interpolation procedure for software model checking, using the integration in the Horn solver Eldarica. We compare to the software model checker CPAchecker 1.7 [39], which internally uses MathSAT 5 [20] and the interpolation method from [16].

Satisfiability queries on quantifier-free formulas
While our procedure is not specifically designed for just checking satisfiability of formulas, it is nevertheless interesting to evaluate how the approach performs on problems from the QF_BV category of the SMT-LIB. Results for this category are given in Table 1, and show that our implementation can overall solve a decent number of benchmarks, but is not competitive with Z3 and CVC4 on most of the benchmark families. As a general trend, and unsurprisingly, it can be observed that our lazy arithmetic encoding works relatively well for problems that use arithmetic bit-vector operators, but does not pay off for problems that are mostly Boolean, or problems involving bit-wise operators. Our implementation can solve the "challenge/multiplyOverflow.smt2" problem discussed in Example 3, and it performs particularly well on the "brummayerbiere4" and "pspace" families, which contain benchmarks with large bit-widths, with variables with up to 30 000 bits. This is to be expected, since our arithmetic encoding is essentially agnostic about the bounds of bit-vector variables, so that the complexity of a problem hardly changes when adding more bits.
The family "bruttomesso/core" consists of SMT-LIB problems in the structural fragment from Sect. 5 (with additional Boolean structure). Compared to the implementation described in the FMCAD 2018 paper [17], the performance on those problems has improved significantly as a result of adding the procedure described in Sect. 5. In 2018, only 8 benchmarks from the "core" family could be solved, compared to 142 in the new version. This is still lower than the results for Z3 and CVC4, which is likely due to more efficient Boolean reasoning.
We also investigated how often the rules ×split, bmod-split, and bmod-const for splitting and eliminating predicates were applied on the benchmarks. We first determined how many of the problems required the application of the rules at all: The statistics show that a large number of the benchmarks can indeed be solved without those rules. This is in particular the case for unsatisfiable problems, for which it is apparently largely sufficient to work with the simplification rules from Fig. 4, in combination with the rules for Presburger arithmetic, (non-splitting) multiplication, and extraction. In Fig. 11 we compare the required number of applications of bmod-split and bmod-const for the individual benchmarks; the scatter plot shows that often a small number of rule applications is sufficient.
The runtimes reported in Table 1 for Princess are somewhat higher than those of Z3 and CVC4, which can partly be explained by the fact that Princess is entirely implemented in Scala, and runs on a JVM. This results in repeated overhead for starting up the JVM and for just-in-time compilation. In actual applications, for instance software model checking as discussed in Sect. 6.3, normally many queries are handled without restarts in between, and the amortised overhead is smaller.

Satisfiability queries on formulas with quantifiers
We evaluate the effectiveness of our quantifier elimination approach on problems from the BV category of SMT-LIB. In order to check whether a quantified bit-vector formula is satisfiable, QE often does not have to be run to completion, instead the elimination approach from Sect. 2.2 can be stopped as soon as a statement about satisfiability of the resulting formula can be made. This incremental approach to solving quantified formulas has been implemented in Princess for Presburger arithmetic, and in combination with our lazy encoding for bitvectors also directly applies to quantified bit-vector formulas.
Results on the SMT-LIB BV benchmarks are given in Table 2. Our procedure can solve a similar number of problems as Z3 and CVC4 on many of the BV families, although the total number of problems solved is still lower than for Z3 and CVC4. Like for QF_BV, the results confirm that the encoding of bit-vectors into arithmetic is more effective for problems that are arithmetic in nature (e.g., the families "Automizer," "model," and "Heizmann"), than for more combinatorial problems (e.g., "psyco"). In general, quantified bit-vector problems tend to be smaller and harder than quantifier-free problems, which leads to a situation where it is essential to have the right heuristics and optimisations in place; in this respect our implementation is clearly still lagging behind Z3 and CVC4.
In the experiments, we used a simple portfolio mode enabled by the option -portfolio=bv. This mode is inspired by the observation that a closed bit-vector formula φ (i.e., a formula without free variables or uninterpreted predicates) can be shown to be satisfiable also be proving that the negation ¬φ is unsatisfiable, and vice versa. Experiments showed that often one of φ or ¬φ is significantly simpler to solve than the other, but that it is difficult to predict the easier one; in the portfolio mode the prover therefore simultaneously tries to solve φ and ¬φ.

Interpolation and verification of C programs
The main purpose of our procedure is the computation of Craig interpolants for bit-vector formulas. Unfortunately, comparing and evaluating interpolation procedures is relatively tricky, since the properties that can be measured easily (e.g., the size, shape, or strength of interpolants, or the time required to extract interpolants) are ultimately only of limited importance in applications. The decisive property that makes interpolants useful is the ability to generalise, which is hard to measure syntactically. Adding to this, there is no standard set of interpolation benchmarks that could be used, and the interpolation queries that occur in model checking can differ from run to run. In model checking, moreover interpolation queries are interdependent: the results of earlier queries in a run will affect the later interpolation queries being generated.   For each family, the first/second row gives sat/unsat problems. Several of the families contains benchmarks with unknown status; for those families only the total number of benchmarks is specified. Experiments were done with Princess 2019-10-02 and option -portfolio=bv We therefore decided to evaluate in an application-oriented way, by integrating our interpolation procedure into a model checker and measuring its ability to verify safety properties of C programs with machine integer semantics. As model checker we use Eldarica version 2.0.2 7 [40], a Horn clause-based model checker that uses Cartesian predicate abstraction and the CEGAR algorithm. Eldarica was already previously tightly integrated with Princess, and was in the scope of this work extended to also handle Horn clauses over bit-vectors. Since Eldarica internally uses the Princess data-structures to store Horn clauses, we could implement the translation from bit-vectors to our core language (Sect. 4.1) as a preprocessing step that is applied to all Horn clauses upfront. This means that the actual model checking engine operates purely on expressions in the core language, and all interpolation queries and implication checks stay within the core language; the need to translate back and forth between bit-vector formulas and core language is eliminated. As an obvious downside of this approach, however, it is no longer easily possible to replace the interpolation procedure with other solvers.
Benchmarks. For the experiments, we used the built-in C parser of Eldarica, and work with the benchmark set of 551 C programs already used in [41] for evaluating different predicate generation strategies. The programs stem from a variety of sources, including the SV-COMP 2016 categories "Integers and Control Flow" and "Loops," and were selecting by taking all programs that do not include arrays or heap data structures (i.e., only arithmetic operations). The verification task consisted in showing that safety assertions included in the programs can never fail. For the experiment, we interpret the programs as operating either on the unbounded mathematical integers (math, Eldarica option -arithMode:math), or on signed 32-bit bit-vectors (ilp32, Eldarica option -arithMode:ilp32) with wraparound semantics. Eldarica was otherwise run with default settings, which means that it also applies the interpolation abstraction technique from [42].
Comparison math versus ilp32. The results for math and ilp32 semantics are given in Table 3 and Fig. 12. It has to be pointed out that the status of the programs depends on the chosen semantics: for instance, the 46 HOLA programs [43] are all known to be safe in mathematical semantics, but several of the programs turn out to be unsafe in bit-vector semantics due to the possibility of overflow. Eldarica can consistently verify safety of more programs in math than in ilp32, but it can disprove safety in more of the ilp32 cases. The total number of solved cases is higher in math than in ilp32, but ilp32 is quite close (403 vs. 337); given the higher complexity of the bit-vector semantics, this is an encouraging result. The scatter plot in Fig. 12 shows that the runtimes for the two semantics are strongly correlated, and while ilp32 is on average slower than math the difference is relatively small. Table 3 also shows that the number of CEGAR iterations is comparable for math and ilp32, while the size of interpolants (measured as the average number of sub-formulas of interpolants) is bigger for ilp32 than for math, but usually by less than a factor of 2. The exception is the category "llreve/unsafe," where drastically bigger interpolants are computed for ilp32 than for math. Inspecting this case, we found that there was a single benchmark in "llreve" that was solved after 579 seconds with interpolants of size 2133; when removing this outlier, the average interpolant size for "llreve/unsafe" is only 1.1.
Comparison with CPAchecker. As comparison, we also ran the model checker CPAchecker 1.7 [39], using options -predicateAnalysis -32 and MathSAT 5 [20] as solver. MathSAT 5 uses the interpolation method from [16]. The results are given in Table 4 and Fig. 13. Our method is competitive with CPAchecker on all consid- Table 3 Comparison of Eldarica configurations math and ilp32 For each category, the table shows the number of safe/unsafe results, and for the solved cases the average time, the required number of CEGAR iterations, and the average size of computed interpolants. For * , after removing an outlier the number is 1.1, and * * becomes 1.3

Fig. 12
Comparison of the Eldarica runtime in seconds for math and ilp32 semantics ered categories: Eldarica with ilp32 can consistently prove more programs safe, whereas CPAchecker can show more programs unsafe, with a lower number of CEGAR iterations. We suspect that the use of large-block encoding [44] in CPAchecker is responsible for this phenomenon, and indeed makes CPAchecker very effective for bug finding. The runtimes of the systems are on average close, but the scatter plot in Fig. 13 shows no clear trend.
Altogether, we remark that we are comparing different verification systems here: although both Eldarica and CPAchecker apply CEGAR and interpolation, there are many factors affecting the results. What the experiments do show, however, is that the interpolation method proposed in this paper can be used to create a software model checker that is competitive with the state of the art.

Conclusions
We have presented a new calculus for Craig interpolation and quantifier elimination in bitvector arithmetic. Furthermore, we have shown how to efficiently integrate reasoning over the structural fragment. While the experimental results in model checking are already promising, we believe that there is still a lot of room for extension and improvement of the approach. This includes more powerful propagation and simplification rules, and more sophisticated strategies to apply the splitting rules ×split and bmod-split. Future work also includes more efficient use of bounds, and a strategy to employ bit-blasting directly to whole subexpressions when deemed more efficient.