Skip to content

Commit 167a5e1

Browse files
authored
fixes a bug in the KB update function, adds new functions (#1439)
The bug was a typo in the merge function that was manifested with the `Failure "types are not equal"` exception. The new functions, are - `proceed ~until` as a dual to `guard`; - `Value.is_empty` that returns `true` if a value is empty - `Value.has` that checks if the specific property of the value is empty The change also ensures that empty properties are not stored in values (which also makes the `Value.is_empty` implementation trivial).
1 parent 772d4a6 commit 167a5e1

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

lib/knowledge/bap_knowledge.ml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,7 +1835,7 @@ module Dict = struct
18351835
| ILT -> Ok (make3 ka a kb b kc c)
18361836
| IGT -> Ok (make3 kb b kc c ka a)
18371837
| ILE -> Ok (make2 ka (app m ka kb b a) kc c)
1838-
| IGE -> Ok (make2 kb b ka (app m ka kb b a))
1838+
| IGE -> Ok (make2 kb b ka (app m ka kc c a))
18391839
| INC -> Ok (make3 kb b ka a kc c)
18401840
end
18411841
| T2 (ka, a, kb, b), T1 (kc, c) ->
@@ -1853,7 +1853,7 @@ module Dict = struct
18531853
| ILE -> Ok (make3 ka (app m ka kb b a) kc c kd d)
18541854
| IGE -> Ok (make3 kb b kc c ka (app m ka kd d a))
18551855
| INC -> match Key.compare ka kc with
1856-
| 0 -> Ok (make3 kb b kc (app m kc kd d c) kd d)
1856+
| 0 -> Ok (make3 kb b kc (app m kc ka a c) kd d)
18571857
| 1 -> Ok (make4 kb b kc c ka a kd d)
18581858
| _ -> Ok (make4 kb b ka a kc c kd d)
18591859
end
@@ -1934,6 +1934,7 @@ module Record = struct
19341934
Hashtbl.create (module Uid)
19351935

19361936
let empty = Dict.empty
1937+
let is_empty = Dict.is_empty
19371938

19381939
let uid = Key.uid
19391940
let domain k = Hashtbl.find_exn vtables (uid k)
@@ -2294,18 +2295,25 @@ module Knowledge = struct
22942295
let empty cls =
22952296
{cls; data=Record.empty; time = next_second ()}
22962297

2298+
let is_empty {data} = Record.is_empty data
2299+
22972300
let order {data=x} {data=y} = Record.order x y
22982301

22992302
let refine {data; cls; time} s=
23002303
{data; time; cls = Class.refine cls s}
23012304

23022305
let cls {cls} = cls
23032306
let create cls data = {cls; data; time = next_second ()}
2304-
let put {Slot.key} v x = {
2305-
v with data = Record.put key v.data x;
2306-
time = next_second ()
2307-
}
2307+
let put {Slot.key; dom} v x =
2308+
if Domain.is_empty dom x then v
2309+
else {
2310+
v with data = Record.put key v.data x;
2311+
time = next_second ()
2312+
}
23082313
let get {Slot.key; dom} {data} = Record.get key dom data
2314+
let has {Slot.key; dom} {data} =
2315+
not @@ Domain.is_empty dom @@ Record.get key dom data
2316+
23092317
let strip
23102318
: type a b. (a value, b value) Type_equal.t -> (a,b) Type_equal.t =
23112319
fun T -> T
@@ -2669,6 +2677,7 @@ module Knowledge = struct
26692677
let guard cnd = if not cnd
26702678
then reject ()
26712679
else Knowledge.return ()
2680+
let proceed ~unless:cnd = guard (not cnd)
26722681
let on cnd yes = if cnd
26732682
then yes
26742683
else reject ()

lib/knowledge/bap_knowledge.mli

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,16 @@ module Knowledge : sig
329329
val guard : bool -> unit t
330330

331331

332+
(** [proceed ~unless:cnd] rejects the computation unless [cnd] holds.
333+
334+
Dual to {!guard}, this operator rejects a promise (or any other
335+
computation in the scope of the {!with_empty} operator) unless
336+
the [cnd] holds, i.e., it is the same as [guard (not cnd)].
337+
338+
@since 2.5.0 *)
339+
val proceed : unless:bool -> unit t
340+
341+
332342
(** [on cnd x] evaluates to [x] if [cnd], otherwise rejects.
333343
334344
When in the scope of the [with_empty] function, e.g., in a
@@ -886,6 +896,13 @@ module Knowledge : sig
886896
val empty : ('a,'b) cls -> ('a,'b) cls value
887897

888898

899+
(** [is_empty x] iff all properties of [x] are empty.
900+
901+
@since 2.5.0
902+
*)
903+
val is_empty : _ value -> bool
904+
905+
889906
(** [order x y] orders [x] and [y] by their information content. *)
890907
val order : 'a value -> 'a value -> Order.partial
891908

@@ -941,6 +958,12 @@ module Knowledge : sig
941958
(** [put p v x] sets a value of the property [p]. *)
942959
val put : ('k,'p) slot -> ('k,'s) cls value -> 'p -> ('k,'s) cls value
943960

961+
(** [has p x] if property [p] of [x] is not empty.
962+
963+
@since 2.5.0
964+
*)
965+
val has : ('k,'p) slot -> ('k,'s) cls value -> bool
966+
944967
(** [refine v s] refines the sort of [v] to [s].
945968
946969
Since, this function doesn't change the information stored in

0 commit comments

Comments
 (0)