34
35:- module(rbtrees,
36 [ rb_new/1, 37 rb_empty/1, 38 rb_lookup/3, 39 rb_update/4, 40 rb_update/5, 41 rb_apply/4, 42 rb_insert/4, 43 rb_insert_new/4, 44 rb_delete/3, 45 rb_delete/4, 46 rb_visit/2, 47 rb_visit_range/4, 48 rb_keys/2, 49 rb_map/2, 50 rb_map/3, 51 rb_partial_map/4, 52 rb_fold/4, 53 rb_clone/3, 54 rb_min/3, 55 rb_max/3, 56 rb_del_min/4, 57 rb_del_max/4, 58 rb_next/4, 59 rb_previous/4, 60 list_to_rbtree/2, 61 ord_list_to_rbtree/2, 62 is_rbtree/1, 63 rb_size/2, 64 rb_in/3 65 ]). 66:- autoload(library(error), [domain_error/2]). 67
102
108
113
114:- meta_predicate
115 rb_map(+,2,-),
116 rb_map(?,1),
117 rb_partial_map(+,+,2,-),
118 rb_apply(+,+,2,-),
119 rb_fold(3,+,+,-). 120
143
149
150:- det(rb_new/1). 151rb_new(t(Nil,Nil)) :-
152 Nil = black('',_,_,'').
153
157
158rb_empty(t(Nil,Nil)) :-
159 Nil = black('',_,_,'').
160
169
170rb_lookup(Key, Val, t(_,Tree)) =>
171 lookup(Key, Val, Tree).
172
173lookup(_Key, _Val, black('',_,_,'')) => fail.
174lookup(Key, Val, Tree) =>
175 arg(2,Tree,KA),
176 compare(Cmp,KA,Key),
177 lookup(Cmp,Key,Val,Tree).
178
179lookup(>, K, V, Tree) :-
180 arg(1,Tree,NTree),
181 lookup(K, V, NTree).
182lookup(<, K, V, Tree) :-
183 arg(4,Tree,NTree),
184 lookup(K, V, NTree).
185lookup(=, _, V, Tree) :-
186 arg(3,Tree,V).
187
191
192rb_min(t(_,Tree), Key, Val) =>
193 min(Tree, Key, Val).
194
195min(red(black('',_,_,_),Key0,Val0,_), Key, Val) => Key0=Key, Val0=Val.
196min(black(black('',_,_,_),Key0,Val0,_), Key, Val) => Key0=Key, Val0=Val.
197min(red(Right,_,_,_), Key, Val) =>
198 min(Right,Key,Val).
199min(black(Right,_,_,_), Key, Val) =>
200 min(Right,Key,Val).
201min('', _Key, _Val) => fail.
202
206
207rb_max(t(_,Tree), Key, Val) =>
208 max(Tree, Key, Val).
209
210max(red(_,Key0,Val0,black('',_,_,_)), Key, Val) => Key0=Key, Val0=Val.
211max(black(_,Key0,Val0,black('',_,_,_)), Key, Val) =>Key0=Key, Val0=Val.
212max(red(_,_,_,Left), Key, Val) =>
213 max(Left,Key,Val).
214max(black(_,_,_,Left), Key, Val) =>
215 max(Left,Key,Val).
216max('', _Key, _Val) => fail.
217
222
223rb_next(t(_,Tree), Key, Next, Val) =>
224 next(Tree, Key, Next, Val, []).
225
226next(black('',_,_,''), _, _, _, _) => fail.
227next(Tree, Key, Next, Val, Candidate) =>
228 arg(2,Tree,KA),
229 arg(3,Tree,VA),
230 compare(Cmp,KA,Key),
231 next(Cmp, Key, KA, VA, Next, Val, Tree, Candidate).
232
233next(>, K, KA, VA, NK, V, Tree, _) :-
234 arg(1,Tree,NTree),
235 next(NTree,K,NK,V,KA-VA).
236next(<, K, _, _, NK, V, Tree, Candidate) :-
237 arg(4,Tree,NTree),
238 next(NTree,K,NK,V,Candidate).
239next(=, _, _, _, NK, Val, Tree, Candidate) :-
240 arg(4,Tree,NTree),
241 ( min(NTree, NK, Val)
242 -> true
243 ; Candidate = (NK-Val)
244 ).
245
251
252rb_previous(t(_,Tree), Key, Previous, Val) =>
253 previous(Tree, Key, Previous, Val, []).
254
255previous(black('',_,_,''), _, _, _, _) => fail.
256previous(Tree, Key, Previous, Val, Candidate) =>
257 arg(2,Tree,KA),
258 arg(3,Tree,VA),
259 compare(Cmp,KA,Key),
260 previous(Cmp, Key, KA, VA, Previous, Val, Tree, Candidate).
261
262previous(>, K, _, _, NK, V, Tree, Candidate) :-
263 arg(1,Tree,NTree),
264 previous(NTree,K,NK,V,Candidate).
265previous(<, K, KA, VA, NK, V, Tree, _) :-
266 arg(4,Tree,NTree),
267 previous(NTree,K,NK,V,KA-VA).
268previous(=, _, _, _, K, Val, Tree, Candidate) :-
269 arg(1,Tree,NTree),
270 ( max(NTree, K, Val)
271 -> true
272 ; Candidate = (K-Val)
273 ).
274
283
284rb_update(t(Nil,OldTree), Key, OldVal, Val, NewTree2) =>
285 NewTree2 = t(Nil,NewTree),
286 update(OldTree, Key, OldVal, Val, NewTree).
287
292
293rb_update(t(Nil,OldTree), Key, Val, NewTree2) =>
294 NewTree2 = t(Nil,NewTree),
295 update(OldTree, Key, _, Val, NewTree).
296
297update(black(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :-
298 Left \= [],
299 compare(Cmp,Key0,Key),
300 ( Cmp == (=)
301 -> OldVal = Val0,
302 NewTree = black(Left,Key0,Val,Right)
303 ; Cmp == (>)
304 -> NewTree = black(NewLeft,Key0,Val0,Right),
305 update(Left, Key, OldVal, Val, NewLeft)
306 ; NewTree = black(Left,Key0,Val0,NewRight),
307 update(Right, Key, OldVal, Val, NewRight)
308 ).
309update(red(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :-
310 compare(Cmp,Key0,Key),
311 ( Cmp == (=)
312 -> OldVal = Val0,
313 NewTree = red(Left,Key0,Val,Right)
314 ; Cmp == (>)
315 -> NewTree = red(NewLeft,Key0,Val0,Right),
316 update(Left, Key, OldVal, Val, NewLeft)
317 ; NewTree = red(Left,Key0,Val0,NewRight),
318 update(Right, Key, OldVal, Val, NewRight)
319 ).
320
327
328rb_apply(t(Nil,OldTree), Key, Goal, NewTree2) =>
329 NewTree2 = t(Nil,NewTree),
330 apply(OldTree, Key, Goal, NewTree).
331
332:- meta_predicate apply(+,?,2,-). 334apply(black(Left,Key0,Val0,Right), Key, Goal,
335 black(NewLeft,Key0,Val,NewRight)) :-
336 Left \= [],
337 compare(Cmp,Key0,Key),
338 ( Cmp == (=)
339 -> NewLeft = Left,
340 NewRight = Right,
341 call(Goal,Val0,Val)
342 ; Cmp == (>)
343 -> NewRight = Right,
344 Val = Val0,
345 apply(Left, Key, Goal, NewLeft)
346 ; NewLeft = Left,
347 Val = Val0,
348 apply(Right, Key, Goal, NewRight)
349 ).
350apply(red(Left,Key0,Val0,Right), Key, Goal,
351 red(NewLeft,Key0,Val,NewRight)) :-
352 compare(Cmp,Key0,Key),
353 ( Cmp == (=)
354 -> NewLeft = Left,
355 NewRight = Right,
356 call(Goal,Val0,Val)
357 ; Cmp == (>)
358 -> NewRight = Right,
359 Val = Val0,
360 apply(Left, Key, Goal, NewLeft)
361 ; NewLeft = Left,
362 Val = Val0,
363 apply(Right, Key, Goal, NewRight)
364 ).
365
375
376rb_in(Key, Val, t(_,T)) =>
377 enum(Key, Val, T).
378
379enum(Key, Val, black(L,K,V,R)) =>
380 L \= '',
381 enum_cases(Key, Val, L, K, V, R).
382enum(Key, Val, red(L,K,V,R)) =>
383 enum_cases(Key, Val, L, K, V, R).
384enum(_Key, _Val, _Tree) => fail.
385
386enum_cases(Key, Val, L, _, _, _) :-
387 enum(Key, Val, L).
388enum_cases(Key, Val, _, Key, Val, _).
389enum_cases(Key, Val, _, _, _, R) :-
390 enum(Key, Val, R).
391
392
393
394 397
399
407
408:- det(rb_insert/4). 409rb_insert(t(Nil,Tree0),Key,Val,NewTree) =>
410 NewTree = t(Nil,Tree),
411 insert(Tree0,Key,Val,Nil,Tree).
412
413
414insert(Tree0,Key,Val,Nil,Tree) :-
415 insert2(Tree0,Key,Val,Nil,TreeI,_),
416 fix_root(TreeI,Tree).
417
435
436
437
441insert2(black('',_,_,''), K, V, Nil, T, Status) =>
442 T = red(Nil,K,V,Nil),
443 Status = not_done.
444insert2(red(L,K0,V0,R), K, V, Nil, NT, Flag) =>
445 ( K @< K0
446 -> NT = red(NL,K0,V0,R),
447 insert2(L, K, V, Nil, NL, Flag)
448 ; K == K0
449 -> NT = red(L,K0,V,R),
450 Flag = done
451 ; NT = red(L,K0,V0,NR),
452 insert2(R, K, V, Nil, NR, Flag)
453 ).
454insert2(black(L,K0,V0,R), K, V, Nil, NT, Flag) =>
455 ( K @< K0
456 -> insert2(L, K, V, Nil, IL, Flag0),
457 fix_left(Flag0, black(IL,K0,V0,R), NT, Flag)
458 ; K == K0
459 -> NT = black(L,K0,V,R),
460 Flag = done
461 ; insert2(R, K, V, Nil, IR, Flag0),
462 fix_right(Flag0, black(L,K0,V0,IR), NT, Flag)
463 ).
464
466
473
474rb_insert_new(t(Nil,Tree0),Key,Val,NewTree) =>
475 NewTree = t(Nil,Tree),
476 insert_new(Tree0,Key,Val,Nil,Tree).
477
478insert_new(Tree0,Key,Val,Nil,Tree) :-
479 insert_new_2(Tree0,Key,Val,Nil,TreeI,_),
480 fix_root(TreeI,Tree).
481
485insert_new_2(black('',_,_,''), K, V, Nil, T, Status) =>
486 T = red(Nil,K,V,Nil),
487 Status = not_done.
488insert_new_2(red(L,K0,V0,R), K, V, Nil, NT, Flag) =>
489 ( K @< K0
490 -> NT = red(NL,K0,V0,R),
491 insert_new_2(L, K, V, Nil, NL, Flag)
492 ; K == K0
493 -> fail
494 ; NT = red(L,K0,V0,NR),
495 insert_new_2(R, K, V, Nil, NR, Flag)
496 ).
497insert_new_2(black(L,K0,V0,R), K, V, Nil, NT, Flag) =>
498 ( K @< K0
499 -> insert_new_2(L, K, V, Nil, IL, Flag0),
500 fix_left(Flag0, black(IL,K0,V0,R), NT, Flag)
501 ; K == K0
502 -> fail
503 ; insert_new_2(R, K, V, Nil, IR, Flag0),
504 fix_right(Flag0, black(L,K0,V0,IR), NT, Flag)
505 ).
506
510:- det(fix_root/2). 511fix_root(black(L,K,V,R), Root) => Root = black(L,K,V,R).
512fix_root(red(L,K,V,R), Root) => Root = black(L,K,V,R).
513
517:- det(fix_left/4). 518fix_left(done,T0,T,Done) => T = T0, Done = done.
519fix_left(not_done,Tmp,Final,Done) =>
520 fix_left(Tmp,Final,Done).
521
522:- det(fix_left/3). 526fix_left(black(red(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,red(De,KD,VD,Ep)),
527 red(black(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,black(De,KD,VD,Ep)),
528 not_done) :- !.
529fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,red(De,KD,VD,Ep)),
530 red(black(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,black(De,KD,VD,Ep)),
531 not_done) :- !.
535fix_left(black(red(Al,KA,VA,red(Be,KB,VB,Ga)),KC,VC,De),
536 black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)),
537 done) :- !.
541fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,De),
542 black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)),
543 done) :- !.
547fix_left(T,T,done).
548
552:- det(fix_right/4). 553fix_right(done,T0,T,Done) => T0 = T, Done = done.
554fix_right(not_done,Tmp,Final,Done) =>
555 fix_right(Tmp,Final,Done).
556
557:- det(fix_right/3). 561fix_right(black(red(Ep,KD,VD,De),KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)),
562 red(black(Ep,KD,VD,De),KC,VC,black(red(Ga,KB,VB,Be),KA,VA,Al)),
563 not_done) :- !.
564fix_right(black(red(Ep,KD,VD,De),KC,VC,red(Ga,Ka,Va,red(Be,KB,VB,Al))),
565 red(black(Ep,KD,VD,De),KC,VC,black(Ga,Ka,Va,red(Be,KB,VB,Al))),
566 not_done) :- !.
570fix_right(black(De,KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)),
571 black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)),
572 done) :- !.
576fix_right(black(De,KC,VC,red(Ga,KB,VB,red(Be,KA,VA,Al))),
577 black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)),
578 done) :- !.
582fix_right(T,T,done).
583
584
592
593rb_delete(t(Nil,T), K, NewTree) =>
594 NewTree = t(Nil,NT),
595 delete(T, K, _, NT, _).
596
601
602rb_delete(t(Nil,T), K, V, NewTree) =>
603 NewTree = t(Nil,NT),
604 delete(T, K, V0, NT, _),
605 V = V0.
606
610delete(red(L,K0,V0,R), K, V, NT, Flag) =>
611 delete_red(L,K0,V0,R, K, V, NT, Flag).
612delete(black(L,K0,V0,R), K, V, NT, Flag) =>
613 delete_black(L,K0,V0,R, K, V, NT, Flag).
614delete('', _K, _V, _NT, _Flag) =>
615 fail.
616
617delete_red(L,K0,V0,R, K, V, NT, Flag), K @< K0 =>
618 delete(L, K, V, NL, Flag0),
619 fixup_left(Flag0,red(NL,K0,V0,R),NT, Flag).
620delete_red(L,K0,V0,R, K, V, NT, Flag), K @> K0 =>
621 delete(R, K, V, NR, Flag0),
622 fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag).
623delete_red(L,_,V0,R, _, V, Out, Flag) => 624 V0 = V,
625 delete_red_node(L,R,Out,Flag).
626
627delete_black(L,K0,V0,R, K, V, NT, Flag), K @< K0 =>
628 delete(L, K, V, NL, Flag0),
629 fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag).
630delete_black(L,K0,V0,R, K, V, NT, Flag), K @> K0 =>
631 delete(R, K, V, NR, Flag0),
632 fixup_right(Flag0,black(L,K0,V0,NR),NT, Flag).
633delete_black(L,_,V0,R, _, V, Out, Flag) => 634 V0 = V,
635 delete_black_node(L,R,Out,Flag).
636
642
643rb_del_min(t(Nil,T), K, Val, NewTree) =>
644 NewTree = t(Nil,NT),
645 del_min(T, K, Val, Nil, NT, _).
646
647del_min(red(black('',_,_,_),K,V,R), K, V, Nil, Out, Flag) :-
648 !,
649 delete_red_node(Nil,R,Out,Flag).
650del_min(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
651 del_min(L, K, V, Nil, NL, Flag0),
652 fixup_left(Flag0,red(NL,K0,V0,R), NT, Flag).
653del_min(black(black('',_,_,_),K,V,R), K, V, Nil, Out, Flag) :-
654 !,
655 delete_black_node(Nil,R,Out,Flag).
656del_min(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
657 del_min(L, K, V, Nil, NL, Flag0),
658 fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag).
659
660
666
667rb_del_max(t(Nil,T), K, Val, NewTree) =>
668 NewTree = t(Nil,NT),
669 del_max(T, K, Val, Nil, NT, _).
670
671del_max(red(L,K,V,black('',_,_,_)), K, V, Nil, Out, Flag) :-
672 !,
673 delete_red_node(L,Nil,Out,Flag).
674del_max(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
675 del_max(R, K, V, Nil, NR, Flag0),
676 fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag).
677del_max(black(L,K,V,black('',_,_,_)), K, V, Nil, Out, Flag) :-
678 !,
679 delete_black_node(L,Nil,Out,Flag).
680del_max(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
681 del_max(R, K, V, Nil, NR, Flag0),
682 fixup_right(Flag0,black(L,K0,V0,NR), NT, Flag).
683
684delete_red_node(L1,L2,L1,done) :- L1 == L2, !.
685delete_red_node(black('',_,_,''),R,R,done) :- !.
686delete_red_node(L,black('',_,_,''),L,done) :- !.
687delete_red_node(L,R,Out,Done) :-
688 delete_next(R,NK,NV,NR,Done0),
689 fixup_right(Done0,red(L,NK,NV,NR),Out,Done).
690
691delete_black_node(L1,L2,L1,not_done) :- L1 == L2, !.
692delete_black_node(black('',_,_,''),red(L,K,V,R),black(L,K,V,R),done) :- !.
693delete_black_node(black('',_,_,''),R,R,not_done) :- !.
694delete_black_node(red(L,K,V,R),black('',_,_,''),black(L,K,V,R),done) :- !.
695delete_black_node(L,black('',_,_,''),L,not_done) :- !.
696delete_black_node(L,R,Out,Done) :-
697 delete_next(R,NK,NV,NR,Done0),
698 fixup_right(Done0,black(L,NK,NV,NR),Out,Done).
699
700delete_next(red(black('',_,_,''),K,V,R),K,V,R,done) :- !.
701delete_next(black(black('',_,_,''),K,V,red(L1,K1,V1,R1)),
702 K,V,black(L1,K1,V1,R1),done) :- !.
703delete_next(black(black('',_,_,''),K,V,R),K,V,R,not_done) :- !.
704delete_next(red(L,K,V,R),K0,V0,Out,Done) :-
705 delete_next(L,K0,V0,NL,Done0),
706 fixup_left(Done0,red(NL,K,V,R),Out,Done).
707delete_next(black(L,K,V,R),K0,V0,Out,Done) :-
708 delete_next(L,K0,V0,NL,Done0),
709 fixup_left(Done0,black(NL,K,V,R),Out,Done).
710
711fixup_left(done,T,T,done).
712fixup_left(not_done,T,NT,Done) :-
713 fixup2(T,NT,Done).
714
719fixup2(black(black(Al,KA,VA,Be),KB,VB,
720 red(black(Ga,KC,VC,De),KD,VD,
721 black(Ep,KE,VE,Fi))),
722 black(T1,KD,VD,black(Ep,KE,VE,Fi)),done) :-
723 !,
724 fixup2(red(black(Al,KA,VA,Be),KB,VB,black(Ga,KC,VC,De)),
725 T1,
726 _).
730fixup2(red(black(Al,KA,VA,Be),KB,VB,
731 black(black(Ga,KC,VC,De),KD,VD,
732 black(Ep,KE,VE,Fi))),
733 black(black(Al,KA,VA,Be),KB,VB,
734 red(black(Ga,KC,VC,De),KD,VD,
735 black(Ep,KE,VE,Fi))),done) :- !.
736fixup2(black(black(Al,KA,VA,Be),KB,VB,
737 black(black(Ga,KC,VC,De),KD,VD,
738 black(Ep,KE,VE,Fi))),
739 black(black(Al,KA,VA,Be),KB,VB,
740 red(black(Ga,KC,VC,De),KD,VD,
741 black(Ep,KE,VE,Fi))),not_done) :- !.
745fixup2(red(black(Al,KA,VA,Be),KB,VB,
746 black(red(Ga,KC,VC,De),KD,VD,
747 black(Ep,KE,VE,Fi))),
748 red(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,
749 black(De,KD,VD,black(Ep,KE,VE,Fi))),
750 done) :- !.
751fixup2(black(black(Al,KA,VA,Be),KB,VB,
752 black(red(Ga,KC,VC,De),KD,VD,
753 black(Ep,KE,VE,Fi))),
754 black(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,
755 black(De,KD,VD,black(Ep,KE,VE,Fi))),
756 done) :- !.
760fixup2(red(black(Al,KA,VA,Be),KB,VB,
761 black(C,KD,VD,red(Ep,KE,VE,Fi))),
762 red(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,
763 black(Ep,KE,VE,Fi)),
764 done).
765fixup2(black(black(Al,KA,VA,Be),KB,VB,
766 black(C,KD,VD,red(Ep,KE,VE,Fi))),
767 black(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,
768 black(Ep,KE,VE,Fi)),
769 done).
770
771fixup_right(done,T,T,done).
772fixup_right(not_done,T,NT,Done) :-
773 fixup3(T,NT,Done).
774
778fixup3(black(red(black(Fi,KE,VE,Ep),KD,VD,
779 black(De,KC,VC,Ga)),KB,VB,
780 black(Be,KA,VA,Al)),
781 black(black(Fi,KE,VE,Ep),KD,VD,T1),done) :-
782 !,
783 fixup3(red(black(De,KC,VC,Ga),KB,VB,
784 black(Be,KA,VA,Al)),T1,_).
785
789fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,
790 black(De,KC,VC,Ga)),KB,VB,
791 black(Be,KA,VA,Al)),
792 black(red(black(Fi,KE,VE,Ep),KD,VD,
793 black(De,KC,VC,Ga)),KB,VB,
794 black(Be,KA,VA,Al)),
795 done) :- !.
796fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,
797 black(De,KC,VC,Ga)),KB,VB,
798 black(Be,KA,VA,Al)),
799 black(red(black(Fi,KE,VE,Ep),KD,VD,
800 black(De,KC,VC,Ga)),KB,VB,
801 black(Be,KA,VA,Al)),
802 not_done):- !.
806fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,
807 red(De,KC,VC,Ga)),KB,VB,
808 black(Be,KA,VA,Al)),
809 red(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,
810 black(Ga,KB,VB,black(Be,KA,VA,Al))),
811 done) :- !.
812fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,
813 red(De,KC,VC,Ga)),KB,VB,
814 black(Be,KA,VA,Al)),
815 black(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,
816 black(Ga,KB,VB,black(Be,KA,VA,Al))),
817 done) :- !.
821fixup3(red(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)),
822 red(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))),
823 done).
824fixup3(black(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)),
825 black(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))),
826 done).
827
832
833:- det(rb_visit/2). 834rb_visit(t(_,T),Lf) =>
835 visit(T,[],Lf).
836
837visit(black('',_,_,_),L0,L) => L0 = L.
838visit(red(L,K,V,R),L0,Lf) =>
839 visit(L,[K-V|L1],Lf),
840 visit(R,L0,L1).
841visit(black(L,K,V,R),L0,Lf) =>
842 visit(L,[K-V|L1],Lf),
843 visit(R,L0,L1).
844
849
850:- det(rb_visit_range/4). 851rb_visit_range(t(_,T), Min, Max, Pairs) =>
852 visit_range(T, Min, Max, [], Pairs).
853
854visit_range(black('',_,_,_), _Min, _Max, L0, Lf) =>
855 L0 = Lf.
856visit_range(red(L,K,V,R), Min, Max, L0, Lf) =>
857 ( K @< Min
858 -> visit_range(R, Min, Max, L0, Lf)
859 ; K @> Max
860 -> visit_range(L, Min, Max, L0, Lf)
861 ; visit_range(L, Min, Max, [K-V|L1], Lf),
862 visit_range(R, Min, Max, L0, L1)
863 ).
864visit_range(black(L,K,V,R), Min, Max, L0, Lf) =>
865 ( K @< Min
866 -> visit_range(R, Min, Max, L0, Lf)
867 ; K @> Max
868 -> visit_range(L, Min, Max, L0, Lf)
869 ; visit_range(L, Min, Max, [K-V|L1], Lf),
870 visit_range(R, Min, Max, L0, L1)
871 ).
872
873:- meta_predicate map(?,2,?,?). 874
884
885rb_map(t(Nil,Tree),Goal,NewTree2) =>
886 NewTree2 = t(Nil,NewTree),
887 map(Tree,Goal,NewTree,Nil).
888
889
890map(black('',_,_,''),_,Nil0,Nil) => Nil0 = Nil.
891map(red(L,K,V,R),Goal,NewTree,Nil) =>
892 NewTree = red(NL,K,NV,NR),
893 call(Goal,V,NV),
894 map(L,Goal,NL,Nil),
895 map(R,Goal,NR,Nil).
896map(black(L,K,V,R),Goal,NewTree,Nil) =>
897 NewTree = black(NL,K,NV,NR),
898 call(Goal,V,NV),
899 map(L,Goal,NL,Nil),
900 map(R,Goal,NR,Nil).
901
902:- meta_predicate map(?,1). 903
907
908rb_map(t(_,Tree),Goal) =>
909 map(Tree,Goal).
910
911
912map(black('',_,_,''),_) => true.
913map(red(L,_,V,R),Goal) =>
914 call(Goal,V),
915 map(L,Goal),
916 map(R,Goal).
917map(black(L,_,V,R),Goal) =>
918 call(Goal,V),
919 map(L,Goal),
920 map(R,Goal).
921
931
932rb_fold(Pred, t(_,T), S1, S2) =>
933 fold(T, Pred, S1, S2).
934
935fold(black(L,K,V,R), Pred) -->
936 ( {L == ''}
937 -> []
938 ; fold_parts(Pred, L, K-V, R)
939 ).
940fold(red(L,K,V,R), Pred) -->
941 fold_parts(Pred, L, K-V, R).
942
943fold_parts(Pred, L, KV, R) -->
944 fold(L, Pred),
945 call(Pred, KV),
946 fold(R, Pred).
947
953
954:- det(rb_clone/3). 955rb_clone(t(Nil,T),TreeOut,Ns) =>
956 TreeOut = t(Nil,NT),
957 clone(T,Nil,NT,Ns,[]).
958
959clone(black('',_,_,''),Nil0,Nil,Ns0,Ns) => Nil0=Nil, Ns0=Ns.
960clone(red(L,K,_,R),Nil,TreeOut,NsF,Ns0) =>
961 TreeOut = red(NL,K,NV,NR),
962 clone(L,Nil,NL,NsF,[K-NV|Ns1]),
963 clone(R,Nil,NR,Ns1,Ns0).
964clone(black(L,K,_,R),Nil,TreeOut,NsF,Ns0) =>
965 TreeOut = black(NL,K,NV,NR),
966 clone(L,Nil,NL,NsF,[K-NV|Ns1]),
967 clone(R,Nil,NR,Ns1,Ns0).
968
977
978rb_partial_map(t(Nil,T0), Map, Goal, NewTree) =>
979 NewTree = t(Nil,TF),
980 partial_map(T0, Map, [], Nil, Goal, TF).
981
982partial_map(T,[],[],_,_,T) :- !.
983partial_map(black('',_,_,_),Map,Map,Nil,_,Nil) :- !.
984partial_map(red(L,K,V,R),Map,MapF,Nil,Goal,red(NL,K,NV,NR)) :-
985 partial_map(L,Map,MapI,Nil,Goal,NL),
986 ( MapI == []
987 -> NR = R, NV = V, MapF = []
988 ; MapI = [K1|MapR],
989 ( K == K1
990 -> ( call(Goal,V,NV)
991 -> true
992 ; NV = V
993 ),
994 MapN = MapR
995 ; NV = V,
996 MapN = MapI
997 ),
998 partial_map(R,MapN,MapF,Nil,Goal,NR)
999 ).
1000partial_map(black(L,K,V,R),Map,MapF,Nil,Goal,black(NL,K,NV,NR)) :-
1001 partial_map(L,Map,MapI,Nil,Goal,NL),
1002 ( MapI == []
1003 -> NR = R, NV = V, MapF = []
1004 ; MapI = [K1|MapR],
1005 ( K == K1
1006 -> ( call(Goal,V,NV)
1007 -> true
1008 ; NV = V
1009 ),
1010 MapN = MapR
1011 ; NV = V,
1012 MapN = MapI
1013 ),
1014 partial_map(R,MapN,MapF,Nil,Goal,NR)
1015 ).
1016
1017
1022
1023:- det(rb_keys/2). 1024rb_keys(t(_,T),Lf) =>
1025 keys(T,[],Lf).
1026
1027keys(black('',_,_,''),L0,L) => L0 = L.
1028keys(red(L,K,_,R),L0,Lf) =>
1029 keys(L,[K|L1],Lf),
1030 keys(R,L0,L1).
1031keys(black(L,K,_,R),L0,Lf) =>
1032 keys(L,[K|L1],Lf),
1033 keys(R,L0,L1).
1034
1035
1042
1043:- det(list_to_rbtree/2). 1044list_to_rbtree(List, T) :-
1045 sort(List,Sorted),
1046 ord_list_to_rbtree(Sorted, T).
1047
1055
1056:- det(ord_list_to_rbtree/2). 1057ord_list_to_rbtree([], Tree) =>
1058 Tree = t(Nil,Nil),
1059 Nil = black('', _, _, '').
1060ord_list_to_rbtree([K-V], Tree) =>
1061 Tree = t(Nil,black(Nil,K,V,Nil)),
1062 Nil = black('', _, _, '').
1063ord_list_to_rbtree(List, Tree2) =>
1064 Tree2 = t(Nil,Tree),
1065 Nil = black('', _, _, ''),
1066 Ar =.. [seq|List],
1067 functor(Ar,_,L),
1068 Height is truncate(log(L)/log(2)),
1069 construct_rbtree(1, L, Ar, Height, Nil, Tree).
1070
1071construct_rbtree(L, M, _, _, Nil, Nil) :- M < L, !.
1072construct_rbtree(L, L, Ar, Depth, Nil, Node) :-
1073 !,
1074 arg(L, Ar, K-Val),
1075 build_node(Depth, Nil, K, Val, Nil, Node).
1076construct_rbtree(I0, Max, Ar, Depth, Nil, Node) :-
1077 I is (I0+Max)//2,
1078 arg(I, Ar, K-Val),
1079 build_node(Depth, Left, K, Val, Right, Node),
1080 I1 is I-1,
1081 NewDepth is Depth-1,
1082 construct_rbtree(I0, I1, Ar, NewDepth, Nil, Left),
1083 I2 is I+1,
1084 construct_rbtree(I2, Max, Ar, NewDepth, Nil, Right).
1085
1086build_node( 0, Left, K, Val, Right, red(Left, K, Val, Right)) :- !.
1087build_node( _, Left, K, Val, Right, black(Left, K, Val, Right)).
1088
1089
1093
1094:- det(rb_size/2). 1095rb_size(t(_,T),Size) =>
1096 size(T,0,Size).
1097
1098size(black('',_,_,_),Sz,Sz) :- !.
1099size(red(L,_,_,R),Sz0,Szf) :-
1100 Sz1 is Sz0+1,
1101 size(L,Sz1,Sz2),
1102 size(R,Sz2,Szf).
1103size(black(L,_,_,R),Sz0,Szf) :-
1104 Sz1 is Sz0+1,
1105 size(L,Sz1,Sz2),
1106 size(R,Sz2,Szf).
1107
1114
1115is_rbtree(X), var(X) =>
1116 fail.
1117is_rbtree(t(Nil,Nil)) => true.
1118is_rbtree(t(_,T)) =>
1119 Err = error(_,_),
1120 catch(check_rbtree(T), Err, is_rbtree_error(Err)).
1121is_rbtree(_) =>
1122 fail.
1123
1124is_rbtree_error(Err), Err = error(resource_error(_),_) => throw(Err).
1125is_rbtree_error(_) => fail.
1126
1128
1129check_rbtree(black(L,K,_,R)) =>
1130 find_path_blacks(L, 0, Bls),
1131 check_rbtree(L,-inf,K,Bls),
1132 check_rbtree(R,K,+inf,Bls).
1133check_rbtree(Node), Node = red(_,_,_,_) =>
1134 domain_error(rb_black, Node).
1135
1136
1137find_path_blacks(black('',_,_,''), Bls0, Bls) => Bls = Bls0.
1138find_path_blacks(black(L,_,_,_), Bls0, Bls) =>
1139 Bls1 is Bls0+1,
1140 find_path_blacks(L, Bls1, Bls).
1141find_path_blacks(red(L,_,_,_), Bls0, Bls) =>
1142 find_path_blacks(L, Bls0, Bls).
1143
1144check_rbtree(black('',_,_,''),Min,Max,Bls0) =>
1145 check_height(Bls0,Min,Max).
1146check_rbtree(red(L,K,_,R),Min,Max,Bls) =>
1147 check_val(K,Min,Max),
1148 check_red_child(L),
1149 check_red_child(R),
1150 check_rbtree(L,Min,K,Bls),
1151 check_rbtree(R,K,Max,Bls).
1152check_rbtree(black(L,K,_,R),Min,Max,Bls0) =>
1153 check_val(K,Min,Max),
1154 Bls is Bls0-1,
1155 check_rbtree(L,Min,K,Bls),
1156 check_rbtree(R,K,Max,Bls).
1157
1158check_height(0,_,_) => true.
1159check_height(Bls0,Min,Max) =>
1160 throw(error(rbtree(balance(Bls0, Min, Max)), _)).
1161
1162check_val(K, Min, Max), (K @> Min ; Min == -inf), (K @< Max ; Max == +inf) =>
1163 true.
1164check_val(K, Min, Max) =>
1165 throw(error(rbtree(order(K, Min, Max)), _)).
1166
1167check_red_child(black(_,_,_,_)) => true.
1168check_red_child(Node), Node = red(_,_,_,_) =>
1169 domain_error(rb_black, Node).
1170
1171
1172 1175
1176:- multifile
1177 prolog:error_message//1. 1178
1179prolog:error_message(rbtree(balance(Bls0, Min, Max))) -->
1180 [ 'Unbalance ~d between ~w and ~w'-[Bls0,Min,Max] ].
1181prolog:error_message(rbtree(order(K, Min, Max))) -->
1182 [ 'not ordered: ~w not between ~w and ~w'-[K,Min,Max] ]