Skip to content

Commit 3860ccd

Browse files
committed
Support FPA literals {+|-}{inf,zero} and NaN
1 parent 8ec6207 commit 3860ccd

File tree

7 files changed

+69
-12
lines changed

7 files changed

+69
-12
lines changed

src/smtml/logic.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type t =
1111
| QF_AX
1212
| QF_BV
1313
| QF_BVFP
14+
| QF_FP
1415
| QF_IDL
1516
| QF_LIA
1617
| QF_LRA
@@ -40,6 +41,7 @@ let pp fmt = function
4041
| QF_AX -> Fmt.string fmt "QF_AX"
4142
| QF_BV -> Fmt.string fmt "QF_BV"
4243
| QF_BVFP -> Fmt.string fmt "QF_BVFP"
44+
| QF_FP -> Fmt.string fmt "QF_FP"
4345
| QF_IDL -> Fmt.string fmt "QF_IDL"
4446
| QF_LIA -> Fmt.string fmt "QF_LIA"
4547
| QF_LRA -> Fmt.string fmt "QF_LRA"
@@ -70,6 +72,7 @@ let of_string logic =
7072
| "QF_AX" -> Ok QF_AX
7173
| "QF_BV" -> Ok QF_BV
7274
| "QF_BVFP" -> Ok QF_BVFP
75+
| "QF_FP" -> Ok QF_FP
7376
| "QF_IDL" -> Ok QF_IDL
7477
| "QF_LIA" -> Ok QF_LIA
7578
| "QF_LRA" -> Ok QF_LRA

src/smtml/logic.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type t =
3030
| QF_AX (** Quantifier-free array theory. *)
3131
| QF_BV (** Quantifier-free bitvector theory. *)
3232
| QF_BVFP (** Quantifier-free bitvectors and floating-point arithmetic. *)
33+
| QF_FP (** Quantifier-free floating-point arithmetic. *)
3334
| QF_IDL (** Quantifier-free integer difference logic. *)
3435
| QF_LIA (** Quantifier-free linear integer arithmetic. *)
3536
| QF_LRA (** Quantifier-free linear real arithmetic. *)

src/smtml/rewrite.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ let debug fmt k = if debug then k (Fmt.epr fmt)
2323
let rewrite_ty unknown_ty tys =
2424
debug " rewrite_ty: %a@." (fun k -> k Ty.pp unknown_ty);
2525
match (unknown_ty, tys) with
26-
| Ty.Ty_none, [ ty ] -> ty
27-
| Ty.Ty_none, [ ty1; ty2 ] ->
26+
| Ty_none, [ ty ] -> ty
27+
| Ty_none, [ ty1; ty2 ] ->
2828
debug " rewrite_ty: %a %a@." (fun k -> k Ty.pp ty1 Ty.pp ty2);
2929
assert (Ty.equal ty1 ty2);
3030
ty1
31-
| Ty.Ty_none, _ -> assert false
31+
| Ty_none, _ -> assert false
3232
| ty, _ -> ty
3333

3434
(** Propagates types in [type_map] and inlines [Let_in] binders *)

src/smtml/smtlib.ml

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,22 @@ let pp_loc fmt = function
1212
| None -> ()
1313
| Some loc -> Fmt.pf fmt "%a: " Loc.print_compact loc
1414

15+
let z_of_string_opt str =
16+
match Z.of_string str with
17+
| exception Invalid_argument _ -> None
18+
| z -> Some z
19+
1520
module Term = struct
1621
type t = Expr.t
1722

23+
let fp_of_size f ebits sbits =
24+
match (ebits, sbits) with
25+
| "8", "24" -> Expr.value (Num (F32 (Int32.bits_of_float f)))
26+
| "11", "53" -> Expr.value (Num (F64 (Int64.bits_of_float f)))
27+
| _ ->
28+
Fmt.failwith "fp_of_size: unsupported %a (fp %a %a)" Fmt.float f
29+
Fmt.string ebits Fmt.string sbits
30+
1831
let const ?loc (id : Symbol.t) : t =
1932
match (Symbol.namespace id, Symbol.name id) with
2033
| Sort, Simple name -> (
@@ -50,15 +63,24 @@ module Term = struct
5063
| "true" -> Expr.value True
5164
| "false" -> Expr.value False
5265
| _ -> Expr.symbol id )
53-
| Term, Indexed { basename = base; indices } -> (
54-
match String.(sub base 0 2, sub base 2 (length base - 2), indices) with
55-
| "bv", str, [ numbits ] -> begin
56-
match (int_of_string_opt str, int_of_string_opt numbits) with
57-
| Some n, Some width ->
58-
Expr.value (Bitv (Bitvector.make (Z.of_int n) width))
66+
| Term, Indexed { basename = base; indices } -> begin
67+
match (base, indices) with
68+
| bv, [ numbits ] when String.starts_with ~prefix:"bv" bv -> begin
69+
let str = String.sub bv 2 (String.length bv - 2) in
70+
match (z_of_string_opt str, int_of_string_opt numbits) with
71+
| Some z, Some width -> Expr.value (Bitv (Bitvector.make z width))
5972
| (None | Some _), _ -> assert false
6073
end
61-
| _ -> Expr.symbol id )
74+
| "+oo", [ ebits; sbits ] -> fp_of_size Float.infinity ebits sbits
75+
| "-oo", [ ebits; sbits ] -> fp_of_size Float.neg_infinity ebits sbits
76+
| "+zero", [ ebits; sbits ] -> fp_of_size Float.zero ebits sbits
77+
| "-zero", [ ebits; sbits ] ->
78+
fp_of_size (Float.neg Float.zero) ebits sbits
79+
| "NaN", [ ebits; sbits ] -> fp_of_size Float.nan ebits sbits
80+
| _ ->
81+
Log.debug (fun k -> k "const: Unknown %a making app" Symbol.pp id);
82+
Expr.symbol id
83+
end
6284
| Attr, Simple _ -> Expr.symbol id
6385
| Attr, Indexed _ -> assert false
6486
| Var, _ -> Fmt.failwith "%acould not parse var: %a" pp_loc loc Symbol.pp id
@@ -94,6 +116,7 @@ module Term = struct
94116
match Expr.view symbol with
95117
| Symbol s ->
96118
(* Hack: var bindings are 1 argument lambdas *)
119+
Log.debug (fun k -> k "colon: unknown '%a' making app" Expr.pp symbol);
97120
Expr.app s [ term ]
98121
| _ ->
99122
Fmt.failwith "%acould not parse colon: %a %a" pp_loc loc Expr.pp symbol
@@ -257,8 +280,11 @@ module Term = struct
257280
| "fp.geq", [ a; b ] -> Expr.raw_relop Ty_bool Ge a b
258281
| "fp.gt", [ a; b ] -> Expr.raw_relop Ty_bool Gt a b
259282
| "fp.eq", [ a; b ] -> Expr.raw_relop Ty_bool Eq a b
260-
| _, l -> Expr.app symbol l )
283+
| _, l ->
284+
Log.debug (fun k -> k "apply: unknown %a making app" Symbol.pp symbol);
285+
Expr.app symbol l )
261286
| Symbol ({ name = Simple _; namespace = Attr; _ } as attr) ->
287+
Log.debug (fun k -> k "apply: unknown %a making app" Symbol.pp attr);
262288
Expr.app attr args
263289
| Symbol { name = Indexed { basename; indices }; _ } -> (
264290
match (basename, indices, args) with
@@ -291,7 +317,9 @@ module Term = struct
291317
Expr.raw_unop Ty_regexp (Regexp_loop (i1, i2)) a
292318
| _ ->
293319
Fmt.failwith "%acould not parse indexed app: %a" pp_loc loc Expr.pp id )
294-
| Symbol id -> Expr.app id args
320+
| Symbol id ->
321+
Log.debug (fun k -> k "apply: unknown %a making app" Symbol.pp id);
322+
Expr.app id args
295323
| _ ->
296324
(* Ids can only be symbols. Any other expr here is super wrong *)
297325
assert false

test/cli/smt2/dune

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
test_exists.smt2
1414
test_forall.smt2
1515
test_fp.smt2
16+
test_fp_literals.smt2
1617
test_lia.smt2
1718
test_lra.smt2
1819
test_string_all.smt2
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
(set-logic QF_FP)
2+
3+
(declare-fun pos_inf () (_ FloatingPoint 8 24))
4+
(declare-fun neg_inf () (_ FloatingPoint 8 24))
5+
(declare-fun pos_zero () (_ FloatingPoint 8 24))
6+
(declare-fun neg_zero () (_ FloatingPoint 8 24))
7+
(declare-fun nan_val () (_ FloatingPoint 8 24))
8+
9+
(assert (= pos_inf (_ +oo 8 24)))
10+
(assert (= neg_inf (_ -oo 8 24)))
11+
(assert (= pos_zero (_ +zero 8 24)))
12+
(assert (= neg_zero (_ -zero 8 24)))
13+
(assert (= nan_val (_ NaN 8 24)))
14+
15+
(check-sat)
16+
(get-model)

test/cli/smt2/test_smt2.t

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ Test BitVector parsing:
5353
Test FloatingPoint parsing:
5454
$ smtml run test_fp.smt2
5555
sat
56+
$ smtml run test_fp_literals.smt2
57+
sat
58+
(model
59+
(nan_val f32 nan)
60+
(neg_inf f32 neg_infinity)
61+
(neg_zero f32 -0.)
62+
(pos_inf f32 infinity)
63+
(pos_zero f32 0.))
5664

5765
Tests smt2 with the --from-file argument:
5866
$ cat <<EOF > test.list

0 commit comments

Comments
 (0)