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_keys/2, 48 rb_map/2, 49 rb_map/3, 50 rb_partial_map/4, 51 rb_fold/4, 52 rb_clone/3, 53 rb_min/3, 54 rb_max/3, 55 rb_del_min/4, 56 rb_del_max/4, 57 rb_next/4, 58 rb_previous/4, 59 list_to_rbtree/2, 60 ord_list_to_rbtree/2, 61 is_rbtree/1, 62 rb_size/2, 63 rb_in/3 64 ]). 65
83
84:- meta_predicate
85 rb_map(+,:,-),
86 rb_partial_map(+,+,:,-),
87 rb_apply(+,+,:,-),
88 rb_fold(3,+,+,-). 89
112
118
119rb_new(t(Nil,Nil)) :-
120 Nil = black('',_,_,'').
121
125
126rb_empty(t(Nil,Nil)) :-
127 Nil = black('',_,_,'').
128
135
136rb_lookup(Key, Val, t(_,Tree)) :-
137 lookup(Key, Val, Tree).
138
139lookup(_, _, black('',_,_,'')) :- !, fail.
140lookup(Key, Val, Tree) :-
141 arg(2,Tree,KA),
142 compare(Cmp,KA,Key),
143 lookup(Cmp,Key,Val,Tree).
144
145lookup(>, K, V, Tree) :-
146 arg(1,Tree,NTree),
147 lookup(K, V, NTree).
148lookup(<, K, V, Tree) :-
149 arg(4,Tree,NTree),
150 lookup(K, V, NTree).
151lookup(=, _, V, Tree) :-
152 arg(3,Tree,V).
153
157
158rb_min(t(_,Tree), Key, Val) :-
159 min(Tree, Key, Val).
160
161min(red(black('',_,_,_),Key,Val,_), Key, Val) :- !.
162min(black(black('',_,_,_),Key,Val,_), Key, Val) :- !.
163min(red(Right,_,_,_), Key, Val) :-
164 min(Right,Key,Val).
165min(black(Right,_,_,_), Key, Val) :-
166 min(Right,Key,Val).
167
171
172rb_max(t(_,Tree), Key, Val) :-
173 max(Tree, Key, Val).
174
175max(red(_,Key,Val,black('',_,_,_)), Key, Val) :- !.
176max(black(_,Key,Val,black('',_,_,_)), Key, Val) :- !.
177max(red(_,_,_,Left), Key, Val) :-
178 max(Left,Key,Val).
179max(black(_,_,_,Left), Key, Val) :-
180 max(Left,Key,Val).
181
186
187rb_next(t(_,Tree), Key, Next, Val) :-
188 next(Tree, Key, Next, Val, []).
189
190next(black('',_,_,''), _, _, _, _) :- !, fail.
191next(Tree, Key, Next, Val, Candidate) :-
192 arg(2,Tree,KA),
193 arg(3,Tree,VA),
194 compare(Cmp,KA,Key),
195 next(Cmp, Key, KA, VA, Next, Val, Tree, Candidate).
196
197next(>, K, KA, VA, NK, V, Tree, _) :-
198 arg(1,Tree,NTree),
199 next(NTree,K,NK,V,KA-VA).
200next(<, K, _, _, NK, V, Tree, Candidate) :-
201 arg(4,Tree,NTree),
202 next(NTree,K,NK,V,Candidate).
203next(=, _, _, _, NK, Val, Tree, Candidate) :-
204 arg(4,Tree,NTree),
205 ( min(NTree, NK, Val)
206 -> true
207 ; Candidate = (NK-Val)
208 ).
209
214
215rb_previous(t(_,Tree), Key, Previous, Val) :-
216 previous(Tree, Key, Previous, Val, []).
217
218previous(black('',_,_,''), _, _, _, _) :- !, fail.
219previous(Tree, Key, Previous, Val, Candidate) :-
220 arg(2,Tree,KA),
221 arg(3,Tree,VA),
222 compare(Cmp,KA,Key),
223 previous(Cmp, Key, KA, VA, Previous, Val, Tree, Candidate).
224
225previous(>, K, _, _, NK, V, Tree, Candidate) :-
226 arg(1,Tree,NTree),
227 previous(NTree,K,NK,V,Candidate).
228previous(<, K, KA, VA, NK, V, Tree, _) :-
229 arg(4,Tree,NTree),
230 previous(NTree,K,NK,V,KA-VA).
231previous(=, _, _, _, K, Val, Tree, Candidate) :-
232 arg(1,Tree,NTree),
233 ( max(NTree, K, Val)
234 -> true
235 ; Candidate = (K-Val)
236 ).
237
243
244rb_update(t(Nil,OldTree), Key, OldVal, Val, t(Nil,NewTree)) :-
245 update(OldTree, Key, OldVal, Val, NewTree).
246
247rb_update(t(Nil,OldTree), Key, Val, t(Nil,NewTree)) :-
248 update(OldTree, Key, _, Val, NewTree).
249
250update(black(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :-
251 Left \= [],
252 compare(Cmp,Key0,Key),
253 ( Cmp == (=)
254 -> OldVal = Val0,
255 NewTree = black(Left,Key0,Val,Right)
256 ; Cmp == (>)
257 -> NewTree = black(NewLeft,Key0,Val0,Right),
258 update(Left, Key, OldVal, Val, NewLeft)
259 ; NewTree = black(Left,Key0,Val0,NewRight),
260 update(Right, Key, OldVal, Val, NewRight)
261 ).
262update(red(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :-
263 compare(Cmp,Key0,Key),
264 ( Cmp == (=)
265 -> OldVal = Val0,
266 NewTree = red(Left,Key0,Val,Right)
267 ; Cmp == (>)
268 -> NewTree = red(NewLeft,Key0,Val0,Right),
269 update(Left, Key, OldVal, Val, NewLeft)
270 ; NewTree = red(Left,Key0,Val0,NewRight),
271 update(Right, Key, OldVal, Val, NewRight)
272 ).
273
280
281rb_apply(t(Nil,OldTree), Key, Goal, t(Nil,NewTree)) :-
282 apply(OldTree, Key, Goal, NewTree).
283
285apply(black(Left,Key0,Val0,Right), Key, Goal,
286 black(NewLeft,Key0,Val,NewRight)) :-
287 Left \= [],
288 compare(Cmp,Key0,Key),
289 ( Cmp == (=)
290 -> NewLeft = Left,
291 NewRight = Right,
292 call(Goal,Val0,Val)
293 ; Cmp == (>)
294 -> NewRight = Right,
295 Val = Val0,
296 apply(Left, Key, Goal, NewLeft)
297 ; NewLeft = Left,
298 Val = Val0,
299 apply(Right, Key, Goal, NewRight)
300 ).
301apply(red(Left,Key0,Val0,Right), Key, Goal,
302 red(NewLeft,Key0,Val,NewRight)) :-
303 compare(Cmp,Key0,Key),
304 ( Cmp == (=)
305 -> NewLeft = Left,
306 NewRight = Right,
307 call(Goal,Val0,Val)
308 ; Cmp == (>)
309 -> NewRight = Right,
310 Val = Val0,
311 apply(Left, Key, Goal, NewLeft)
312 ; NewLeft = Left,
313 Val = Val0,
314 apply(Right, Key, Goal, NewRight)
315 ).
316
323
324rb_in(Key, Val, t(_,T)) :-
325 enum(Key, Val, T).
326
327enum(Key, Val, black(L,K,V,R)) :-
328 L \= '',
329 enum_cases(Key, Val, L, K, V, R).
330enum(Key, Val, red(L,K,V,R)) :-
331 enum_cases(Key, Val, L, K, V, R).
332
333enum_cases(Key, Val, L, _, _, _) :-
334 enum(Key, Val, L).
335enum_cases(Key, Val, _, Key, Val, _).
336enum_cases(Key, Val, _, _, _, R) :-
337 enum(Key, Val, R).
338
339
340
341 344
346
352
353rb_insert(t(Nil,Tree0),Key,Val,t(Nil,Tree)) :-
354 insert(Tree0,Key,Val,Nil,Tree).
355
356
357insert(Tree0,Key,Val,Nil,Tree) :-
358 insert2(Tree0,Key,Val,Nil,TreeI,_),
359 fix_root(TreeI,Tree).
360
378
379
380
384insert2(black('',_,_,''), K, V, Nil, T, Status) :-
385 !,
386 T = red(Nil,K,V,Nil),
387 Status = not_done.
388insert2(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
389 ( K @< K0
390 -> NT = red(NL,K0,V0,R),
391 insert2(L, K, V, Nil, NL, Flag)
392 ; K == K0
393 -> NT = red(L,K0,V,R),
394 Flag = done
395 ; NT = red(L,K0,V0,NR),
396 insert2(R, K, V, Nil, NR, Flag)
397 ).
398insert2(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
399 ( K @< K0
400 -> insert2(L, K, V, Nil, IL, Flag0),
401 fix_left(Flag0, black(IL,K0,V0,R), NT, Flag)
402 ; K == K0
403 -> NT = black(L,K0,V,R),
404 Flag = done
405 ; insert2(R, K, V, Nil, IR, Flag0),
406 fix_right(Flag0, black(L,K0,V0,IR), NT, Flag)
407 ).
408
410
415
416rb_insert_new(t(Nil,Tree0),Key,Val,t(Nil,Tree)) :-
417 insert_new(Tree0,Key,Val,Nil,Tree).
418
419insert_new(Tree0,Key,Val,Nil,Tree) :-
420 insert_new_2(Tree0,Key,Val,Nil,TreeI,_),
421 fix_root(TreeI,Tree).
422
426insert_new_2(black('',_,_,''), K, V, Nil, T, Status) :-
427 !,
428 T = red(Nil,K,V,Nil),
429 Status = not_done.
430insert_new_2(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
431 ( K @< K0
432 -> NT = red(NL,K0,V0,R),
433 insert_new_2(L, K, V, Nil, NL, Flag)
434 ; K == K0
435 -> fail
436 ; NT = red(L,K0,V0,NR),
437 insert_new_2(R, K, V, Nil, NR, Flag)
438 ).
439insert_new_2(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
440 ( K @< K0
441 -> insert_new_2(L, K, V, Nil, IL, Flag0),
442 fix_left(Flag0, black(IL,K0,V0,R), NT, Flag)
443 ; K == K0
444 -> fail
445 ; insert_new_2(R, K, V, Nil, IR, Flag0),
446 fix_right(Flag0, black(L,K0,V0,IR), NT, Flag)
447 ).
448
452fix_root(black(L,K,V,R),black(L,K,V,R)).
453fix_root(red(L,K,V,R),black(L,K,V,R)).
454
458fix_left(done,T,T,done) :- !.
459fix_left(not_done,Tmp,Final,Done) :-
460 fix_left(Tmp,Final,Done).
461
465fix_left(black(red(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,red(De,KD,VD,Ep)),
466 red(black(Al,AK,AV,red(Be,BK,BV,Ga)),KC,VC,black(De,KD,VD,Ep)),
467 not_done) :- !.
468fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,red(De,KD,VD,Ep)),
469 red(black(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,black(De,KD,VD,Ep)),
470 not_done) :- !.
474fix_left(black(red(Al,KA,VA,red(Be,KB,VB,Ga)),KC,VC,De),
475 black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)),
476 done) :- !.
480fix_left(black(red(red(Al,KA,VA,Be),KB,VB,Ga),KC,VC,De),
481 black(red(Al,KA,VA,Be),KB,VB,red(Ga,KC,VC,De)),
482 done) :- !.
486fix_left(T,T,done).
487
491fix_right(done,T,T,done) :- !.
492fix_right(not_done,Tmp,Final,Done) :-
493 fix_right(Tmp,Final,Done).
494
498fix_right(black(red(Ep,KD,VD,De),KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)),
499 red(black(Ep,KD,VD,De),KC,VC,black(red(Ga,KB,VB,Be),KA,VA,Al)),
500 not_done) :- !.
501fix_right(black(red(Ep,KD,VD,De),KC,VC,red(Ga,Ka,Va,red(Be,KB,VB,Al))),
502 red(black(Ep,KD,VD,De),KC,VC,black(Ga,Ka,Va,red(Be,KB,VB,Al))),
503 not_done) :- !.
507fix_right(black(De,KC,VC,red(red(Ga,KB,VB,Be),KA,VA,Al)),
508 black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)),
509 done) :- !.
513fix_right(black(De,KC,VC,red(Ga,KB,VB,red(Be,KA,VA,Al))),
514 black(red(De,KC,VC,Ga),KB,VB,red(Be,KA,VA,Al)),
515 done) :- !.
519fix_right(T,T,done).
520
521
527
528rb_delete(t(Nil,T), K, t(Nil,NT)) :-
529 delete(T, K, _, NT, _).
530
531rb_delete(t(Nil,T), K, V, t(Nil,NT)) :-
532 delete(T, K, V0, NT, _),
533 V = V0.
534
538delete(red(L,K0,V0,R), K, V, NT, Flag) :-
539 K @< K0,
540 !,
541 delete(L, K, V, NL, Flag0),
542 fixup_left(Flag0,red(NL,K0,V0,R),NT, Flag).
543delete(red(L,K0,V0,R), K, V, NT, Flag) :-
544 K @> K0,
545 !,
546 delete(R, K, V, NR, Flag0),
547 fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag).
548delete(red(L,_,V,R), _, V, OUT, Flag) :-
549 550 delete_red_node(L,R,OUT,Flag).
551delete(black(L,K0,V0,R), K, V, NT, Flag) :-
552 K @< K0,
553 !,
554 delete(L, K, V, NL, Flag0),
555 fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag).
556delete(black(L,K0,V0,R), K, V, NT, Flag) :-
557 K @> K0,
558 !,
559 delete(R, K, V, NR, Flag0),
560 fixup_right(Flag0,black(L,K0,V0,NR),NT, Flag).
561delete(black(L,_,V,R), _, V, OUT, Flag) :-
562 563 delete_black_node(L,R,OUT,Flag).
564
569
570rb_del_min(t(Nil,T), K, Val, t(Nil,NT)) :-
571 del_min(T, K, Val, Nil, NT, _).
572
573del_min(red(black('',_,_,_),K,V,R), K, V, Nil, OUT, Flag) :-
574 !,
575 delete_red_node(Nil,R,OUT,Flag).
576del_min(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
577 del_min(L, K, V, Nil, NL, Flag0),
578 fixup_left(Flag0,red(NL,K0,V0,R), NT, Flag).
579del_min(black(black('',_,_,_),K,V,R), K, V, Nil, OUT, Flag) :-
580 !,
581 delete_black_node(Nil,R,OUT,Flag).
582del_min(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
583 del_min(L, K, V, Nil, NL, Flag0),
584 fixup_left(Flag0,black(NL,K0,V0,R),NT, Flag).
585
586
591
592rb_del_max(t(Nil,T), K, Val, t(Nil,NT)) :-
593 del_max(T, K, Val, Nil, NT, _).
594
595del_max(red(L,K,V,black('',_,_,_)), K, V, Nil, OUT, Flag) :-
596 !,
597 delete_red_node(L,Nil,OUT,Flag).
598del_max(red(L,K0,V0,R), K, V, Nil, NT, Flag) :-
599 del_max(R, K, V, Nil, NR, Flag0),
600 fixup_right(Flag0,red(L,K0,V0,NR),NT, Flag).
601del_max(black(L,K,V,black('',_,_,_)), K, V, Nil, OUT, Flag) :-
602 !,
603 delete_black_node(L,Nil,OUT,Flag).
604del_max(black(L,K0,V0,R), K, V, Nil, NT, Flag) :-
605 del_max(R, K, V, Nil, NR, Flag0),
606 fixup_right(Flag0,black(L,K0,V0,NR), NT, Flag).
607
608delete_red_node(L1,L2,L1,done) :- L1 == L2, !.
609delete_red_node(black('',_,_,''),R,R,done) :- !.
610delete_red_node(L,black('',_,_,''),L,done) :- !.
611delete_red_node(L,R,OUT,Done) :-
612 delete_next(R,NK,NV,NR,Done0),
613 fixup_right(Done0,red(L,NK,NV,NR),OUT,Done).
614
615delete_black_node(L1,L2,L1,not_done) :- L1 == L2, !.
616delete_black_node(black('',_,_,''),red(L,K,V,R),black(L,K,V,R),done) :- !.
617delete_black_node(black('',_,_,''),R,R,not_done) :- !.
618delete_black_node(red(L,K,V,R),black('',_,_,''),black(L,K,V,R),done) :- !.
619delete_black_node(L,black('',_,_,''),L,not_done) :- !.
620delete_black_node(L,R,OUT,Done) :-
621 delete_next(R,NK,NV,NR,Done0),
622 fixup_right(Done0,black(L,NK,NV,NR),OUT,Done).
623
624delete_next(red(black('',_,_,''),K,V,R),K,V,R,done) :- !.
625delete_next(black(black('',_,_,''),K,V,red(L1,K1,V1,R1)),
626 K,V,black(L1,K1,V1,R1),done) :- !.
627delete_next(black(black('',_,_,''),K,V,R),K,V,R,not_done) :- !.
628delete_next(red(L,K,V,R),K0,V0,OUT,Done) :-
629 delete_next(L,K0,V0,NL,Done0),
630 fixup_left(Done0,red(NL,K,V,R),OUT,Done).
631delete_next(black(L,K,V,R),K0,V0,OUT,Done) :-
632 delete_next(L,K0,V0,NL,Done0),
633 fixup_left(Done0,black(NL,K,V,R),OUT,Done).
634
635fixup_left(done,T,T,done).
636fixup_left(not_done,T,NT,Done) :-
637 fixup2(T,NT,Done).
638
643fixup2(black(black(Al,KA,VA,Be),KB,VB,
644 red(black(Ga,KC,VC,De),KD,VD,
645 black(Ep,KE,VE,Fi))),
646 black(T1,KD,VD,black(Ep,KE,VE,Fi)),done) :-
647 !,
648 fixup2(red(black(Al,KA,VA,Be),KB,VB,black(Ga,KC,VC,De)),
649 T1,
650 _).
654fixup2(red(black(Al,KA,VA,Be),KB,VB,
655 black(black(Ga,KC,VC,De),KD,VD,
656 black(Ep,KE,VE,Fi))),
657 black(black(Al,KA,VA,Be),KB,VB,
658 red(black(Ga,KC,VC,De),KD,VD,
659 black(Ep,KE,VE,Fi))),done) :- !.
660fixup2(black(black(Al,KA,VA,Be),KB,VB,
661 black(black(Ga,KC,VC,De),KD,VD,
662 black(Ep,KE,VE,Fi))),
663 black(black(Al,KA,VA,Be),KB,VB,
664 red(black(Ga,KC,VC,De),KD,VD,
665 black(Ep,KE,VE,Fi))),not_done) :- !.
669fixup2(red(black(Al,KA,VA,Be),KB,VB,
670 black(red(Ga,KC,VC,De),KD,VD,
671 black(Ep,KE,VE,Fi))),
672 red(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,
673 black(De,KD,VD,black(Ep,KE,VE,Fi))),
674 done) :- !.
675fixup2(black(black(Al,KA,VA,Be),KB,VB,
676 black(red(Ga,KC,VC,De),KD,VD,
677 black(Ep,KE,VE,Fi))),
678 black(black(black(Al,KA,VA,Be),KB,VB,Ga),KC,VC,
679 black(De,KD,VD,black(Ep,KE,VE,Fi))),
680 done) :- !.
684fixup2(red(black(Al,KA,VA,Be),KB,VB,
685 black(C,KD,VD,red(Ep,KE,VE,Fi))),
686 red(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,
687 black(Ep,KE,VE,Fi)),
688 done).
689fixup2(black(black(Al,KA,VA,Be),KB,VB,
690 black(C,KD,VD,red(Ep,KE,VE,Fi))),
691 black(black(black(Al,KA,VA,Be),KB,VB,C),KD,VD,
692 black(Ep,KE,VE,Fi)),
693 done).
694
695fixup_right(done,T,T,done).
696fixup_right(not_done,T,NT,Done) :-
697 fixup3(T,NT,Done).
698
702fixup3(black(red(black(Fi,KE,VE,Ep),KD,VD,
703 black(De,KC,VC,Ga)),KB,VB,
704 black(Be,KA,VA,Al)),
705 black(black(Fi,KE,VE,Ep),KD,VD,T1),done) :-
706 !,
707 fixup3(red(black(De,KC,VC,Ga),KB,VB,
708 black(Be,KA,VA,Al)),T1,_).
709
713fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,
714 black(De,KC,VC,Ga)),KB,VB,
715 black(Be,KA,VA,Al)),
716 black(red(black(Fi,KE,VE,Ep),KD,VD,
717 black(De,KC,VC,Ga)),KB,VB,
718 black(Be,KA,VA,Al)),
719 done) :- !.
720fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,
721 black(De,KC,VC,Ga)),KB,VB,
722 black(Be,KA,VA,Al)),
723 black(red(black(Fi,KE,VE,Ep),KD,VD,
724 black(De,KC,VC,Ga)),KB,VB,
725 black(Be,KA,VA,Al)),
726 not_done):- !.
730fixup3(red(black(black(Fi,KE,VE,Ep),KD,VD,
731 red(De,KC,VC,Ga)),KB,VB,
732 black(Be,KA,VA,Al)),
733 red(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,
734 black(Ga,KB,VB,black(Be,KA,VA,Al))),
735 done) :- !.
736fixup3(black(black(black(Fi,KE,VE,Ep),KD,VD,
737 red(De,KC,VC,Ga)),KB,VB,
738 black(Be,KA,VA,Al)),
739 black(black(black(Fi,KE,VE,Ep),KD,VD,De),KC,VC,
740 black(Ga,KB,VB,black(Be,KA,VA,Al))),
741 done) :- !.
745fixup3(red(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)),
746 red(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))),
747 done).
748fixup3(black(black(red(Fi,KE,VE,Ep),KD,VD,C),KB,VB,black(Be,KA,VA,Al)),
749 black(black(Fi,KE,VE,Ep),KD,VD,black(C,KB,VB,black(Be,KA,VA,Al))),
750 done).
751
756
757rb_visit(t(_,T),Lf) :-
758 visit(T,[],Lf).
759
760visit(black('',_,_,_),L,L) :- !.
761visit(red(L,K,V,R),L0,Lf) :-
762 visit(L,[K-V|L1],Lf),
763 visit(R,L0,L1).
764visit(black(L,K,V,R),L0,Lf) :-
765 visit(L,[K-V|L1],Lf),
766 visit(R,L0,L1).
767
768:- meta_predicate rb_map(?,:,?). 769:- meta_predicate map(?,:,?,?). 770
774
775rb_map(t(Nil,Tree),Goal,t(Nil,NewTree)) :-
776 map(Tree,Goal,NewTree,Nil).
777
778
779map(black('',_,_,''),_,Nil,Nil) :- !.
780map(red(L,K,V,R),Goal,red(NL,K,NV,NR),Nil) :-
781 call(Goal,V,NV),
782 !,
783 map(L,Goal,NL,Nil),
784 map(R,Goal,NR,Nil).
785map(black(L,K,V,R),Goal,black(NL,K,NV,NR),Nil) :-
786 call(Goal,V,NV),
787 !,
788 map(L,Goal,NL,Nil),
789 map(R,Goal,NR,Nil).
790
791:- meta_predicate rb_map(?,:). 792:- meta_predicate map(?,:). 793
800
801rb_map(t(_,Tree),Goal) :-
802 map(Tree,Goal).
803
804
805map(black('',_,_,''),_) :- !.
806map(red(L,_,V,R),Goal) :-
807 call(Goal,V),
808 !,
809 map(L,Goal),
810 map(R,Goal).
811map(black(L,_,V,R),Goal) :-
812 call(Goal,V),
813 !,
814 map(L,Goal),
815 map(R,Goal).
816
824
825rb_fold(Pred, t(_,T), S1, S2) :-
826 fold(T, Pred, S1, S2).
827
828fold(black(L,K,V,R), Pred) -->
829 ( {L == ''}
830 -> []
831 ; fold_parts(Pred, L, K-V, R)
832 ).
833fold(red(L,K,V,R), Pred) -->
834 fold_parts(Pred, L, K-V, R).
835
836fold_parts(Pred, L, KV, R) -->
837 fold(L, Pred),
838 call(Pred, KV),
839 fold(R, Pred).
840
846
847rb_clone(t(Nil,T),t(Nil,NT),Ns) :-
848 clone(T,Nil,NT,Ns,[]).
849
850clone(black('',_,_,''),Nil,Nil,Ns,Ns) :- !.
851clone(red(L,K,_,R),Nil,red(NL,K,NV,NR),NsF,Ns0) :-
852 clone(L,Nil,NL,NsF,[K-NV|Ns1]),
853 clone(R,Nil,NR,Ns1,Ns0).
854clone(black(L,K,_,R),Nil,black(NL,K,NV,NR),NsF,Ns0) :-
855 clone(L,Nil,NL,NsF,[K-NV|Ns1]),
856 clone(R,Nil,NR,Ns1,Ns0).
857
865
866rb_partial_map(t(Nil,T0), Map, Goal, t(Nil,TF)) :-
867 partial_map(T0, Map, [], Nil, Goal, TF).
868
869partial_map(T,[],[],_,_,T) :- !.
870partial_map(black('',_,_,_),Map,Map,Nil,_,Nil) :- !.
871partial_map(red(L,K,V,R),Map,MapF,Nil,Goal,red(NL,K,NV,NR)) :-
872 partial_map(L,Map,MapI,Nil,Goal,NL),
873 ( MapI == []
874 -> NR = R, NV = V, MapF = []
875 ; MapI = [K1|MapR],
876 ( K == K1
877 -> ( call(Goal,V,NV)
878 -> true
879 ; NV = V
880 ),
881 MapN = MapR
882 ; NV = V,
883 MapN = MapI
884 ),
885 partial_map(R,MapN,MapF,Nil,Goal,NR)
886 ).
887partial_map(black(L,K,V,R),Map,MapF,Nil,Goal,black(NL,K,NV,NR)) :-
888 partial_map(L,Map,MapI,Nil,Goal,NL),
889 ( MapI == []
890 -> NR = R, NV = V, MapF = []
891 ; MapI = [K1|MapR],
892 ( K == K1
893 -> ( call(Goal,V,NV)
894 -> true
895 ; NV = V
896 ),
897 MapN = MapR
898 ; NV = V,
899 MapN = MapI
900 ),
901 partial_map(R,MapN,MapF,Nil,Goal,NR)
902 ).
903
904
909
910rb_keys(t(_,T),Lf) :-
911 keys(T,[],Lf).
912
913keys(black('',_,_,''),L,L) :- !.
914keys(red(L,K,_,R),L0,Lf) :-
915 keys(L,[K|L1],Lf),
916 keys(R,L0,L1).
917keys(black(L,K,_,R),L0,Lf) :-
918 keys(L,[K|L1],Lf),
919 keys(R,L0,L1).
920
921
927
928list_to_rbtree(List, T) :-
929 sort(List,Sorted),
930 ord_list_to_rbtree(Sorted, T).
931
938
939ord_list_to_rbtree([], t(Nil,Nil)) :-
940 !,
941 Nil = black('', _, _, '').
942ord_list_to_rbtree([K-V], t(Nil,black(Nil,K,V,Nil))) :-
943 !,
944 Nil = black('', _, _, '').
945ord_list_to_rbtree(List, t(Nil,Tree)) :-
946 Nil = black('', _, _, ''),
947 Ar =.. [seq|List],
948 functor(Ar,_,L),
949 Height is truncate(log(L)/log(2)),
950 construct_rbtree(1, L, Ar, Height, Nil, Tree).
951
952construct_rbtree(L, M, _, _, Nil, Nil) :- M < L, !.
953construct_rbtree(L, L, Ar, Depth, Nil, Node) :-
954 !,
955 arg(L, Ar, K-Val),
956 build_node(Depth, Nil, K, Val, Nil, Node).
957construct_rbtree(I0, Max, Ar, Depth, Nil, Node) :-
958 I is (I0+Max)//2,
959 arg(I, Ar, K-Val),
960 build_node(Depth, Left, K, Val, Right, Node),
961 I1 is I-1,
962 NewDepth is Depth-1,
963 construct_rbtree(I0, I1, Ar, NewDepth, Nil, Left),
964 I2 is I+1,
965 construct_rbtree(I2, Max, Ar, NewDepth, Nil, Right).
966
967build_node( 0, Left, K, Val, Right, red(Left, K, Val, Right)) :- !.
968build_node( _, Left, K, Val, Right, black(Left, K, Val, Right)).
969
970
974
975rb_size(t(_,T),Size) :-
976 size(T,0,Size).
977
978size(black('',_,_,_),Sz,Sz) :- !.
979size(red(L,_,_,R),Sz0,Szf) :-
980 Sz1 is Sz0+1,
981 size(L,Sz1,Sz2),
982 size(R,Sz2,Szf).
983size(black(L,_,_,R),Sz0,Szf) :-
984 Sz1 is Sz0+1,
985 size(L,Sz1,Sz2),
986 size(R,Sz2,Szf).
987
993
994is_rbtree(X) :-
995 var(X), !, fail.
996is_rbtree(t(Nil,Nil)) :- !.
997is_rbtree(t(_,T)) :-
998 catch(rbtree1(T), msg(_,_), fail).
999
1003
1004rbtree1(black(L,K,_,R)) :-
1005 find_path_blacks(L, 0, Bls),
1006 check_rbtree(L,-inf,K,Bls),
1007 check_rbtree(R,K,+inf,Bls).
1008rbtree1(red(_,_,_,_)) :-
1009 throw(msg("root should be black",[])).
1010
1011
1012find_path_blacks(black('',_,_,''), Bls, Bls) :- !.
1013find_path_blacks(black(L,_,_,_), Bls0, Bls) :-
1014 Bls1 is Bls0+1,
1015 find_path_blacks(L, Bls1, Bls).
1016find_path_blacks(red(L,_,_,_), Bls0, Bls) :-
1017 find_path_blacks(L, Bls0, Bls).
1018
1019check_rbtree(black('',_,_,''),Min,Max,Bls0) :-
1020 !,
1021 check_height(Bls0,Min,Max).
1022check_rbtree(red(L,K,_,R),Min,Max,Bls) :-
1023 check_val(K,Min,Max),
1024 check_red_child(L),
1025 check_red_child(R),
1026 check_rbtree(L,Min,K,Bls),
1027 check_rbtree(R,K,Max,Bls).
1028check_rbtree(black(L,K,_,R),Min,Max,Bls0) :-
1029 check_val(K,Min,Max),
1030 Bls is Bls0-1,
1031 check_rbtree(L,Min,K,Bls),
1032 check_rbtree(R,K,Max,Bls).
1033
1034check_height(0,_,_) :- !.
1035check_height(Bls0,Min,Max) :-
1036 throw(msg("Unbalance ~d between ~w and ~w~n",[Bls0,Min,Max])).
1037
1038check_val(K, Min, Max) :- ( K @> Min ; Min == -inf), (K @< Max ; Max == +inf), !.
1039check_val(K, Min, Max) :-
1040 throw(msg("not ordered: ~w not between ~w and ~w~n",[K,Min,Max])).
1041
1042check_red_child(black(_,_,_,_)).
1043check_red_child(red(_,K,_,_)) :-
1044 throw(msg("must be red: ~w~n",[K]))