Skip to content

Commit 729eb71

Browse files
authored
Merge pull request #2002 from goblint/patricia-tree
Use Codex patricia-tree library for base map domain
2 parents 40cae05 + e580b64 commit 729eb71

11 files changed

Lines changed: 220 additions & 98 deletions

File tree

dune-project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Goblint includes analyses for assertions, overflows, deadlocks, etc and can be e
3939
(ocaml (>= 4.14))
4040
(goblint-cil (>= 2.0.9)) ; TODO no way to define as pin-depends? Used goblint.opam.template to add it for now. https://github.com/ocaml/dune/issues/3231. Alternatively, removing this line and adding cil as a git submodule and `(vendored_dirs cil)` as ./dune also works. This way, no more need to reinstall the pinned cil opam package on changes. However, then cil is cleaned and has to be rebuild together with goblint.
4141
(batteries (>= 3.9.0))
42+
(patricia-tree (>= 0.13.0))
4243
(zarith (>= 1.12))
4344
(yojson (and (>= 2.0.0) (< 3))) ; json-data-encoding has incompatible yojson representation for yojson 3
4445
(qcheck-core (>= 0.19))

goblint.opam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ depends: [
4141
"ocaml" {>= "4.14"}
4242
"goblint-cil" {>= "2.0.9"}
4343
"batteries" {>= "3.9.0"}
44+
"patricia-tree" {>= "0.13.0"}
4445
"zarith" {>= "1.12"}
4546
"yojson" {>= "2.0.0" & < "3"}
4647
"qcheck-core" {>= "0.19"}

goblint.opam.locked

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ depends: [
8888
"odoc-parser" {= "3.0.0" & with-doc}
8989
"ordering" {= "3.19.1"}
9090
"ounit2" {= "2.2.7" & with-test}
91+
"patricia-tree" {= "0.13.0"}
9192
"pp" {= "2.0.0"}
9293
"ppx_blob" {= "0.9.0"}
9394
"ppx_derivers" {= "1.2.1"}

src/analyses/basePriv.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ struct
442442
(* Additionally filter get_m in case it contains variables it no longer protects. *)
443443
let is_in_Gm x _ = is_protected_by ask m x in
444444
let get_m = CPA.filter is_in_Gm get_m in
445-
let long_meet m1 m2 = CPA.long_map2 VD.meet m1 m2 in
445+
let long_meet m1 m2 = CPA.nonidempotent_union VD.meet m1 m2 in (* TODO: idempotent_union if not using int domain refinement *)
446446
let meet = long_meet st.cpa get_m in
447447
if M.tracing then M.tracel "priv" "LOCK %a:\n get_m: %a\n meet: %a" LockDomain.MustLock.pretty m CPA.pretty get_m CPA.pretty meet;
448448
{st with cpa = meet}
@@ -508,7 +508,7 @@ struct
508508
| VarQuery.Global g -> vf (V.global g)
509509
| _ -> ()
510510

511-
let long_meet m1 m2 = CPA.long_map2 VD.meet m1 m2
511+
let long_meet m1 m2 = CPA.nonidempotent_union VD.meet m1 m2 (* TODO: idempotent_union if not using int domain refinement *)
512512

513513
let update_if_mem var value m =
514514
if CPA.mem var m then

src/cdomains/baseDomain.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module VD = ValueDomain.Compound
55

66
module CPA =
77
struct
8-
module M0 = MapDomain.MapBot (Basetype.Variables) (VD)
8+
module M0 = MapDomain.PatriciaMapBot (Basetype.Variables) (VD)
99
module M =
1010
struct
1111
include M0

src/common/util/cilType.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ struct
365365
let equal x y = x.vid = y.vid
366366
let compare x y = Stdlib.compare x.vid y.vid
367367
let hash x = x.vid
368+
let tag x = x.vid
368369

369370
(* Output *)
370371
let show x = x.vname

src/domain/disjointDomain.ml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -572,11 +572,17 @@ struct
572572
let mapi f m = M.map (fun b ->
573573
B.mapi f b
574574
) m
575-
let long_map2 f m1 m2 = M.long_map2 (fun b1 b2 ->
576-
B.long_map2 f b1 b2
575+
let idempotent_union f m1 m2 = M.idempotent_union (fun b1 b2 ->
576+
B.idempotent_union f b1 b2
577577
) m1 m2
578-
let map2 f m1 m2 = M.map2 (fun b1 b2 ->
579-
B.map2 f b1 b2
578+
let nonidempotent_union f m1 m2 = M.nonidempotent_union (fun b1 b2 ->
579+
B.nonidempotent_union f b1 b2
580+
) m1 m2
581+
let idempotent_inter f m1 m2 = M.idempotent_inter (fun b1 b2 ->
582+
B.idempotent_inter f b1 b2
583+
) m1 m2
584+
let nonidempotent_inter f m1 m2 = M.nonidempotent_inter (fun b1 b2 ->
585+
B.nonidempotent_inter f b1 b2
580586
) m1 m2
581587
let merge f m1 m2 = failwith "ProjectiveMap.merge" (* TODO: ? *)
582588

@@ -627,6 +633,7 @@ struct
627633

628634
let filter p m = failwith "ProjectiveMap.filter"
629635

636+
let reflexive_subset_domain_for_all2 _ _ _ = failwith "ProjectiveMap.reflexive_subset_domain_for_all2"
630637
let leq_with_fct _ _ _ = failwith "ProjectiveMap.leq_with_fct"
631638
let join_with_fct _ _ _ = failwith "ProjectiveMap.join_with_fct"
632639
let widen_with_fct _ _ _ = failwith "ProjectiveMap.widen_with_fct"
@@ -735,28 +742,29 @@ struct
735742
let mapi f m = S.map (fun b ->
736743
B.mapi f b
737744
) m
738-
let long_map2 f s1 s2 =
745+
let nonidempotent_union f s1 s2 =
739746
let f b2 (s1, acc) =
740747
let e2 = fst (B.choose b2) in
741748
let (s1_match, s1_rest) = S.partition (fun b1 -> C.cong (fst (B.choose b1)) e2) s1 in
742749
let b' = match S.choose s1_match with
743750
| b1 ->
744751
assert (S.cardinal s1_match = 1);
745-
B.long_map2 f b1 b2
752+
B.nonidempotent_union f b1 b2
746753
| exception Not_found -> b2
747754
in
748755
(s1_rest, S.add b' acc)
749756
in
750757
let (s1', acc) = S.fold f s2 (s1, empty ()) in
751758
S.union s1' acc
752-
let map2 f s1 s2 =
759+
let idempotent_union _ _ _ = failwith "PairwiseMap.idempotent_union" (* TODO: ? *)
760+
let nonidempotent_inter f s1 s2 =
753761
let f b2 (s1, acc) =
754762
let e2 = fst (B.choose b2) in
755763
let (s1_match, s1_rest) = S.partition (fun b1 -> C.cong (fst (B.choose b1)) e2) s1 in
756764
let acc' = match S.choose s1_match with
757765
| b1 ->
758766
assert (S.cardinal s1_match = 1);
759-
begin match B.map2 f b1 b2 with
767+
begin match B.nonidempotent_inter f b1 b2 with
760768
| b' when B.is_bot b' ->
761769
acc (* remove bot bucket to preserve invariant *)
762770
| exception Lattice.BotValue ->
@@ -769,6 +777,7 @@ struct
769777
(s1_rest, acc')
770778
in
771779
snd (S.fold f s2 (s1, S.empty ()))
780+
let idempotent_inter _ _ _ = failwith "PairwiseMap.idempotent_inter" (* TODO: ? *)
772781
let merge f m1 m2 = failwith "PairwiseMap.merge" (* TODO: ? *)
773782

774783
let leq s1 s2 =
@@ -885,6 +894,7 @@ struct
885894

886895
let filter p s = failwith "PairwiseMap.filter"
887896

897+
let reflexive_subset_domain_for_all2 _ _ _ = failwith "PairwiseMap.reflexive_subset_domain_for_all2"
888898
let leq_with_fct _ _ _ = failwith "PairwiseMap.leq_with_fct"
889899
let join_with_fct _ _ _ = failwith "PairwiseMap.join_with_fct"
890900
let widen_with_fct _ _ _ = failwith "PairwiseMap.widen_with_fct"

src/domain/dune

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
batteries.unthreaded
99
goblint_std
1010
goblint_common
11-
goblint-cil)
11+
goblint-cil
12+
patricia-tree)
1213
(flags :standard -open Goblint_std)
1314
(preprocess
1415
(pps

src/domain/hoareDomain.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ struct
277277

278278
let elements (s: t): (key * R.t) list = bindings s
279279
let of_list (l: (key * R.t) list): t = List.fold_left (fun acc (x, r) -> add x r acc) (empty ()) l
280-
let union = long_map2 R.union
280+
let union = idempotent_union R.union
281281

282282

283283
(* copied & modified from SetDomain.Hoare_NoTop *)

0 commit comments

Comments
 (0)