2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
21 private type xtreemap(key : type, cls : class_ord(key), value : type);
22 type treemap(key : type, value : type, cls : class_ord(key)) := xtreemap(key, cls, value);
24 record treemap_key_value(key : type, value : type) [
29 fn treemap_init(key : type, value : type, const cls : class_ord(key)) : treemap(key, value, cls);
30 fn treemap_test(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key) : bool;
31 fn treemap_search(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(value);
32 fn treemap_first(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value));
33 fn treemap_last(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value));
34 fn treemap_next(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(treemap_key_value(key, value));
35 fn treemap_prev(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(treemap_key_value(key, value));
36 fn treemap_size(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : int;
37 fn treemap_insert(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key, v : value) : treemap(key, value, cls);
38 fn treemap_delete(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : treemap(key, value, cls);
40 implicit fn instance_functor_treemap~inline(key : type, const cls : class_ord(key)) : class_functor(xtreemap(key, cls,));
42 conversion fn treemap_iterator~type(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : class_iterator :=
44 state : maybe(treemap_key_value(key, value)),
45 element : treemap_key_value(key, value),
46 init : treemap_first(tm),
47 test : lambda(st : maybe(treemap_key_value(key, value))) [ return st is j; ],
48 get_element : lambda(st : maybe(treemap_key_value(key, value))) [ return st.j; ],
49 increment : lambda(st : maybe(treemap_key_value(key, value))) [ return treemap_next(tm, st.j.k); ],
52 fn treemap_iterator_reverse~type(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : class_iterator :=
54 state : maybe(treemap_key_value(key, value)),
55 element : treemap_key_value(key, value),
56 init : treemap_last(tm),
57 test : lambda(st : maybe(treemap_key_value(key, value))) [ return st is j; ],
58 get_element : lambda(st : maybe(treemap_key_value(key, value))) [ return st.j; ],
59 increment : lambda(st : maybe(treemap_key_value(key, value))) [ return treemap_prev(tm, st.j.k); ],
62 type treeset(key : type, cls : class_ord(key));
64 fn treeset_init(key : type, const cls : class_ord(key)) : treeset(key, cls);
65 fn treeset_test(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : bool;
66 fn treeset_first(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key);
67 fn treeset_last(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key);
68 fn treeset_next(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key);
69 fn treeset_prev(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key);
70 fn treeset_size(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : int;
71 fn treeset_set(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls);
72 fn treeset_clear(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls);
73 fn treeset_from_list(key : type, const cls : class_ord(key), l : list(key)) : treeset(key, cls);
75 conversion fn treeset_iterator~type(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : class_iterator :=
79 init : treeset_first(ts),
80 test : lambda(st : maybe(key)) [ return st is j; ],
81 get_element : lambda(st : maybe(key)) [ return st.j; ],
82 increment : lambda(st : maybe(key)) [ return treeset_next(ts, st.j); ],
85 fn treeset_iterator_reverse~type(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : class_iterator :=
89 init : treeset_last(ts),
90 test : lambda(st : maybe(key)) [ return st is j; ],
91 get_element : lambda(st : maybe(key)) [ return st.j; ],
92 increment : lambda(st : maybe(key)) [ return treeset_prev(ts, st.j); ],
97 record treemap_entry(key : type, value : type, cls : class_ord(key)) [
100 left : treemap(key, value, cls);
101 right : treemap(key, value, cls);
105 type xtreemap(key : type, cls : class_ord(key), value : type) := maybe(treemap_entry(key, value, cls));
109 fn treemap_verify(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls)) : int
113 var depth1 := treemap_verify(tm.j.left);
114 var depth2 := treemap_verify(tm.j.right);
115 var diff := tm.j.balance;
116 if abs(diff) > 1 or depth2 - depth1 <> diff then
117 abort internal("treemap_verify: diff " + ntos(diff) + ", depth1 " + ntos(depth1) + ", depth2 " + ntos(depth2));
118 return max(depth1, depth2) + 1;
122 fn treemap_init(key : type, value : type, const cls : class_ord(key)) : treemap(key, value, cls)
124 return treemap(key, value, cls).n;
127 fn treemap_test(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : bool
141 fn treemap_search(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(value)
145 return maybe(value).n;
147 return maybe(value).j.(tm.j.v);
155 fn treemap_first(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value))
158 return maybe(treemap_key_value(key, value)).n;
159 while tm.j.left is j do
161 return maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
164 fn treemap_last(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value))
167 return maybe(treemap_key_value(key, value)).n;
168 while tm.j.right is j do
170 return maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
173 fn treemap_next(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(treemap_key_value(key, value))
175 var result := maybe(treemap_key_value(key, value)).n;
180 result := maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
188 fn treemap_prev(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(treemap_key_value(key, value))
190 var result := maybe(treemap_key_value(key, value)).n;
195 result := maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
203 fn treemap_size(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : int
207 return 1 + treemap_size(tm.j.left) + treemap_size(tm.j.right);
210 fn treemap_insert_internal(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key, v : value) : (treemap(key, value, cls), bool)
212 const te := treemap_entry(key, value);
214 return maybe(te).j.(te.[ k : k, v : v, left : maybe(te).n, right : maybe(te).n, balance : 0 ]), true;
219 var height_changed : bool;
221 var s := maybe(te).n;
222 s, tm.j.left := tm.j.left, s;
223 s, height_changed := treemap_insert_internal(s, k, v);
224 if height_changed then [
225 if tm.j.balance = 1 then [
227 height_changed := false;
228 ] else if tm.j.balance = 0 then [
231 if s.j.balance = 0 then
232 abort internal("treemap_insert_internal: s.j.balance = 0");
233 else if s.j.balance = -1 then [
234 //eval debug("insert rotate 1");
235 tm.j.left := s.j.right;
241 //eval debug("insert rotate 2");
243 var balance := x.j.balance;
244 tm.j.left := x.j.right;
245 s.j.right := x.j.left;
246 tm.j.balance := select(balance = -1, 0, 1);
247 s.j.balance := select(balance = 1, 0, -1);
255 s, tm.j.left := tm.j.left, s;
257 var s := maybe(te).n;
258 s, tm.j.right := tm.j.right, s;
259 s, height_changed := treemap_insert_internal(s, k, v);
260 if height_changed then [
261 if tm.j.balance = -1 then [
263 height_changed := false;
264 ] else if tm.j.balance = 0 then [
267 if s.j.balance = 0 then
268 abort internal("treemap_insert_internal: s.j.balance = 0");
269 else if s.j.balance = 1 then [
270 //eval debug("insert rotate 3");
271 tm.j.right := s.j.left;
277 //eval debug("insert rotate 4");
279 var balance := x.j.balance;
280 tm.j.right := x.j.left;
281 s.j.left := x.j.right;
282 tm.j.balance := select(balance = 1, 0, -1);
283 s.j.balance := select(balance = -1, 0, 1);
291 s, tm.j.right := tm.j.right, s;
293 return tm, height_changed;
296 fn treemap_insert(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key, v : value) : treemap(key, value, cls)
298 var tm, height_changed := treemap_insert_internal(tm, k, v);
299 //xeval treemap_verify(tm);
303 fn treemap_delete_internal(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : (treemap(key, value, cls), bool)
305 const te := treemap_entry(key, value);
308 var height_changed : bool;
310 if tm.j.left is n then
311 return tm.j.right, true;
312 if tm.j.right is n then
313 return tm.j.left, true;
314 var last := tm.j.left;
315 while last.j.right is j do
316 last := last.j.right;
324 var s := maybe(te).n;
325 s, tm.j.left := tm.j.left, s;
326 s, height_changed := treemap_delete_internal(s, k);
327 s, tm.j.left := tm.j.left, s;
328 if height_changed then [
329 if tm.j.balance = -1 then [
331 ] else if tm.j.balance = 0 then [
333 height_changed := false;
336 var balance := s.j.balance;
337 if balance >= 0 then [
338 //eval debug("delete rotate 1");
339 tm.j.right := s.j.left;
340 tm.j.balance := 1 - balance;
342 s.j.balance := balance - 1;
343 return s, balance <> 0;
345 //eval debug("delete rotate 2");
347 balance := x.j.balance;
348 tm.j.right := x.j.left;
349 s.j.left := x.j.right;
350 tm.j.balance := select(balance = 1, 0, -1);
351 s.j.balance := select(balance = -1, 0, 1);
360 var s := maybe(te).n;
361 s, tm.j.right := tm.j.right, s;
362 s, height_changed := treemap_delete_internal(s, k);
363 s, tm.j.right := tm.j.right, s;
364 if height_changed then [
365 if tm.j.balance = 1 then [
367 ] else if tm.j.balance = 0 then [
369 height_changed := false;
372 var balance := s.j.balance;
373 if balance <= 0 then [
374 //eval debug("delete rotate 3");
375 tm.j.left := s.j.right;
376 tm.j.balance := -1 - balance;
378 s.j.balance := balance + 1;
379 return s, balance <> 0;
381 //eval debug("delete rotate 4");
383 balance := x.j.balance;
384 tm.j.left := x.j.right;
385 s.j.right := x.j.left;
386 tm.j.balance := select(balance = -1, 0, 1);
387 s.j.balance := select(balance = 1, 0, -1);
396 return tm, height_changed;
399 fn treemap_delete(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : treemap(key, value, cls)
401 var tm, height_changed := treemap_delete_internal(tm, k);
402 //xeval treemap_verify(tm);
406 fn treemap_map(key : type, const implicit cls : class_ord(key), value : type, new_value : type, tm : treemap(key, value, cls), m : fn(value) : new_value) : treemap(key, new_value, cls)
409 return treemap_init(key, new_value, cls);
410 const te := treemap_entry(key, new_value);
411 return maybe(te).j.(te.[
414 balance : tm.j.balance,
415 left : treemap_map(key, cls, value, new_value, tm.j.left, m),
416 right : treemap_map(key, cls, value, new_value, tm.j.right, m),
420 implicit fn instance_functor_treemap~inline(key : type, const cls : class_ord(key)) : class_functor(xtreemap(key, cls,)) :=
421 class_functor(xtreemap(key, cls,)).[
422 map : treemap_map(key, cls,,,,),
426 type treeset(key : type, cls : class_ord(key)) := treemap(key, unit_type, cls);
428 fn treeset_init(key : type, const cls : class_ord(key)) : treeset(key, cls) := treemap_init(key, unit_type, cls);
429 fn treeset_test(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : bool := treemap_test(ts, k);
430 fn treeset_first(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key)
432 var f := treemap_first(ts);
436 return maybe(key).j.(f.j.k);
438 fn treeset_last(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key)
440 var f := treemap_last(ts);
444 return maybe(key).j.(f.j.k);
446 fn treeset_next(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key)
448 var f := treemap_next(ts, k);
452 return maybe(key).j.(f.j.k);
454 fn treeset_prev(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key)
456 var f := treemap_prev(ts, k);
460 return maybe(key).j.(f.j.k);
462 fn treeset_size(key : type, const cls : class_ord(key), tm : treeset(key, cls)) : int := treemap_size(tm);
463 fn treeset_set(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls) := treemap_insert(ts, k, unit_value);
464 fn treeset_clear(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls) := treemap_delete(ts, k);
465 fn treeset_from_list(key : type, const cls : class_ord(key), l : list(key)) : treeset(key, cls)
467 var ts := treeset_init(key, cls);
469 ts := treeset_set(ts, f);