Source file sequence.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
let bitsize = 5
let node_size = 1 lsl bitsize
type 'a t =
| Leaf of 'a array
| Node of int * int * 'a t array
let map (f:'a ->'b) (t:'a t): 'b t =
let rec map (t:'a t): 'b t =
match t with
| Leaf arr ->
Leaf (Array.map f arr)
| Node (size, h, arr) ->
Node (size, h,
Array.map map arr)
in
map t
let empty = Leaf [||]
let length (t:'a t): int =
match t with
| Leaf arr ->
Array.length arr
| Node (size,_,_) ->
size
let is_empty (t:'a t): bool =
length t = 0
let slot_of_index (level: int) (index: int): int =
index lsr (level * bitsize)
let slot_and_offset (index: int) (level: int): int * int =
let slot = slot_of_index level index in
let offset = index - slot lsl (level * bitsize) in
slot, offset
let rec elem (i:int) (t:'a t): 'a =
assert (0 <= i);
assert (i < length t);
match t with
| Leaf arr ->
arr.(i)
| Node (_,h,arr) ->
let slot,offset = slot_and_offset i h in
assert (slot < Array.length arr);
elem offset arr.(slot)
let rec singleton_with_height (e:'a) (h:int): 'a t =
assert (0 <= h);
if h = 0 then
Leaf [|e|]
else
Node (1,h, [|singleton_with_height e (h-1)|])
let singleton (a:'a): 'a t =
singleton_with_height a 0
let push_array (e:'a) (arr:'a array): 'a array =
let len = Array.length arr in
let arr2 = Array.make (len+1) e in
Array.blit arr 0 arr2 0 len;
arr2
let put_array (i:int) (e:'a) (arr:'a array): 'a array =
let arr2 = Array.copy arr in
arr2.(i) <- e;
arr2
let rec put (i:int) (e:'a) (t:'a t): 'a t =
assert (i < length t);
match t with
| Leaf arr ->
Leaf (put_array i e arr)
| Node (s,h,arr) ->
let slot, rel = slot_and_offset i h in
let arr = put_array slot (put rel e arr.(slot)) arr in
Node (s,h,arr)
let push (e:'a) (t:'a t): 'a t =
let n = length t in
let rec push0 e t =
match t with
| Leaf arr ->
let len = Array.length arr in
if len < node_size then
Leaf (push_array e arr), false
else
Node (len+1,1,[|Leaf arr; Leaf [|e|]|]), true
| Node (size,h,arr) ->
assert (0 < h);
let len = Array.length arr in
assert (0 < len);
if size = len * (1 lsl (h*bitsize)) then
if len = node_size then
Node (size+1, h+1, [|t; singleton_with_height e h|]),
true
else
Node (size+1, h, push_array (singleton_with_height e (h-1)) arr),
false
else
let t0, incr = push0 e arr.(len-1) in
assert (not incr);
let arr2 = Array.copy arr in
arr2.(len-1) <- t0;
Node (size+1,h,arr2), false
in
let t,_ = push0 e t in
assert (length t = n + 1);
t
let rec push_list (l:'a list) (t:'a t): 'a t =
match l with
| [] ->
t
| e :: l ->
push_list l (push e t)
let push_array (arr:'a array) (t:'a t): 'a t =
Array.fold_left
(fun t e -> push e t)
t
arr
let of_list (l:'a list): 'a t =
push_list l empty
let of_array (arr:'a array): 'a t =
push_array arr empty
let rec take (n:int) (t:'a t): 'a t =
assert (n <= length t);
match t with
| Leaf arr ->
Leaf (Array.sub arr 0 n)
| Node (s,h,arr) ->
if n = s then
t
else
let slot,rel = slot_and_offset n h in
let slot,rel =
if rel = 0 && 0 < slot then
slot - 1, 1 lsl (h*bitsize)
else
slot,rel
in
let t0 = take rel arr.(slot) in
if slot = 0 then
t0
else
let arr = Array.sub arr 0 (slot+1) in
arr.(slot) <- t0;
Node (n,h,arr)
let remove_last (n: int) (arr: 'a t): 'a t =
let len = length arr in
assert (n <= len);
take (len - n) arr
let to_array (arr:'a t): 'a array =
Array.init (length arr) (fun i -> elem i arr)
let to_string (arr:char t): string =
String.init (length arr) (fun i -> elem i arr)
let fill (n:int): int t =
assert (0 <= n);
let rec fill0 (i:int) (t:int t): int t =
if i = n then
t
else
fill0 (i+1) (push i t) in
fill0 0 empty
let overwrite (n:int) (t:int t): int t =
let rec over i t =
if i = n then
t
else
over (i+1) (put i (i+1) t)
in
over 0 t
let%test _ =
let n = 32768 in
let t = fill n in
let check = ref true in
for i = 0 to n - 1 do
check := !check && elem i t = i
done;
!check
let%test _ =
let n = 32768 in
let t = fill n in
let t1 = overwrite n t in
let check = ref true in
for i = 0 to n - 1 do
check := !check && elem i t1 = i +1
done;
!check
let%test _ =
let n = 32768 in
let m = 1024 in
let t = fill n in
let t2 = take m t in
let check = ref true in
for i = 0 to m - 1 do
check := !check && elem i t2 = i
done;
!check && length t2 = m