Source file maybe_bound.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
open! Import
type interval_comparison =
| Below_lower_bound
| In_range
| Above_upper_bound
[@@deriving sexp ~stackify, sexp_grammar, compare ~localize, hash]
[%%template
[@@@kind.default k = base_or_null]
type ('a : k) t =
| Incl of 'a
| Excl of 'a
| Unbounded
[@@deriving sexp ~stackify, sexp_grammar, globalize]
let all (all_of_a : ('a List.t[@kind k])) : ('a t[@kind k]) list =
(List.map [@kind k value_or_null]) all_of_a ~f:(fun a : ('a t[@kind k]) -> Incl a)
@ (List.map [@kind k value_or_null]) all_of_a ~f:(fun a : ('a t[@kind k]) -> Excl a)
@ [ (Unbounded : ('a t[@kind k])) ]
;;
let map (t : (_ t[@kind k])) ~f : (_ t[@kind k]) =
match t with
| Incl incl -> Incl (f incl)
| Excl excl -> Excl (f excl)
| Unbounded -> Unbounded
;;
let is_lower_bound (t : (_ t[@kind k])) ~of_:a ~compare =
match t with
| Incl incl -> compare incl a <= 0
| Excl excl -> compare excl a < 0
| Unbounded -> true
;;
let is_upper_bound (t : (_ t[@kind k])) ~of_:a ~compare =
match t with
| Incl incl -> compare a incl <= 0
| Excl excl -> compare a excl < 0
| Unbounded -> true
;;
let bounds_crossed ~(lower : ('a t[@kind k])) ~(upper : ('a t[@kind k])) ~compare =
match lower with
| Unbounded -> false
| Incl lower | Excl lower ->
(match upper with
| Unbounded -> false
| Incl upper | Excl upper -> compare lower upper > 0)
;;
let check_interval_exn ~lower ~upper ~compare =
if (bounds_crossed [@kind k]) ~lower ~upper ~compare
then failwith "Maybe_bound.compare_to_interval_exn: lower bound > upper bound"
;;
let compare_to_interval_exn ~lower ~upper a ~compare =
(check_interval_exn [@kind k]) ~lower ~upper ~compare;
if not ((is_lower_bound [@kind k]) lower ~of_:a ~compare)
then Below_lower_bound
else if not ((is_upper_bound [@kind k]) upper ~of_:a ~compare)
then Above_upper_bound
else In_range
;;
let interval_contains_exn ~lower ~upper a ~compare =
match (compare_to_interval_exn [@kind k]) ~lower ~upper a ~compare with
| In_range -> true
| Below_lower_bound | Above_upper_bound -> false
;;]