forked from semgrep/semgrep
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new libs/commons/Ord.ml, extracted from Common.ml (semgrep#9892)
Part of the set of PRs to reduce the size of Common.ml test plan: make make test
- Loading branch information
Yoann Padioleau
authored
Mar 6, 2024
1 parent
9f07bad
commit dc1477e
Showing
9 changed files
with
82 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
type t = Less | Equal | Greater | ||
|
||
(* We use this to be able to factorize our code for binary search, by | ||
instantiating our code against different kinds of containers and | ||
element types. | ||
In particular, this is an improvement over functorization, because the | ||
type of Bigarray.Array1.t is actually triply-polymorphic. By making the | ||
container type itself unspecified, we are able to abstract over even | ||
multiply-polymorphic containers. | ||
*) | ||
type ('elt, 'container) binary_searchable = { | ||
length : 'container -> int; | ||
get : 'container -> int -> 'elt; | ||
} | ||
|
||
let create_binary_search (searchable : ('elt, 'container) binary_searchable) = | ||
let binary_search ~f arr = | ||
let arr_lo = 0 in | ||
let arr_hi = searchable.length arr in | ||
|
||
let rec aux lo hi = | ||
if Int.equal lo hi then Error lo | ||
else | ||
let mid = (lo + hi) / 2 in | ||
match f mid (searchable.get arr mid) with | ||
| Equal -> Ok (mid, searchable.get arr mid) | ||
| Less -> aux lo mid | ||
| Greater -> aux (mid + 1) hi | ||
in | ||
aux arr_lo arr_hi | ||
in | ||
binary_search | ||
|
||
let arr_searchable = { length = Array.length; get = Array.get } | ||
|
||
let bigarr1_searchable = | ||
{ length = Bigarray.Array1.dim; get = Bigarray.Array1.get } | ||
|
||
let binary_search_arr ~f x = create_binary_search arr_searchable ~f x | ||
let binary_search_bigarr1 ~f x = create_binary_search bigarr1_searchable ~f x | ||
|
||
let to_comparison f x y = | ||
let res = f x y in | ||
if res < 0 then Less else if res > 0 then Greater else Equal | ||
|
||
let cmp target _i x = to_comparison Int.compare target x | ||
let%test _ = binary_search_arr ~f:(cmp 1) [| 1; 2; 4; 5 |] = Ok (0, 1) | ||
let%test _ = binary_search_arr ~f:(cmp 2) [| 1; 2; 4; 5 |] = Ok (1, 2) | ||
let%test _ = binary_search_arr ~f:(cmp 5) [| 1; 2; 4; 5 |] = Ok (3, 5) | ||
|
||
(* out of bounds or not in the array returns the position it should be inserted at *) | ||
let%test _ = binary_search_arr ~f:(cmp 6) [| 1; 2; 4; 5 |] = Error 4 | ||
let%test _ = binary_search_arr ~f:(cmp 3) [| 1; 2; 4; 5 |] = Error 2 | ||
let%test _ = binary_search_arr ~f:(cmp 0) [| 1; 2; 4; 5 |] = Error 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
type t = Less | Equal | Greater | ||
|
||
val binary_search_arr : f:(int -> 'a -> t) -> 'a array -> (int * 'a, int) result | ||
(** [binary_search_arr f A] returns Ok (idx, x) if the element x can be found | ||
at idx x, according to comparison function f. | ||
Otherwise, it returns Error idx, where idx is the index that the element | ||
must be inserted at, if it were to be in the array. | ||
For instance, when searching for 2 in [|0, 3|], we get Error 1. | ||
Inserting at the beginning is Error 0, and at the end is Error 2. | ||
*) | ||
|
||
val binary_search_bigarr1 : | ||
f:(int -> 'a -> t) -> ('a, 'b, 'c) Bigarray.Array1.t -> (int * 'a, int) result | ||
|
||
val to_comparison : ('a -> 'a -> int) -> 'a -> 'a -> t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters