Source file cset.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
type c = int
type t = (c * c) list
let rec union l l' =
match l, l' with
_, [] -> l
| [], _ -> l'
| (c1, c2)::r, (c1', c2')::r' ->
if c2 + 1 < c1' then
(c1, c2)::union r l'
else if c2' + 1 < c1 then
(c1', c2')::union l r'
else if c2 < c2' then
union r ((min c1 c1', c2')::r')
else
union ((min c1 c1', c2)::r) r'
let rec inter l l' =
match l, l' with
_, [] -> []
| [], _ -> []
| (c1, c2)::r, (c1', c2')::r' ->
if c2 < c1' then
inter r l'
else if c2' < c1 then
inter l r'
else if c2 < c2' then
(max c1 c1', c2)::inter r l'
else
(max c1 c1', c2')::inter l r'
let rec diff l l' =
match l, l' with
_, [] -> l
| [], _ -> []
| (c1, c2)::r, (c1', c2')::r' ->
if c2 < c1' then
(c1, c2)::diff r l'
else if c2' < c1 then
diff l r'
else
let r'' = if c2' < c2 then (c2' + 1, c2) :: r else r in
if c1 < c1' then
(c1, c1' - 1)::diff r'' r'
else
diff r'' r'
let single c = [c, c]
let add c l = union (single c) l
let seq c c' = if c <= c' then [c, c'] else [c', c]
let rec offset o l =
match l with
[] -> []
| (c1, c2) :: r -> (c1 + o, c2 + o) :: offset o r
let empty = []
let rec mem (c : int) s =
match s with
[] -> false
| (c1, c2) :: rem -> if c <= c2 then c >= c1 else mem c rem
type hash = int
let rec hash_rec = function
| [] -> 0
| (i, j)::r -> i + 13 * j + 257 * hash_rec r
let hash l = (hash_rec l) land 0x3FFFFFFF
let print_one ch (c1, c2) =
if c1 = c2 then
Format.fprintf ch "%d" c1
else
Format.fprintf ch "%d-%d" c1 c2
let pp = Fmt.list print_one
let rec iter t ~f =
match t with
| [] -> ()
| (x, y)::xs ->
f x y;
iter xs ~f
let one_char = function
| [i, j] when i = j -> Some i
| _ -> None
module CSetMap = Map.Make (struct
type t = int * (int * int) list
let compare (i, u) (j, v) =
let c = compare i j in
if c <> 0
then c
else compare u v
end)
let fold_right t ~init ~f = List.fold_right f t init
let csingle c = single (Char.code c)
let cany = [0, 255]
let is_empty = function
| [] -> true
| _ -> false
let rec prepend s x l =
match s, l with
| [], _ -> l
| _r, [] -> []
| (_c, c') :: r, ([d, _d'], _x') :: _r' when c' < d -> prepend r x l
| (c, c') :: r, ([d, d'], x') :: r' ->
if c <= d then begin
if c' < d'
then ([d, c'], x @ x') :: prepend r x (([c' + 1, d'], x') :: r')
else ([d, d'], x @ x') :: prepend s x r'
end else begin
if c > d'
then ([d, d'], x') :: prepend s x r'
else ([d, c - 1], x') :: prepend s x (([c, d'], x') :: r')
end
| _ -> assert false
let pick = function
| [] -> invalid_arg "Re_cset.pick"
| (x, _)::_ -> x