Skip to content

Commit 379b3a1

Browse files
authored
Merge pull request #1890 from goblint/list-concat_map-map
Extract `GobLint.cartesian_*map` functions
2 parents 5c469be + 896edda commit 379b3a1

File tree

11 files changed

+48
-44
lines changed

11 files changed

+48
-44
lines changed

src/analyses/extractPthread.ml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,16 +1197,15 @@ module Spec : Analyses.MCPSpec = struct
11971197
| Wait {cond = cond_var; mutex = mutex}, _, _ ->
11981198
let cond_vars = ExprEval.eval_ptr man cond_var in
11991199
let mutex_vars = ExprEval.eval_ptr man mutex in
1200-
let cond_var_action (v, m) =
1200+
let cond_var_action v m =
12011201
let open Action in
12021202
CondVarWait
12031203
{ cond_var_id = Tbls.CondVarIdTbl.get @@ Variable.show v
12041204
; mid = Tbls.MutexMidTbl.get @@ Variable.show m
12051205
}
12061206
in
12071207
add_actions
1208-
@@ List.map cond_var_action
1209-
@@ List.cartesian_product cond_vars mutex_vars
1208+
@@ GobList.cartesian_map cond_var_action cond_vars mutex_vars
12101209
| _ -> man.local
12111210

12121211
let startstate v =

src/arg/myARG.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ struct
278278
let next_opt _ = None
279279
end
280280

281-
let cartesian_concat_paths (ps : cfg_path list) (qs : cfg_path list) : cfg_path list = List.concat_map (fun p -> List.map (fun q -> p @ q) qs) ps
281+
let cartesian_append: cfg_path list -> cfg_path list -> cfg_path list = GobList.cartesian_map (@)
282282

283283
let partition_if_next if_next =
284284
let (if_next_trues, if_next_falses) = List.partition (function
@@ -318,8 +318,8 @@ struct
318318
if Node.equal if_false_next_n if_true_next_false_next_n then
319319
let exp = BinOp (LAnd, e, e2, intType) in
320320
Some [
321-
(Test (exp, true), if_true_next_true_next_n, cartesian_concat_paths if_true_next_ps if_true_next_true_next_ps);
322-
(Test (exp, false), if_true_next_false_next_n, if_false_next_ps @ cartesian_concat_paths if_true_next_ps if_true_next_false_next_ps) (* concat two different path families to same false node *)
321+
(Test (exp, true), if_true_next_true_next_n, cartesian_append if_true_next_ps if_true_next_true_next_ps);
322+
(Test (exp, false), if_true_next_false_next_n, if_false_next_ps @ cartesian_append if_true_next_ps if_true_next_false_next_ps) (* concat two different path families to same false node *)
323323
]
324324
else
325325
None
@@ -330,8 +330,8 @@ struct
330330
if Node.equal if_true_next_n if_false_next_true_next_n then
331331
let exp = BinOp (LOr, e, e2, intType) in
332332
Some [
333-
(Test (exp, true), if_false_next_true_next_n, if_true_next_ps @ cartesian_concat_paths if_false_next_ps if_false_next_true_next_ps); (* concat two different path families to same true node *)
334-
(Test (exp, false), if_false_next_false_next_n, cartesian_concat_paths if_false_next_ps if_false_next_false_next_ps)
333+
(Test (exp, true), if_false_next_true_next_n, if_true_next_ps @ cartesian_append if_false_next_ps if_false_next_true_next_ps); (* concat two different path families to same true node *)
334+
(Test (exp, false), if_false_next_false_next_n, cartesian_append if_false_next_ps if_false_next_false_next_ps)
335335
]
336336
else
337337
None
@@ -366,7 +366,7 @@ struct
366366
| [(Assign (v_true, e_true), if_true_next_next_n, if_true_next_next_ps)], [(Assign (v_false, e_false), if_false_next_next_n, if_false_next_next_ps)] when v_true = v_false && Node.equal if_true_next_next_n if_false_next_next_n ->
367367
let exp = ternary e_cond e_true e_false in
368368
Some [
369-
(Assign (v_true, exp), if_true_next_next_n, cartesian_concat_paths if_true_next_ps if_true_next_next_ps @ cartesian_concat_paths if_false_next_ps if_false_next_next_ps) (* concat two different path families with same variable to same node *)
369+
(Assign (v_true, exp), if_true_next_next_n, cartesian_append if_true_next_ps if_true_next_next_ps @ cartesian_append if_false_next_ps if_false_next_next_ps) (* concat two different path families with same variable to same node *)
370370
]
371371
| _, _ -> None
372372
else

src/cdomain/value/cdomains/int/intervalSetDomain.ml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ struct
114114
let binop (x: t) (y: t) op : t = match x, y with
115115
| [], _ -> []
116116
| _, [] -> []
117-
| _, _ -> canonize @@ List.concat_map op (BatList.cartesian_product x y)
117+
| _, _ -> canonize @@ GobList.cartesian_concat_map op x y
118118

119119

120120
include Std (struct type nonrec t = t let name = name let top_of = top_of let bot_of = bot_of let show = show let equal = equal end)
@@ -185,18 +185,18 @@ struct
185185
let binary_op_with_norm op (ik:ikind) (x: t) (y: t) : t*overflow_info = match x, y with
186186
| [], _ -> ([],{overflow=false; underflow=false})
187187
| _, [] -> ([],{overflow=false; underflow=false})
188-
| _, _ -> norm_intvs ik @@ List.map (fun (x,y) -> op x y) (BatList.cartesian_product x y)
188+
| _, _ -> norm_intvs ik @@ GobList.cartesian_map op x y
189189

190190
let binary_op_concat_with_norm op (ik:ikind) (x: t) (y: t) : t*overflow_info = match x, y with
191191
| [], _ -> ([],{overflow=false; underflow=false})
192192
| _, [] -> ([],{overflow=false; underflow=false})
193-
| _, _ -> norm_intvs ik @@ List.concat_map (fun (x,y) -> op x y) (BatList.cartesian_product x y)
193+
| _, _ -> norm_intvs ik @@ GobList.cartesian_concat_map op x y
194194

195195
let binary_op_with_ovc (x: t) (y: t) op : t*overflow_info = match x, y with
196196
| [], _ -> ([],{overflow=false; underflow=false})
197197
| _, [] -> ([],{overflow=false; underflow=false})
198198
| _, _ ->
199-
let res = List.map op (BatList.cartesian_product x y) in
199+
let res = GobList.cartesian_map op x y in
200200
let intvs = List.concat_map fst res in
201201
let underflow = List.exists (fun (_,{underflow; _}) -> underflow) res in
202202
let overflow = List.exists (fun (_,{overflow; _}) -> underflow) res in
@@ -307,7 +307,7 @@ struct
307307
let interval_to_int i = Interval.to_int (Some i)
308308
let interval_to_bool i = Interval.to_bool (Some i)
309309

310-
let log f ik (i1, i2) =
310+
let log f ik i1 i2 =
311311
match (interval_to_bool i1, interval_to_bool i2) with
312312
| Some x, Some y -> of_bool ik (f x y)
313313
| _ -> top_of ik
@@ -319,7 +319,7 @@ struct
319319
| _ -> top_of ik
320320

321321

322-
let bitcomp f ik (i1, i2) =
322+
let bitcomp f ik i1 i2 =
323323
match (interval_to_int i1, interval_to_int i2) with
324324
| Some x, Some y -> (try of_int ik (f x y) with Division_by_zero | Invalid_argument _ -> (top_of ik,{overflow=false; underflow=false}))
325325
| _, _ -> (top_of ik,{overflow=false; underflow=false})
@@ -340,7 +340,7 @@ struct
340340
Ints_t.sub (Ints_t.shift_left Ints_t.one (Z.numbits @@ Z.abs @@ Ints_t.to_bigint x)) Ints_t.one
341341

342342
(* TODO: deduplicate with IntervalDomain? *)
343-
let interval_logand ik (i1, i2) =
343+
let interval_logand ik i1 i2 =
344344
match bit Ints_t.logand ik (i1, i2) with
345345
| result when not (is_top_of ik result) -> result
346346
| _ ->
@@ -361,7 +361,7 @@ struct
361361
let logand ik x y = binop x y (interval_logand ik)
362362

363363
(* TODO: deduplicate with IntervalDomain? *)
364-
let interval_logor ik (i1, i2) =
364+
let interval_logor ik i1 i2 =
365365
match bit Ints_t.logor ik (i1, i2) with
366366
| result when not (is_top_of ik result) -> result
367367
| _ ->
@@ -381,7 +381,7 @@ struct
381381
let logor ik x y = binop x y (interval_logor ik)
382382

383383
(* TODO: deduplicate with IntervalDomain? *)
384-
let interval_logxor ik (i1, i2) =
384+
let interval_logxor ik i1 i2 =
385385
match bit Ints_t.logxor ik (i1, i2) with
386386
| result when not (is_top_of ik result) && not (is_bot result) -> result (* TODO: why bot check here, but not elsewhere? *)
387387
| _ ->
@@ -426,7 +426,7 @@ struct
426426
binary_op_with_ovc x y interval_shiftleft
427427

428428
(* TODO: deduplicate with IntervalDomain? *)
429-
let interval_shiftright ik (i1, i2) =
429+
let interval_shiftright ik i1 i2 =
430430
match interval_to_int i1, interval_to_int i2 with
431431
| Some x, Some y -> (try of_int ik (Ints_t.shift_right x (Ints_t.to_int y)) with Division_by_zero | Invalid_argument _ -> (top_of ik, {overflow=false; underflow=false}))
432432
| _, _ ->
@@ -472,7 +472,7 @@ struct
472472
binary_op_concat_with_norm interval_div ik x y
473473

474474
let rem ik x y =
475-
let interval_rem (x, y) =
475+
let interval_rem x y =
476476
if Interval.is_top_of ik (Some x) && Interval.is_top_of ik (Some y) then
477477
top_of ik
478478
else

src/cdomain/value/cdomains/structDomain.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ struct
177177
in
178178
let x_list = HS.elements x in
179179
let y_list = HS.elements y in
180-
List.concat_map (fun xss -> List.map (fun yss -> (xss, yss)) y_list) x_list
180+
(* TODO: GobList.cartesian_filter_map? or just Seq? *)
181+
BatList.cartesian_product x_list y_list
181182
|> List.filter (fun (ssx, ssy) -> maps_overlap ssx ssy)
182183
|> List.map (fun (ssx, ssy) -> f ssx ssy)
183184
|> HS.of_list
@@ -195,7 +196,7 @@ struct
195196
let widen_with_fct f =
196197
let product_widen op a b = (* assumes b to be bigger than a *) (* from HS.product_widen *)
197198
let xs,ys = HS.elements a, HS.elements b in
198-
List.concat_map (fun x -> List.map (fun y -> op x y) ys) xs |> fun x -> HS.of_list (List.append x ys)
199+
GobList.cartesian_map op xs ys |> fun x -> HS.of_list (List.append x ys)
199200
in
200201
product_widen (fun x y -> if SS.leq x y then (SS.widen_with_fct f) x y else SS.bot ())
201202

@@ -367,7 +368,7 @@ struct
367368
let ((sx, kx), (sy, ky)) = (x, y) in
368369
let x_list = HS.elements sx in
369370
let y_list = HS.elements sy in
370-
let s = List.concat_map (fun xss -> List.map (fun yss -> (xss, yss)) y_list) x_list
371+
let s = BatList.cartesian_product x_list y_list (* TODO: GobList.cartesian_filter_map? or just Seq? *)
371372
|> List.filter (fun (ssx, ssy) -> maps_overlap ssx ssy)
372373
|> List.map (fun (ssx, ssy) -> f ssx ssy)
373374
|> HS.of_list
@@ -395,7 +396,7 @@ struct
395396
let widen_with_fct f (x, kx) (y, ky) =
396397
let product_widen op a b = (* assumes b to be bigger than a *) (* from HS.product_widen *)
397398
let xs,ys = HS.elements a, HS.elements b in
398-
List.concat_map (fun x -> List.map (op x) ys) xs |> fun x -> HS.of_list (List.append x ys)
399+
GobList.cartesian_map op xs ys |> fun x -> HS.of_list (List.append x ys)
399400
in
400401
let s = product_widen (fun x y -> if SS.leq x y then (SS.widen_with_fct f) x y else SS.bot ()) x y
401402
in reduce_key (s, take_some_key kx ky s)

src/cdomains/congruenceClosure.ml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,12 @@ module Disequalities = struct
209209
let arg = List.fold_left do_bindings TMap.empty clist in
210210
(uf, cmap, arg)
211211

212+
(* TODO: GobList.cartesian_fold_left? *)
212213
let fold_left2 f acc l1 l2 =
213214
List.fold_left (
214215
fun acc x -> List.fold_left (
215216
fun acc y -> f acc x y) acc l2) acc l1
216217

217-
let map2 f l1 l2 =
218-
let map_f x = List.map (f x) l2 in
219-
List.concat_map map_f l1
220-
221218
let map_find_opt (v,r) map =
222219
let inner_map = TMap.find_opt v map in
223220
BatOption.map_default (ZMap.find_opt r) None inner_map
@@ -382,10 +379,10 @@ module Disequalities = struct
382379
let comp_closure (r1,r2,z) =
383380
let eq_class1 = LMap.comp_t_cmap_repr cmap r1 in
384381
let eq_class2 = LMap.comp_t_cmap_repr cmap r2 in
385-
let to_diseq ((z1, nt1), (z2, nt2)) =
382+
let to_diseq (z1, nt1) (z2, nt2) =
386383
(nt1, nt2, Z.(-z2+z+z1))
387384
in
388-
List.map to_diseq (BatList.cartesian_product eq_class1 eq_class2)
385+
GobList.cartesian_map to_diseq eq_class1 eq_class2
389386
in
390387
List.concat_map comp_closure diseqs
391388
end

src/domain/hoareDomain.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ struct
199199
let reduce s = filter (fun x -> not (exists (le x) s)) s
200200
let product_bot op a b =
201201
let a,b = elements a, elements b in
202-
List.concat_map (fun x -> List.map (fun y -> op x y) b) a |> fun x -> reduce (of_list x)
202+
GobList.cartesian_map op a b |> fun x -> reduce (of_list x)
203203
let product_widen op a b = (* assumes b to be bigger than a *)
204204
let xs,ys = elements a, elements b in
205-
List.concat_map (fun x -> List.map (fun y -> op x y) ys) xs |> fun x -> reduce (union b (of_list x))
205+
GobList.cartesian_map op xs ys |> fun x -> reduce (union b (of_list x))
206206
let widen = product_widen (fun x y -> if B.leq x y then B.widen x y else B.bot ())
207207
let narrow = product_bot (fun x y -> if B.leq y x then B.narrow x y else x)
208208

@@ -302,18 +302,18 @@ struct
302302
maximals
303303
let product_bot op op2 a b =
304304
let a,b = elements a, elements b in
305-
List.concat_map (fun (x,xr) -> List.map (fun (y,yr) -> (op x y, op2 xr yr)) b) a |> fun x -> reduce (of_list x)
305+
GobList.cartesian_map (fun (x,xr) (y,yr) -> (op x y, op2 xr yr)) a b |> fun x -> reduce (of_list x)
306306
let product_bot2 op2 a b =
307307
let a,b = elements a, elements b in
308-
List.concat_map (fun (x,xr) -> List.map (fun (y,yr) -> op2 (x, xr) (y, yr)) b) a |> fun x -> reduce (of_list x)
308+
GobList.cartesian_map op2 a b |> fun x -> reduce (of_list x)
309309
(* why are type annotations needed for product_widen? *)
310310
(* TODO: unused now *)
311311
let product_widen op op2 (a:t) (b:t): t = (* assumes b to be bigger than a *)
312312
let xs,ys = elements a, elements b in
313-
List.concat_map (fun (x,xr) -> List.map (fun (y,yr) -> (op x y, op2 xr yr)) ys) xs |> fun x -> reduce (join b (of_list x)) (* join instead of union because R is HoareDomain.Set for witness generation *)
313+
GobList.cartesian_map (fun (x,xr) (y,yr) -> (op x y, op2 xr yr)) xs ys |> fun x -> reduce (join b (of_list x)) (* join instead of union because R is HoareDomain.Set for witness generation *)
314314
let product_widen2 op2 (a:t) (b:t): t = (* assumes b to be bigger than a *)
315315
let xs,ys = elements a, elements b in
316-
List.concat_map (fun (x,xr) -> List.map (fun (y,yr) -> op2 (x, xr) (y, yr)) ys) xs |> fun x -> reduce (join b (of_list x)) (* join instead of union because R is HoareDomain.Set for witness generation *)
316+
GobList.cartesian_map op2 xs ys |> fun x -> reduce (join b (of_list x)) (* join instead of union because R is HoareDomain.Set for witness generation *)
317317
let join a b = join a b |> reduce
318318
let meet = product_bot SpecD.meet R.inter
319319
(* let narrow = product_bot (fun x y -> if SpecD.leq y x then SpecD.narrow x y else x) R.narrow *)
@@ -368,7 +368,7 @@ struct
368368
(* TODO: move to Set above? *)
369369
let product_widen (op: elt -> elt -> elt option) a b = (* assumes b to be bigger than a *)
370370
let xs,ys = elements a, elements b in
371-
List.concat_map (fun x -> List.filter_map (fun y -> op x y) ys) xs |> fun x -> join b (of_list x)
371+
GobList.cartesian_filter_map op xs ys |> fun x -> join b (of_list x)
372372
let widen = product_widen (fun x y -> if E.leq x y then Some (E.widen x y) else None)
373373

374374
(* above widen is actually extrapolation operator, so define connector-based widening instead *)

src/domains/intDomainProperties.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ struct
9292
let name () = "integerset"
9393

9494
let lift1 = map
95-
let lift2 f x y = BatList.cartesian_product (elements x) (elements y) |> List.map (Batteries.uncurry f) |> of_list
95+
let lift2 f x y = GobList.cartesian_map f (elements x) (elements y) |> of_list
9696

9797
let neg = lift1 Base.neg
9898
let add = lift2 Base.add

src/util/std/gobList.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ let until_last_with (pred: 'a -> bool) (xs: 'a list) =
5555
in
5656
until_last_helper [] [] xs
5757

58+
let cartesian_map f l1 l2 =
59+
List.concat_map (fun x -> List.map (f x) l2) l1
60+
61+
let cartesian_filter_map f l1 l2 =
62+
List.concat_map (fun x -> List.filter_map (f x) l2) l1
63+
64+
let cartesian_concat_map f l1 l2 =
65+
List.concat_map (fun x -> List.concat_map (f x) l2) l1
66+
5867

5968
(** Open this to use applicative functor/monad syntax for {!list}. *)
6069
module Syntax =

tests/unit/cdomains/intDomainTest.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,6 @@ struct
483483
assert_bool "-5 ?= not (4 | 12)" (I.equal_to (of_int (-5)) (I.lognot ik b12) = `Top)
484484

485485
let of_list ik is = List.fold_left (fun acc x -> I.join ik acc (I.of_int ik x)) (I.bot ()) is
486-
let cart_op op a b = List.map (BatTuple.Tuple2.uncurry op) (BatList.cartesian_product a b)
487486

488487
let precision ik = snd @@ IntDomain.Size.bits ik
489488
let over_precision ik = Int.succ @@ precision ik
@@ -546,7 +545,7 @@ struct
546545
Test.make ~name:name ~print:shift_test_printer
547546
test_case_gen
548547
(fun (a,b) ->
549-
let expected_subset = cart_op c_op a b |> of_list ik in
548+
let expected_subset = GobList.cartesian_map c_op a b |> of_list ik in
550549
let result = a_op ik (of_list ik a) (of_list ik b) in
551550
I.leq expected_subset result
552551
)

tests/unit/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
)
1313
(preprocess (pps ppx_deriving.std ppx_deriving_hash ppx_deriving_yojson))
14-
(flags :standard -linkall))
14+
(flags :standard -open Goblint_std -linkall))
1515

1616
(env
1717
(dev

0 commit comments

Comments
 (0)