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_is_nonempty(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : bool;
31 fn treemap_test(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key) : bool;
32 fn treemap_search(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(value);
33 fn treemap_search_default(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key, def : value) : value;
34 fn treemap_first(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value));
35 fn treemap_last(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value));
36 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));
37 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));
38 fn treemap_size(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : int;
39 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);
40 fn treemap_delete(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : treemap(key, value, cls);
42 implicit fn instance_functor_treemap~inline(key : type, const cls : class_ord(key)) : class_functor(xtreemap(key, cls,));
44 conversion fn treemap_iterator~type(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : class_iterator :=
46 state : maybe(treemap_key_value(key, value)),
47 element : treemap_key_value(key, value),
48 init : treemap_first(tm),
49 test : lambda(st : maybe(treemap_key_value(key, value))) [ return st is j; ],
50 get_element : lambda(st : maybe(treemap_key_value(key, value))) [ return st.j; ],
51 increment : lambda(st : maybe(treemap_key_value(key, value))) [ return treemap_next(tm, st.j.k); ],
54 fn treemap_iterator_reverse~type(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : class_iterator :=
56 state : maybe(treemap_key_value(key, value)),
57 element : treemap_key_value(key, value),
58 init : treemap_last(tm),
59 test : lambda(st : maybe(treemap_key_value(key, value))) [ return st is j; ],
60 get_element : lambda(st : maybe(treemap_key_value(key, value))) [ return st.j; ],
61 increment : lambda(st : maybe(treemap_key_value(key, value))) [ return treemap_prev(tm, st.j.k); ],
64 type treeset(key : type, cls : class_ord(key));
66 fn treeset_init(key : type, const cls : class_ord(key)) : treeset(key, cls);
67 fn treeset_is_nonempty(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : bool;
68 fn treeset_test(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : bool;
69 fn treeset_first(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key);
70 fn treeset_last(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key);
71 fn treeset_next(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key);
72 fn treeset_prev(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key);
73 fn treeset_size(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : int;
74 fn treeset_set(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls);
75 fn treeset_clear(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls);
76 fn treeset_from_list(key : type, const cls : class_ord(key), l : list(key)) : treeset(key, cls);
78 conversion fn treeset_iterator~type(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : class_iterator :=
82 init : treeset_first(ts),
83 test : lambda(st : maybe(key)) [ return st is j; ],
84 get_element : lambda(st : maybe(key)) [ return st.j; ],
85 increment : lambda(st : maybe(key)) [ return treeset_next(ts, st.j); ],
88 fn treeset_iterator_reverse~type(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : class_iterator :=
92 init : treeset_last(ts),
93 test : lambda(st : maybe(key)) [ return st is j; ],
94 get_element : lambda(st : maybe(key)) [ return st.j; ],
95 increment : lambda(st : maybe(key)) [ return treeset_prev(ts, st.j); ],
100 record treemap_entry(key : type, value : type, cls : class_ord(key)) [
103 left : treemap(key, value, cls);
104 right : treemap(key, value, cls);
108 type xtreemap(key : type, cls : class_ord(key), value : type) := maybe(treemap_entry(key, value, cls));
112 fn treemap_verify(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls)) : int
116 var depth1 := treemap_verify(tm.j.left);
117 var depth2 := treemap_verify(tm.j.right);
118 var diff := tm.j.balance;
119 if abs(diff) > 1 or depth2 - depth1 <> diff then
120 abort internal("treemap_verify: diff " + ntos(diff) + ", depth1 " + ntos(depth1) + ", depth2 " + ntos(depth2));
121 return max(depth1, depth2) + 1;
125 fn treemap_init(key : type, value : type, const cls : class_ord(key)) : treemap(key, value, cls)
127 return treemap(key, value, cls).n;
130 fn treemap_is_nonempty(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : bool
135 fn treemap_test(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : bool
149 fn treemap_search(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : maybe(value)
153 return maybe(value).n;
155 return maybe(value).j.(tm.j.v);
163 fn treemap_search_default(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls), k : key, def : value) : value
165 var s := treemap_search(tm, k);
171 fn treemap_first(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value))
174 return maybe(treemap_key_value(key, value)).n;
175 while tm.j.left is j do
177 return maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
180 fn treemap_last(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : maybe(treemap_key_value(key, value))
183 return maybe(treemap_key_value(key, value)).n;
184 while tm.j.right is j do
186 return maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
189 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))
191 var result := maybe(treemap_key_value(key, value)).n;
196 result := maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
204 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))
206 var result := maybe(treemap_key_value(key, value)).n;
211 result := maybe(treemap_key_value(key, value)).j.(treemap_key_value(key, value).[ k : tm.j.k, v : tm.j.v ]);
219 fn treemap_size(key : type, value : type, const cls : class_ord(key), tm : treemap(key, value, cls)) : int
223 return 1 + treemap_size(tm.j.left) + treemap_size(tm.j.right);
226 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)
228 const te := treemap_entry(key, value);
230 return maybe(te).j.(te.[ k : k, v : v, left : maybe(te).n, right : maybe(te).n, balance : 0 ]), true;
235 var height_changed : bool;
237 var s := maybe(te).n;
238 s, tm.j.left := tm.j.left, s;
239 s, height_changed := treemap_insert_internal(s, k, v);
240 if height_changed then [
241 if tm.j.balance = 1 then [
243 height_changed := false;
244 ] else if tm.j.balance = 0 then [
247 if s.j.balance = 0 then
248 abort internal("treemap_insert_internal: s.j.balance = 0");
249 else if s.j.balance = -1 then [
250 //eval debug("insert rotate 1");
251 tm.j.left := s.j.right;
257 //eval debug("insert rotate 2");
259 var balance := x.j.balance;
260 tm.j.left := x.j.right;
261 s.j.right := x.j.left;
262 tm.j.balance := select(balance = -1, 0, 1);
263 s.j.balance := select(balance = 1, 0, -1);
271 s, tm.j.left := tm.j.left, s;
273 var s := maybe(te).n;
274 s, tm.j.right := tm.j.right, s;
275 s, height_changed := treemap_insert_internal(s, k, v);
276 if height_changed then [
277 if tm.j.balance = -1 then [
279 height_changed := false;
280 ] else if tm.j.balance = 0 then [
283 if s.j.balance = 0 then
284 abort internal("treemap_insert_internal: s.j.balance = 0");
285 else if s.j.balance = 1 then [
286 //eval debug("insert rotate 3");
287 tm.j.right := s.j.left;
293 //eval debug("insert rotate 4");
295 var balance := x.j.balance;
296 tm.j.right := x.j.left;
297 s.j.left := x.j.right;
298 tm.j.balance := select(balance = 1, 0, -1);
299 s.j.balance := select(balance = -1, 0, 1);
307 s, tm.j.right := tm.j.right, s;
309 return tm, height_changed;
312 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)
314 var tm, height_changed := treemap_insert_internal(tm, k, v);
315 //xeval treemap_verify(tm);
319 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)
321 const te := treemap_entry(key, value);
324 var height_changed : bool;
326 if tm.j.left is n then
327 return tm.j.right, true;
328 if tm.j.right is n then
329 return tm.j.left, true;
330 var last := tm.j.left;
331 while last.j.right is j do
332 last := last.j.right;
340 var s := maybe(te).n;
341 s, tm.j.left := tm.j.left, s;
342 s, height_changed := treemap_delete_internal(s, k);
343 s, tm.j.left := tm.j.left, s;
344 if height_changed then [
345 if tm.j.balance = -1 then [
347 ] else if tm.j.balance = 0 then [
349 height_changed := false;
352 var balance := s.j.balance;
353 if balance >= 0 then [
354 //eval debug("delete rotate 1");
355 tm.j.right := s.j.left;
356 tm.j.balance := 1 - balance;
358 s.j.balance := balance - 1;
359 return s, balance <> 0;
361 //eval debug("delete rotate 2");
363 balance := x.j.balance;
364 tm.j.right := x.j.left;
365 s.j.left := x.j.right;
366 tm.j.balance := select(balance = 1, 0, -1);
367 s.j.balance := select(balance = -1, 0, 1);
376 var s := maybe(te).n;
377 s, tm.j.right := tm.j.right, s;
378 s, height_changed := treemap_delete_internal(s, k);
379 s, tm.j.right := tm.j.right, s;
380 if height_changed then [
381 if tm.j.balance = 1 then [
383 ] else if tm.j.balance = 0 then [
385 height_changed := false;
388 var balance := s.j.balance;
389 if balance <= 0 then [
390 //eval debug("delete rotate 3");
391 tm.j.left := s.j.right;
392 tm.j.balance := -1 - balance;
394 s.j.balance := balance + 1;
395 return s, balance <> 0;
397 //eval debug("delete rotate 4");
399 balance := x.j.balance;
400 tm.j.left := x.j.right;
401 s.j.right := x.j.left;
402 tm.j.balance := select(balance = -1, 0, 1);
403 s.j.balance := select(balance = 1, 0, -1);
412 return tm, height_changed;
415 fn treemap_delete(key : type, value : type, const implicit cls : class_ord(key), tm : treemap(key, value, cls), k : key) : treemap(key, value, cls)
417 var tm, height_changed := treemap_delete_internal(tm, k);
418 //xeval treemap_verify(tm);
422 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)
425 return treemap_init(key, new_value, cls);
426 const te := treemap_entry(key, new_value);
427 return maybe(te).j.(te.[
430 balance : tm.j.balance,
431 left : treemap_map(key, cls, value, new_value, tm.j.left, m),
432 right : treemap_map(key, cls, value, new_value, tm.j.right, m),
436 implicit fn instance_functor_treemap~inline(key : type, const cls : class_ord(key)) : class_functor(xtreemap(key, cls,)) :=
437 class_functor(xtreemap(key, cls,)).[
438 map : treemap_map(key, cls,,,,),
442 type treeset(key : type, cls : class_ord(key)) := treemap(key, unit_type, cls);
444 fn treeset_init(key : type, const cls : class_ord(key)) : treeset(key, cls) := treemap_init(key, unit_type, cls);
445 fn treeset_is_nonempty(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : bool := treemap_is_nonempty(ts);
446 fn treeset_test(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : bool := treemap_test(ts, k);
447 fn treeset_first(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key)
449 var f := treemap_first(ts);
453 return maybe(key).j.(f.j.k);
455 fn treeset_last(key : type, const cls : class_ord(key), ts : treeset(key, cls)) : maybe(key)
457 var f := treemap_last(ts);
461 return maybe(key).j.(f.j.k);
463 fn treeset_next(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key)
465 var f := treemap_next(ts, k);
469 return maybe(key).j.(f.j.k);
471 fn treeset_prev(key : type, const implicit cls : class_ord(key), ts : treeset(key, cls), k : key) : maybe(key)
473 var f := treemap_prev(ts, k);
477 return maybe(key).j.(f.j.k);
479 fn treeset_size(key : type, const cls : class_ord(key), tm : treeset(key, cls)) : int := treemap_size(tm);
480 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);
481 fn treeset_clear(key : type, const cls : class_ord(key), ts : treeset(key, cls), k : key) : treeset(key, cls) := treemap_delete(ts, k);
482 fn treeset_from_list(key : type, const cls : class_ord(key), l : list(key)) : treeset(key, cls)
484 var ts := treeset_init(key, cls);
486 ts := treeset_set(ts, f);