Skip to content

Commit 794db70

Browse files
committed
Add solver mappings Internals module and generic to_ieee_bv impl
- All the mappings now include a `Internals` module that will inform the `Mappings` module of internal behaviours, such as const caching and native support for the `to_ieee_bv` operator. - Lift `to_ieee_bv` implementation to the `Mappings` module so that other solvers that don't have native support for `to_ieee_bv` use this aproximated implementation.
1 parent 9da6a21 commit 794db70

10 files changed

+108
-59
lines changed

src/smtml/altergo_mappings.default.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,6 @@ module Fresh = struct
318318
end
319319
end
320320

321-
let is_available = true
322-
323321
include Fresh.Make ()
322+
323+
let is_available = Internals.is_available

src/smtml/bitwuzla_mappings.default.ml

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ include Mappings_intf
77
module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
88
open B
99

10+
module Internals = struct
11+
let caches_consts = false
12+
13+
let is_available = true
14+
15+
let has_to_ieee_bv = false
16+
end
17+
1018
type ty = Sort.t
1119

1220
type term = Term.t
@@ -24,9 +32,7 @@ module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
2432
type optimizer = unit
2533

2634
(* Not supported *)
27-
type func_decl = unit
28-
29-
let caches_consts = false
35+
type func_decl = Term.t
3036

3137
let true_ = mk_true ()
3238

@@ -63,13 +69,13 @@ module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
6369
let exists _ = Fmt.failwith "Bitwuzla_mappings: exists not implemented"
6470

6571
module Types = struct
66-
let int = Obj.magic 0xdeadc0de
72+
let int = mk_bool_sort ()
6773

68-
let real = Obj.magic 0xdeadbeef
74+
let real = mk_bool_sort ()
6975

7076
let bool = mk_bool_sort ()
7177

72-
let string = Obj.magic 0xbadcafe
78+
let string = mk_bool_sort ()
7379

7480
let bitv bitwidth = mk_bv_sort bitwidth
7581

@@ -408,33 +414,19 @@ module Fresh_bitwuzla (B : Bitwuzla_cxx.S) : M = struct
408414

409415
let of_ieee_bv eb sb bv = mk_term1_indexed2 Kind.Fp_to_fp_from_bv bv eb sb
410416

411-
(* TODO *)
412-
let f32_to_i32 =
413-
let args = [| Types.float 8 24 |] in
414-
let ret = Types.bitv 32 in
415-
let sort = B.mk_fun_sort args ret in
416-
B.mk_const sort ~symbol:"f32_to_i32"
417-
418-
let f64_to_i64 =
419-
let args = [| Types.float 11 53 |] in
420-
let ret = Types.bitv 64 in
421-
let sort = B.mk_fun_sort args ret in
422-
B.mk_const sort ~symbol:"f64_to_i64"
423-
424-
let to_ieee_bv f =
425-
let f_size = Sort.fp_exp_size (Term.sort f) + Sort.fp_sig_size (Term.sort f) in
426-
if f_size = 32 then
427-
mk_term2 Kind.Apply f32_to_i32 f
428-
else if f_size = 64 then
429-
mk_term2 Kind.Apply f64_to_i64 f
430-
else
431-
Fmt.failwith "Bitwuzla_mappings: Unsupported floating-point size"
417+
let to_ieee_bv _f =
418+
Fmt.failwith "Bitwuzla_mappings: to_ieee_bv is not implemented"
432419
end
433420

434421
module Func = struct
435-
let make _ _ _ = ()
436-
437-
let apply () _ = false_
422+
let make symbol args return_ =
423+
let args = Array.of_list args in
424+
let sort = B.mk_fun_sort args return_ in
425+
B.mk_const sort ~symbol
426+
427+
let apply f args =
428+
let args = f :: args in
429+
mk_term Kind.Apply @@ Array.of_list args
438430
end
439431

440432
module Model = struct
@@ -527,9 +519,8 @@ end
527519
include (
528520
Mappings.Make (struct
529521
module Make () = Fresh_bitwuzla (Bitwuzla_cxx.Make ())
530-
531-
let is_available = true
532-
533522
include Fresh_bitwuzla (Bitwuzla_cxx)
523+
524+
let is_available = Internals.is_available
534525
end) :
535526
S_with_fresh )

src/smtml/colibri2_mappings.default.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,9 @@ module M = struct
299299
end
300300
end
301301

302-
let is_available = true
303-
304302
include Make ()
303+
304+
let is_available = Internals.is_available
305305
end
306306

307307
module M' : Mappings_intf.M_with_make = M

src/smtml/cvc5_mappings.default.ml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ open Cvc5
66
include Mappings_intf
77

88
module Fresh_cvc5 () = struct
9+
module Internals = struct
10+
let caches_consts = false
11+
12+
let is_available = true
13+
14+
let has_to_ieee_bv = false
15+
end
16+
917
type ty = Sort.sort
1018

1119
type term = Term.term
@@ -22,8 +30,6 @@ module Fresh_cvc5 () = struct
2230

2331
type func_decl = unit
2432

25-
let caches_consts = false
26-
2733
let tm = TermManager.mk_tm ()
2834

2935
let true_ = Term.mk_true tm
@@ -518,10 +524,9 @@ end
518524

519525
module Cvc5_with_make : Mappings_intf.M_with_make = struct
520526
module Make () = Fresh_cvc5 ()
521-
522-
let is_available = true
523-
524527
include Fresh_cvc5 ()
528+
529+
let is_available = Internals.is_available
525530
end
526531

527532
include Mappings.Make (Cvc5_with_make)

src/smtml/dolmenexpr_to_expr.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,20 @@ end
7575
module DolmenIntf = struct
7676
include DTerm
7777

78+
module Internals = struct
79+
let caches_consts = false
80+
81+
let is_available = true
82+
83+
let has_to_ieee_bv = false
84+
end
85+
7886
type ty = DTy.t
7987

8088
type term = DTerm.t
8189

8290
type func_decl = DTerm.Const.t
8391

84-
let caches_consts = false
85-
8692
let true_ = DTerm._true
8793

8894
let false_ = DTerm._false

src/smtml/dolmenexpr_to_expr.mli

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,20 @@ module Builtin : sig
3737
end
3838

3939
module DolmenIntf : sig
40+
module Internals : sig
41+
val caches_consts : bool
42+
43+
val is_available : bool
44+
45+
val has_to_ieee_bv : bool
46+
end
47+
4048
type ty = DTy.t
4149

4250
type term = DTerm.t
4351

4452
type func_decl = DTerm.Const.t
4553

46-
val caches_consts : bool
47-
4854
val true_ : term
4955

5056
val false_ : term

src/smtml/mappings.ml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
5050

5151
let str_trim = M.Func.make "string_trim" [ M.Types.string ] M.Types.string
5252

53+
let f32_to_i32 = M.Func.make "f32_to_i32" [ f32 ] i32
54+
55+
let f64_to_i64 = M.Func.make "f64_to_i64" [ f64 ] i64
56+
5357
let get_type = function
5458
| Ty_int -> M.Types.int
5559
| Ty_real -> M.Types.real
@@ -66,7 +70,7 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
6670

6771
let make_symbol (ctx : symbol_ctx) (s : Symbol.t) : symbol_ctx * M.term =
6872
let name = match s.name with Simple name -> name | _ -> assert false in
69-
if M.caches_consts then
73+
if M.Internals.caches_consts then
7074
let sym = M.const name (get_type s.ty) in
7175
(Smap.add s sym ctx, sym)
7276
else
@@ -297,6 +301,8 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
297301

298302
val bitwidth : int
299303

304+
val to_ieee_bv : M.term -> M.term
305+
300306
module Ixx : sig
301307
val of_int : int -> elt
302308

@@ -401,7 +407,7 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
401407
Float.to_sbv bitwidth ~rm:Float.Rounding_mode.rtz e
402408
| TruncUF32 | TruncUF64 ->
403409
Float.to_ubv bitwidth ~rm:Float.Rounding_mode.rtz e
404-
| Reinterpret_float -> Float.to_ieee_bv e
410+
| Reinterpret_float -> to_ieee_bv e
405411
| ToBool -> M.distinct [ e; v @@ Ixx.of_int 0 ]
406412
| OfBool -> ite e (v @@ Ixx.of_int 1) (v @@ Ixx.of_int 0)
407413
| _ -> assert false
@@ -414,20 +420,28 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
414420

415421
let bitwidth = 8
416422

423+
let to_ieee_bv _ = assert false
424+
417425
module Ixx = struct
418426
let of_int i = i [@@inline]
419427

420428
let shift_left v i = v lsl i [@@inline]
421429
end
422430
end)
423431

432+
let to_ieee_bv f e =
433+
if M.Internals.has_to_ieee_bv then M.Float.to_ieee_bv e
434+
else M.Func.apply f [ e ]
435+
424436
module I32 = Bitv_impl (struct
425437
type elt = int32
426438

427439
let v i = M.Bitv.v (Int32.to_string i) 32
428440

429441
let bitwidth = 32
430442

443+
let to_ieee_bv = to_ieee_bv f32_to_i32
444+
431445
module Ixx = Int32
432446
end)
433447

@@ -436,6 +450,8 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
436450

437451
let v i = M.Bitv.v (Int64.to_string i) 64
438452

453+
let to_ieee_bv = to_ieee_bv f64_to_i64
454+
439455
let bitwidth = 64
440456

441457
module Ixx = Int64

src/smtml/mappings.nop.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
module Nop = struct
66
module Make () = struct
7+
module Internals = struct
8+
let caches_consts = false
9+
10+
let is_available = false
11+
12+
let has_to_ieee_bv = false
13+
end
14+
715
type ty = unit
816

917
type term = unit
@@ -20,8 +28,6 @@ module Nop = struct
2028

2129
type func_decl = unit
2230

23-
let caches_consts = false
24-
2531
let true_ = ()
2632

2733
let false_ = ()

src/smtml/mappings_intf.ml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
solvers, including term construction, type handling, and solver interaction.
1414
*)
1515
module type M = sig
16+
module Internals : sig
17+
(** [is_available] indicates whether the module is available for use. *)
18+
val is_available : bool
19+
20+
(** [caches_consts] indicates whether the solver caches constants. *)
21+
val caches_consts : bool
22+
23+
(** [has_to_ieee_bv] indicates whether the solver native support for the
24+
[to_ieee_bv]. *)
25+
val has_to_ieee_bv : bool
26+
end
27+
1628
(** The type of SMT sorts (types). *)
1729
type ty
1830

@@ -37,9 +49,6 @@ module type M = sig
3749
(** The type of function declarations. *)
3850
type func_decl
3951

40-
(** [caches_consts] indicates whether the solver caches constants. *)
41-
val caches_consts : bool
42-
4352
(** [true_] represents the Boolean constant [true]. *)
4453
val true_ : term
4554

@@ -74,7 +83,8 @@ module type M = sig
7483
(** [xor t1 t2] constructs the logical XOR of the terms [t1] and [t2]. *)
7584
val xor : term -> term -> term
7685

77-
(** [implies t1 t2] constructs the logical implication of the terms [t1] and [t2]. *)
86+
(** [implies t1 t2] constructs the logical implication of the terms [t1] and
87+
[t2]. *)
7888
val implies : term -> term -> term
7989

8090
(** [eq t1 t2] constructs the equality of the terms [t1] and [t2]. *)
@@ -711,7 +721,10 @@ module type M_with_make = sig
711721
(** [Make ()] creates a new instance of the [M] module type. *)
712722
module Make () : M
713723

714-
(** [is_available] indicates whether the module is available for use. *)
724+
(** [is_available] indicates whether the module is available for use.
725+
726+
Will be deprecated in the future, please use Internals.is_available
727+
instead. *)
715728
val is_available : bool
716729

717730
(** Include the [M] module type. *)

src/smtml/z3_mappings.default.ml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ include Mappings_intf
66

77
module M = struct
88
module Make () = struct
9+
module Internals = struct
10+
let caches_consts = true
11+
12+
let is_available = true
13+
14+
let has_to_ieee_bv = true
15+
end
16+
917
type ty = Z3.Sort.sort
1018

1119
type term = Z3.Expr.expr
@@ -22,8 +30,6 @@ module M = struct
2230

2331
type func_decl = Z3.FuncDecl.func_decl
2432

25-
let caches_consts = true
26-
2733
let ctx = Z3.mk_context []
2834

2935
let true_ = Z3.Boolean.mk_true ctx
@@ -554,9 +560,9 @@ module M = struct
554560
end
555561
end
556562

557-
let is_available = true
558-
559563
include Make ()
564+
565+
let is_available = Internals.is_available
560566
end
561567

562568
module M' : Mappings_intf.M_with_make = M

0 commit comments

Comments
 (0)