Skip to content

Commit bccb230

Browse files
authored
Merge pull request #1527 from goblint/apron-pretty
Refactor Apron `Printable`s
2 parents 4ca8df9 + eb78ad7 commit bccb230

File tree

8 files changed

+130
-34
lines changed

8 files changed

+130
-34
lines changed

src/analyses/apron/relationAnalysis.apron.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ struct
295295
(* there should be smarter ways to do this, e.g. by keeping track of which values are written etc. ... *)
296296
(* See, e.g, Beckschulze E, Kowalewski S, Brauer J (2012) Access-based localization for octagons. Electron Notes Theor Comput Sci 287:29–40 *)
297297
(* Also, a local *)
298-
let vname = Apron.Var.to_string var in
298+
let vname = GobApron.Var.show var in
299299
let locals = fundec.sformals @ fundec.slocals in
300300
match List.find_opt (fun v -> VM.var_name (Local v) = vname) locals with (* TODO: optimize *)
301301
| None -> true
@@ -418,7 +418,7 @@ struct
418418
in
419419
let any_local_reachable = any_local_reachable fundec reachable_from_args in
420420
let arg_vars = f.sformals |> List.filter (RD.Tracked.varinfo_tracked) |> List.map RV.arg in
421-
if M.tracing then M.tracel "combine-rel" "relation remove vars: %a" (docList (fun v -> Pretty.text (Apron.Var.to_string v))) arg_vars;
421+
if M.tracing then M.tracel "combine-rel" "relation remove vars: %a" (docList (GobApron.Var.pretty ())) arg_vars;
422422
RD.remove_vars_with new_fun_rel arg_vars; (* fine to remove arg vars that also exist in caller because unify from new_rel adds them back with proper constraints *)
423423
let tainted = f_ask.f Queries.MayBeTainted in
424424
let tainted_vars = TaintPartialContexts.conv_varset tainted in

src/cdomains/apron/affineEqualityDomain.apron.ml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct
181181
else if Z.lt coeff Z.minus_one then Z.to_string coeff
182182
else Format.asprintf "+%s" (Z.to_string coeff)
183183
in
184-
coeff_str ^ Var.to_string var
184+
coeff_str ^ Var.show var
185185
in
186186
let const_to_str vl =
187187
if Z.equal vl Z.zero then
@@ -203,11 +203,10 @@ struct
203203
| Some m when Matrix.is_empty m -> ""
204204
| Some m ->
205205
let constraint_list = List.init (Matrix.num_rows m) (fun i -> vec_to_constraint (conv_to_ints @@ Matrix.get_row m i) t.env) in
206-
Format.asprintf "%s" ("[|"^ (String.concat "; " constraint_list) ^"|]")
206+
"[|"^ (String.concat "; " constraint_list) ^"|]"
207207

208208
let pretty () (x:t) = text (show x)
209-
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nmatrix\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%s</value>\n</map>\n</value>\n" (XmlUtil.escape (Format.asprintf "%s" (show x) )) (XmlUtil.escape (Format.asprintf "%a" (Environment.print: Format.formatter -> Environment.t -> unit) (x.env)))
210-
209+
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nmatrix\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%a</value>\n</map>\n</value>\n" (XmlUtil.escape (show x)) Environment.printXml x.env
211210
let eval_interval ask = Bounds.bound_texpr
212211

213212
let name () = "affeq"
@@ -430,8 +429,8 @@ struct
430429

431430
let assign_exp ask t var exp no_ov =
432431
let res = assign_exp ask t var exp no_ov in
433-
if M.tracing then M.tracel "ops" "assign_exp t:\n %s \n var: %s \n exp: %a\n no_ov: %b -> \n %s"
434-
(show t) (Var.to_string var) d_exp exp (Lazy.force no_ov) (show res) ;
432+
if M.tracing then M.tracel "ops" "assign_exp t:\n %s \n var: %a \n exp: %a\n no_ov: %b -> \n %s"
433+
(show t) Var.pretty var d_exp exp (Lazy.force no_ov) (show res);
435434
res
436435

437436
let assign_var (t: VarManagement(Vc)(Mx).t) v v' =
@@ -441,7 +440,7 @@ struct
441440

442441
let assign_var t v v' =
443442
let res = assign_var t v v' in
444-
if M.tracing then M.tracel "ops" "assign_var t:\n %s \n v: %s \n v': %s\n -> %s" (show t) (Var.to_string v) (Var.to_string v') (show res) ;
443+
if M.tracing then M.tracel "ops" "assign_var t:\n %s \n v: %a \n v': %a\n -> %s" (show t) Var.pretty v Var.pretty v' (show res);
445444
res
446445

447446
let assign_var_parallel t vv's =
@@ -499,7 +498,7 @@ struct
499498

500499
let substitute_exp ask t var exp no_ov =
501500
let res = substitute_exp ask t var exp no_ov in
502-
if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %s \n exp: %a \n -> \n %s" (show t) (Var.to_string var) d_exp exp (show res);
501+
if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %a \n exp: %a \n -> \n %s" (show t) Var.pretty var d_exp exp (show res);
503502
res
504503

505504
let substitute_exp ask t var exp no_ov = timing_wrap "substitution" (substitute_exp ask t var exp) no_ov

src/cdomains/apron/apronDomain.apron.ml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ struct
283283
let assign_exp_with ask nd v e no_ov =
284284
match Convert.texpr1_of_cil_exp ask nd (A.env nd) e no_ov with
285285
| texpr1 ->
286-
if M.tracing then M.trace "apron" "assign_exp converted: %s" (Format.asprintf "%a" Texpr1.print texpr1);
286+
if M.tracing then M.trace "apron" "assign_exp converted: %a" Texpr1.pretty texpr1;
287287
A.assign_texpr_with Man.mgr nd v texpr1 None
288288
| exception Convert.Unsupported_CilExp _ ->
289289
if M.tracing then M.trace "apron" "assign_exp unsupported";
@@ -442,7 +442,7 @@ struct
442442
let invariant _ = []
443443

444444
let show (x:t) =
445-
Format.asprintf "%a (env: %a)" A.print x (Environment.print: Format.formatter -> Environment.t -> unit) (A.env x)
445+
GobFormat.asprintf "%a (env: %a)" A.print x Environment.pp (A.env x)
446446
let pretty () (x:t) = text (show x)
447447

448448
let equal x y =
@@ -454,7 +454,7 @@ struct
454454
let compare (x: t) (y: t): int =
455455
failwith "Apron.Abstract1 doesn't have total order" (* https://github.com/antoinemine/apron/issues/99 *)
456456

457-
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nconstraints\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%s</value>\n</map>\n</value>\n" (XmlUtil.escape (Format.asprintf "%a" A.print x)) (XmlUtil.escape (Format.asprintf "%a" (Environment.print: Format.formatter -> Environment.t -> unit) (A.env x)))
457+
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nconstraints\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%a</value>\n</map>\n</value>\n" (XmlUtil.escape (GobFormat.asprint A.print x)) Environment.printXml (A.env x)
458458

459459
let to_yojson (x: t) =
460460
let constraints =
@@ -463,11 +463,9 @@ struct
463463
|> Lincons1Set.elements
464464
|> List.map (fun lincons1 -> `String (Lincons1.show lincons1))
465465
in
466-
let env = `String (Format.asprintf "%a" (Environment.print: Format.formatter -> Environment.t -> unit) (A.env x))
467-
in
468466
`Assoc [
469467
("constraints", `List constraints);
470-
("env", env);
468+
("env", Environment.to_yojson (A.env x));
471469
]
472470

473471
let unify x y =
@@ -533,9 +531,9 @@ struct
533531
| _ ->
534532
begin match Convert.tcons1_of_cil_exp ask d (A.env d) e negate no_ov with
535533
| tcons1 ->
536-
if M.tracing then M.trace "apron" "assert_constraint %a %s" d_exp e (Format.asprintf "%a" Tcons1.print tcons1);
534+
if M.tracing then M.trace "apron" "assert_constraint %a %a" d_exp e Tcons1.pretty tcons1;
537535
if M.tracing then M.trace "apron" "assert_constraint st: %a" D.pretty d;
538-
if M.tracing then M.trace "apron" "assert_constraint tcons1: %s" (Format.asprintf "%a" Tcons1.print tcons1);
536+
if M.tracing then M.trace "apron" "assert_constraint tcons1: %a" Tcons1.pretty tcons1;
539537
let r = meet_tcons ask d tcons1 e in
540538
if M.tracing then M.trace "apron" "assert_constraint r: %a" D.pretty r;
541539
r
@@ -598,7 +596,7 @@ struct
598596
let x_cons = A.to_lincons_array Man.mgr x_j in
599597
let y_cons = A.to_lincons_array Man.mgr y_j in
600598
let try_add_con j con1 =
601-
if M.tracing then M.tracei "apron" "try_add_con %s" (Format.asprintf "%a" (Lincons1.print: Format.formatter -> Lincons1.t -> unit) con1);
599+
if M.tracing then M.tracei "apron" "try_add_con %a" Lincons1.pretty con1;
602600
let t = meet_lincons j con1 in
603601
let t_x = A.change_environment Man.mgr t x_env false in
604602
let t_y = A.change_environment Man.mgr t y_env false in
@@ -637,7 +635,7 @@ struct
637635
in
638636
let env_exists_mem_con1 env con1 =
639637
let r = env_exists_mem_con1 env con1 in
640-
if M.tracing then M.trace "apron" "env_exists_mem_con1 %s %s -> %B" (Format.asprintf "%a" (Environment.print: Format.formatter -> Environment.t -> unit) env) (Lincons1.show con1) r;
638+
if M.tracing then M.trace "apron" "env_exists_mem_con1 %a %a -> %B" Environment.pretty env Lincons1.pretty con1 r;
641639
r
642640
in
643641
(* Heuristically reorder constraints to pass 36/12 with singlethreaded->multithreaded mode switching. *)

src/cdomains/apron/gobApron.apron.ml

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
open Batteries
22
include Apron
33

4+
module Scalar =
5+
struct
6+
include Scalar
7+
8+
let pp = print
9+
include Printable.SimpleFormat (
10+
struct
11+
type nonrec t = t
12+
let pp = pp
13+
end
14+
)
15+
end
16+
417
module Coeff =
518
struct
619
include Coeff
@@ -11,14 +24,30 @@ end
1124
module Var =
1225
struct
1326
include Var
27+
28+
let pp = print
29+
include Printable.SimpleFormat (
30+
struct
31+
type nonrec t = t
32+
let pp = pp
33+
end
34+
)
35+
1436
let equal x y = Var.compare x y = 0
1537
end
1638

1739
module Lincons1 =
1840
struct
1941
include Lincons1
2042

21-
let show = Format.asprintf "%a" print
43+
let pp = print
44+
include Printable.SimpleFormat (
45+
struct
46+
type nonrec t = t
47+
let pp = pp
48+
end
49+
)
50+
2251
let compare x y =
2352
(* TODO: implement proper total Lincons1 order *)
2453
String.compare (show x) (show y) (* HACK *)
@@ -45,12 +74,59 @@ struct
4574
|> of_enum
4675
end
4776

77+
module Texpr1 =
78+
struct
79+
include Texpr1
80+
81+
let pp = print
82+
include Printable.SimpleFormat (
83+
struct
84+
type nonrec t = t
85+
let pp = pp
86+
end
87+
)
88+
89+
module Expr =
90+
struct
91+
type t = expr
92+
93+
let pp = print_expr
94+
include Printable.SimpleFormat (
95+
struct
96+
type nonrec t = t
97+
let pp = pp
98+
end
99+
)
100+
end
101+
end
102+
103+
module Tcons1 =
104+
struct
105+
include Tcons1
106+
107+
let pp = print
108+
include Printable.SimpleFormat (
109+
struct
110+
type nonrec t = t
111+
let pp = pp
112+
end
113+
)
114+
end
115+
48116
(** A few code elements for environment changes from functions as remove_vars etc. have been moved to sharedFunctions as they are needed in a similar way inside affineEqualityDomain.
49117
A module that includes various methods used by variable handling operations such as add_vars, remove_vars etc. in apronDomain and affineEqualityDomain. *)
50118
module Environment =
51119
struct
52120
include Environment
53121

122+
let pp: Format.formatter -> Environment.t -> unit = Environment.print
123+
include Printable.SimpleFormat (
124+
struct
125+
type nonrec t = t
126+
let pp = pp
127+
end
128+
)
129+
54130
let compare (x: t) (y: t): int =
55131
(* TODO: implement total Environment order in OCaml *)
56132
failwith "Apron.Environment doesn't have total order" (* https://github.com/antoinemine/apron/issues/99 *)

src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ open Batteries
1111
open GoblintCil
1212
open Pretty
1313
module M = Messages
14-
open Apron
14+
open GobApron
1515
open VectorMatrix
1616

1717
module Mpqf = SharedFunctions.Mpqf
@@ -331,7 +331,7 @@ struct
331331

332332
let simplified_monomials_from_texp (t: t) texp =
333333
let res = simplified_monomials_from_texp t texp in
334-
if M.tracing then M.tracel "from_texp" "%s %s -> %s" (EConj.show @@ snd @@ BatOption.get t.d) (Format.asprintf "%a" Texpr1.print_expr texp)
334+
if M.tracing then M.tracel "from_texp" "%s %a -> %s" (EConj.show @@ snd @@ BatOption.get t.d) Texpr1.Expr.pretty texp
335335
(BatOption.map_default (fun (l,(o,d)) -> List.fold_right (fun (a,x,b) acc -> Printf.sprintf "%s*var_%d/%s + %s" (Z.to_string a) x (Z.to_string b) acc) l ((Z.to_string o)^"/"^(Z.to_string d))) "" res);
336336
res
337337

@@ -361,7 +361,7 @@ struct
361361
else
362362
match simplify_to_ref_and_offset t (Texpr1.to_expr texpr) with
363363
| Some (None, offset, divisor) when Z.equal (Z.rem offset divisor) Z.zero -> let res = Z.div offset divisor in
364-
(if M.tracing then M.tracel "bounds" "min: %s max: %s" (IntOps.BigIntOps.to_string res) (IntOps.BigIntOps.to_string res);
364+
(if M.tracing then M.tracel "bounds" "min: %a max: %a" GobZ.pretty res GobZ.pretty res;
365365
Some res, Some res)
366366
| _ -> None, None
367367

@@ -424,7 +424,7 @@ struct
424424
EConj.show_formatted (show_var varM.env) (snd arr) ^ (to_subscript @@ fst arr)
425425

426426
let pretty () (x:t) = text (show x)
427-
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nequalities\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%s</value>\n</map>\n</value>\n" (XmlUtil.escape (Format.asprintf "%s" (show x) )) (XmlUtil.escape (Format.asprintf "%a" (Environment.print: Format.formatter -> Environment.t -> unit) (x.env)))
427+
let printXml f x = BatPrintf.fprintf f "<value>\n<map>\n<key>\nequalities\n</key>\n<value>\n%s</value>\n<key>\nenv\n</key>\n<value>\n%a</value>\n</map>\n</value>\n" (XmlUtil.escape (show x)) Environment.printXml x.env
428428
let eval_interval ask = Bounds.bound_texpr
429429

430430
let meet_with_one_conj t i (var, o, divi) =
@@ -630,8 +630,8 @@ struct
630630

631631
let assign_exp ask t var exp no_ov =
632632
let res = assign_exp ask t var exp no_ov in
633-
if M.tracing then M.tracel "ops" "assign_exp t:\n %s \n var: %s \n exp: %a\n no_ov: %b -> \n %s"
634-
(show t) (Var.to_string var) d_exp exp (Lazy.force no_ov) (show res) ;
633+
if M.tracing then M.tracel "ops" "assign_exp t:\n %s \n var: %a \n exp: %a\n no_ov: %b -> \n %s"
634+
(show t) Var.pretty var d_exp exp (Lazy.force no_ov) (show res);
635635
res
636636

637637
let assign_var (t: VarManagement.t) v v' =
@@ -640,7 +640,7 @@ struct
640640

641641
let assign_var t v v' =
642642
let res = assign_var t v v' in
643-
if M.tracing then M.tracel "ops" "assign_var t:\n %s \n v: %s \n v': %s\n -> %s" (show t) (Var.to_string v) (Var.to_string v') (show res) ;
643+
if M.tracing then M.tracel "ops" "assign_var t:\n %s \n v: %a \n v': %a\n -> %s" (show t) Var.pretty v Var.pretty v' (show res);
644644
res
645645

646646
(** Parallel assignment of variables.
@@ -693,7 +693,7 @@ struct
693693

694694
let substitute_exp ask t var exp no_ov =
695695
let res = substitute_exp ask t var exp no_ov in
696-
if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %s \n exp: %a \n -> \n %s" (show t) (Var.to_string var) d_exp exp (show res);
696+
if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %a \n exp: %a \n -> \n %s" (show t) Var.pretty var d_exp exp (show res);
697697
res
698698

699699
let substitute_exp ask t var exp no_ov = timing_wrap "substitution" (substitute_exp ask t var exp) no_ov

src/cdomains/apron/sharedFunctions.apron.ml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ let int_of_scalar ?(scalewith=Z.one) ?round (scalar: Scalar.t) =
4040
in
4141
Z_mlgmpidl.z_of_mpzf z
4242
| _ ->
43-
failwith ("int_of_scalar: unsupported: " ^ Scalar.to_string scalar)
43+
failwith ("int_of_scalar: unsupported: " ^ Scalar.show scalar)
4444

4545

4646
module type ConvertArg =
@@ -200,7 +200,7 @@ struct
200200
in
201201
let exp = Cil.constFold false exp in
202202
let res = conv exp in
203-
if M.tracing then M.trace "relation" "texpr1_expr_of_cil_exp: %a -> %s (%b)" d_plainexp exp (Format.asprintf "%a" Texpr1.print_expr res) (Lazy.force no_ov);
203+
if M.tracing then M.trace "relation" "texpr1_expr_of_cil_exp: %a -> %a (%b)" d_plainexp exp Texpr1.Expr.pretty res (Lazy.force no_ov);
204204
res
205205

206206
let texpr1_of_cil_exp ask d env e no_ov =
@@ -267,7 +267,7 @@ struct
267267
else
268268
Const (CInt(i,ILongLong,None)), false
269269
else
270-
(M.warn ~category:Analyzer "Invariant Apron: coefficient is not int: %s" (Scalar.to_string c); raise Unsupported_Linexpr1)
270+
(M.warn ~category:Analyzer "Invariant Apron: coefficient is not int: %a" Scalar.pretty c; raise Unsupported_Linexpr1)
271271
| None -> raise Unsupported_Linexpr1)
272272
| _ -> raise Unsupported_Linexpr1
273273
in
@@ -282,8 +282,8 @@ struct
282282
expr := BinOp(MinusA,!expr,prod,longlong)
283283
else
284284
expr := BinOp(PlusA,!expr,prod,longlong)
285-
| None -> M.warn ~category:Analyzer "Invariant Apron: cannot convert to cil var: %s" (Var.to_string v); raise Unsupported_Linexpr1
286-
| _ -> M.warn ~category:Analyzer "Invariant Apron: cannot convert to cil var in overflow preserving manner: %s" (Var.to_string v); raise Unsupported_Linexpr1
285+
| None -> M.warn ~category:Analyzer "Invariant Apron: cannot convert to cil var: %a" Var.pretty v; raise Unsupported_Linexpr1
286+
| _ -> M.warn ~category:Analyzer "Invariant Apron: cannot convert to cil var in overflow preserving manner: %a" Var.pretty v; raise Unsupported_Linexpr1
287287
in
288288
Linexpr1.iter append_summand linexpr1;
289289
!expr

src/common/domains/printable.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ struct
8888
let to_yojson x = `String (show x)
8989
end
9090

91+
module type Formatable =
92+
sig
93+
type t
94+
val pp: Format.formatter -> t -> unit
95+
end
96+
97+
module SimpleFormat (P: Formatable) =
98+
struct
99+
let show x = GobFormat.asprint P.pp x
100+
let pretty () x = text (show x)
101+
let printXml f x = BatPrintf.fprintf f "<value>\n<data>\n%s\n</data>\n</value>\n" (XmlUtil.escape (show x))
102+
let to_yojson x = `String (show x)
103+
end
104+
91105

92106
module type Name = sig val name: string end
93107
module UnitConf (N: Name) =

src/common/util/gobFormat.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,12 @@ let pp_set_ansi_color_tags ppf =
1919
Format.pp_set_mark_tags ppf true
2020

2121
let pp_print_nothing (ppf: Format.formatter) () = ()
22+
23+
let pp_infinity = 1000000001 (* Exact value not exposed before OCaml 5.2, but use the smallest value permitted by documentation. *)
24+
25+
let pp_set_infinite_geometry = Format.pp_set_geometry ~max_indent:(pp_infinity - 2) ~margin:(pp_infinity - 1)
26+
27+
let asprintf (fmt: ('a, Format.formatter, unit, string) format4): 'a =
28+
Format.asprintf ("%t" ^^ fmt) pp_set_infinite_geometry
29+
30+
let asprint pp x = asprintf "%a" pp x (* eta-expanded to bypass value restriction *)

0 commit comments

Comments
 (0)