Skip to content

Commit 0e0803a

Browse files
committed
Add bitvector overflow predicate operators (#417)
1 parent f251001 commit 0e0803a

File tree

7 files changed

+113
-4
lines changed

7 files changed

+113
-4
lines changed

src/smtml/bitwuzla_mappings.default.ml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
296296

297297
let lshr t1 t2 = mk_term2 Kind.Bv_shr t1 t2
298298

299+
let smod t1 t2 = mk_term2 Kind.Bv_smod t1 t2
300+
299301
let rem t1 t2 = mk_term2 Kind.Bv_srem t1 t2
300302

301303
let rem_u t1 t2 = mk_term2 Kind.Bv_urem t1 t2
@@ -304,6 +306,19 @@ module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
304306

305307
let rotate_right t1 t2 = mk_term2 Kind.Bv_ror t1 t2
306308

309+
let nego t = mk_term1 Kind.Bv_nego t
310+
311+
let addo ~signed t1 t2 =
312+
mk_term2 (if signed then Kind.Bv_saddo else Kind.Bv_uaddo) t1 t2
313+
314+
let subo ~signed t1 t2 =
315+
mk_term2 (if signed then Kind.Bv_ssubo else Kind.Bv_usubo) t1 t2
316+
317+
let mulo ~signed t1 t2 =
318+
mk_term2 (if signed then Kind.Bv_smulo else Kind.Bv_umulo) t1 t2
319+
320+
let divo t1 t2 = mk_term2 Kind.Bv_sdivo t1 t2
321+
307322
let lt t1 t2 = mk_term2 Kind.Bv_slt t1 t2
308323

309324
let lt_u t1 t2 = mk_term2 Kind.Bv_ult t1 t2

src/smtml/cvc5_mappings.default.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ module Fresh_cvc5 () = struct
280280

281281
let lshr t1 t2 = Term.mk_term tm Kind.Bitvector_lshr [| t1; t2 |]
282282

283+
let smod _ = Fmt.failwith "Cvc5_mappings: smod not implemented"
284+
283285
let rem t1 t2 = Term.mk_term tm Kind.Bitvector_srem [| t1; t2 |]
284286

285287
let rem_u t1 t2 = Term.mk_term tm Kind.Bitvector_urem [| t1; t2 |]
@@ -290,6 +292,16 @@ module Fresh_cvc5 () = struct
290292
let rotate_right t1 t2 =
291293
Term.mk_term tm Kind.Bitvector_rotate_right [| t1; t2 |]
292294

295+
let nego _ = Fmt.failwith "Cvc5_mappings: nego not implemented"
296+
297+
let addo ~signed:_ = Fmt.failwith "Cvc5_mappings: addo not implemented"
298+
299+
let subo ~signed:_ = Fmt.failwith "Cvc5_mappings: subo not implemented"
300+
301+
let mulo ~signed:_ = Fmt.failwith "Cvc5_mappings: mulo not implemented"
302+
303+
let divo _ = Fmt.failwith "Cvc5_mappings: divo not support not implemented"
304+
293305
let lt t1 t2 = Term.mk_term tm Kind.Bitvector_slt [| t1; t2 |]
294306

295307
let lt_u t1 t2 = Term.mk_term tm Kind.Bitvector_ult [| t1; t2 |]

src/smtml/dolmenexpr_to_expr.ml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,17 +335,27 @@ module DolmenIntf = struct
335335

336336
let rotate_right t1 t2 = DTerm.Bitv.rotate_right (int_of_term t2) t1
337337

338-
let lt t1 t2 = DTerm.Bitv.slt t1 t2
338+
let nego _ = Fmt.failwith "Dolmenexpr: nego not implemented"
339339

340-
let lt_u t1 t2 = DTerm.Bitv.ult t1 t2
340+
let addo ~signed:_ = Fmt.failwith "Dolmenexpr: addo not implemented"
341+
342+
let subo ~signed:_ = Fmt.failwith "Dolmenexpr: subo not implemented"
343+
344+
let mulo ~signed:_ = Fmt.failwith "Dolmenexpr: mulo not implemented"
345+
346+
let divo _ = Fmt.failwith "Dolmenexpr: divo not implemented"
347+
348+
let lt = DTerm.Bitv.slt
349+
350+
let lt_u = DTerm.Bitv.ult
341351

342352
let le = DTerm.Bitv.sle
343353

344354
let le_u = DTerm.Bitv.ule
345355

346-
let gt t1 t2 = DTerm.Bitv.sgt t1 t2
356+
let gt = DTerm.Bitv.sgt
347357

348-
let gt_u t1 t2 = DTerm.Bitv.ugt t1 t2
358+
let gt_u = DTerm.Bitv.ugt
349359

350360
let ge = DTerm.Bitv.sge
351361

src/smtml/dolmenexpr_to_expr.mli

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ module DolmenIntf : sig
277277

278278
val lshr : term -> term -> term
279279

280+
val smod : term -> term -> term
281+
280282
val rem : term -> term -> term
281283

282284
val rem_u : term -> term -> term
@@ -285,6 +287,16 @@ module DolmenIntf : sig
285287

286288
val rotate_right : term -> term -> term
287289

290+
val nego : term -> term
291+
292+
val addo : signed:bool -> term -> term -> term
293+
294+
val subo : signed:bool -> term -> term -> term
295+
296+
val mulo : signed:bool -> term -> term -> term
297+
298+
val divo : term -> term -> term
299+
288300
val lt : term -> term -> term
289301

290302
val lt_u : term -> term -> term

src/smtml/mappings.nop.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ module Nop = struct
253253

254254
let lshr _ = assert false
255255

256+
let smod _ = assert false
257+
256258
let rem _ = assert false
257259

258260
let rem_u _ = assert false
@@ -261,6 +263,16 @@ module Nop = struct
261263

262264
let rotate_right _ = assert false
263265

266+
let nego _ = assert false
267+
268+
let addo ~signed:_ = assert false
269+
270+
let subo ~signed:_ = assert false
271+
272+
let mulo ~signed:_ = assert false
273+
274+
let divo _ = assert false
275+
264276
let lt _ = assert false
265277

266278
let lt_u _ = assert false

src/smtml/mappings_intf.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ module type M = sig
446446
(** [lshr t1 t2] constructs the logical right shift of [t1] by [t2]. *)
447447
val lshr : term -> term -> term
448448

449+
(** [smod t1 t2] two's complement signed remainder (sign follows divisor).
450+
*)
451+
val smod : term -> term -> term
452+
449453
(** [rem t1 t2] constructs the remainder of the bitvector terms [t1] and
450454
[t2]. *)
451455
val rem : term -> term -> term
@@ -460,6 +464,38 @@ module type M = sig
460464
(** [rotate_right t1 t2] constructs the right rotation of [t1] by [t2]. *)
461465
val rotate_right : term -> term -> term
462466

467+
(** [nego t] constructs a predicate that checks that whether the bit-wise
468+
negation of [t] does not overflow. *)
469+
val nego : term -> term
470+
471+
(** [addo ~signed t1 t2] constructs a predicate that checks whether the
472+
bitwise addition of [t1] and [t2] does not overflow.
473+
474+
The [signed] argument is a boolean:
475+
- [true] -> for signed addition
476+
- [false] -> for unsigned addition *)
477+
val addo : signed:bool -> term -> term -> term
478+
479+
(** [subo ~signed t1 t2] constructs a predicate that checks whether the
480+
bitwise subtraction of [t1] and [t2] does not overflow.
481+
482+
The [signed] argument is a boolean:
483+
- [true] -> for signed subtraction
484+
- [false] -> for unsigned subtraction *)
485+
val subo : signed:bool -> term -> term -> term
486+
487+
(** [mulo ~signed t1 t2] constructs a predicate that checks whether the
488+
bitwise multiplication of [t1] and [t2] does not overflow.
489+
490+
The [signed] argument is a boolean:
491+
- [true] -> for signed multiplication
492+
- [false] -> for unsigned multiplication *)
493+
val mulo : signed:bool -> term -> term -> term
494+
495+
(** [divo t1 t2] constructs a predicate that checks whether the bitwise
496+
division of [t1] and [t2] does not overflow. *)
497+
val divo : term -> term -> term
498+
463499
(** [lt t1 t2] constructs the less-than relation between bitvector terms
464500
[t1] and [t2]. *)
465501
val lt : term -> term -> term

src/smtml/z3_mappings.default.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ module M = struct
322322

323323
let lshr e1 e2 = Z3.BitVector.mk_lshr ctx e1 e2
324324

325+
let smod e1 e2 = Z3.BitVector.mk_smod ctx e1 e2
326+
325327
let rem e1 e2 = Z3.BitVector.mk_srem ctx e1 e2
326328

327329
let rem_u e1 e2 = Z3.BitVector.mk_urem ctx e1 e2
@@ -330,6 +332,16 @@ module M = struct
330332

331333
let rotate_right e1 e2 = Z3.BitVector.mk_ext_rotate_right ctx e1 e2
332334

335+
let nego e = Z3.BitVector.mk_neg_no_overflow ctx e
336+
337+
let addo ~signed e1 e2 = Z3.BitVector.mk_add_no_overflow ctx e1 e2 signed
338+
339+
let subo ~signed:_ e1 e2 = Z3.BitVector.mk_sub_no_overflow ctx e1 e2
340+
341+
let mulo ~signed e1 e2 = Z3.BitVector.mk_mul_no_overflow ctx e1 e2 signed
342+
343+
let divo e1 e2 = Z3.BitVector.mk_sdiv_no_overflow ctx e1 e2
344+
333345
let lt e1 e2 = Z3.BitVector.mk_slt ctx e1 e2
334346

335347
let lt_u e1 e2 = Z3.BitVector.mk_ult ctx e1 e2

0 commit comments

Comments
 (0)