fold operation on tree
This commit is contained in:
parent
38a2bee3ab
commit
5c70b295bd
@ -17,6 +17,8 @@
|
|||||||
rb_lookup/3, % +Key, -Value, +T
|
rb_lookup/3, % +Key, -Value, +T
|
||||||
rb_update/4, % +T, +Key, +NewVal, -TN
|
rb_update/4, % +T, +Key, +NewVal, -TN
|
||||||
rb_update/5, % +T, +Key, ?OldVal, +NewVal, -TN
|
rb_update/5, % +T, +Key, ?OldVal, +NewVal, -TN
|
||||||
|
rb_rewrite/3, % +T, +Key, +NewVal
|
||||||
|
rb_rewrite/4, % +T, +Key, ?OldVal, +NewVal
|
||||||
rb_apply/4, % +T, +Key, :G, -TN
|
rb_apply/4, % +T, +Key, :G, -TN
|
||||||
rb_lookupall/3, % +Key, -Value, +T
|
rb_lookupall/3, % +Key, -Value, +T
|
||||||
rb_insert/4, % +T0, +Key, ?Value, -TN
|
rb_insert/4, % +T0, +Key, ?Value, -TN
|
||||||
@ -39,6 +41,8 @@
|
|||||||
rb_del_max/4,
|
rb_del_max/4,
|
||||||
rb_next/4,
|
rb_next/4,
|
||||||
rb_previous/4,
|
rb_previous/4,
|
||||||
|
rb_fold/4,
|
||||||
|
rb_key_fold/4,
|
||||||
list_to_rbtree/2,
|
list_to_rbtree/2,
|
||||||
ord_list_to_rbtree/2,
|
ord_list_to_rbtree/2,
|
||||||
is_rbtree/1,
|
is_rbtree/1,
|
||||||
@ -257,6 +261,48 @@ update(red(Left,Key0,Val0,Right), Key, OldVal, Val, NewTree) :-
|
|||||||
update(Right, Key, OldVal, Val, NewRight)
|
update(Right, Key, OldVal, Val, NewRight)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
%% rb_rewrite(+T, +Key, +NewVal) is semidet.
|
||||||
|
%% rb_rewrite(+T, +Key, ?OldVal, +NewVal) is semidet.
|
||||||
|
%
|
||||||
|
% Tree T has value for Key associated with
|
||||||
|
% NewVal. Fails if it cannot find Key in T.
|
||||||
|
|
||||||
|
rb_rewrite(t(_Nil,OldTree), Key, OldVal, Val) :-
|
||||||
|
rewrite(OldTree, Key, OldVal, Val).
|
||||||
|
|
||||||
|
rb_rewrite(t(_Nil,OldTree), Key, Val) :-
|
||||||
|
rewrite(OldTree, Key, _, Val).
|
||||||
|
|
||||||
|
rewrite(Node, Key, OldVal, Val) :-
|
||||||
|
Node = black(Left,Key0,Val0,Right),
|
||||||
|
Left \= [],
|
||||||
|
compare(Cmp,Key0,Key),
|
||||||
|
(Cmp == (=)
|
||||||
|
-> OldVal = Val0,
|
||||||
|
setarg(3, Node, Val)
|
||||||
|
;
|
||||||
|
Cmp == (>) ->
|
||||||
|
rewrite(Left, Key, OldVal, Val)
|
||||||
|
;
|
||||||
|
rewrite(Right, Key, OldVal, Val)
|
||||||
|
).
|
||||||
|
rewrite(Node, Key, OldVal, Val) :-
|
||||||
|
Node = red(Left,Key0,Val0,Right),
|
||||||
|
Left \= [],
|
||||||
|
compare(Cmp,Key0,Key),
|
||||||
|
(
|
||||||
|
Cmp == (=)
|
||||||
|
->
|
||||||
|
OldVal = Val0,
|
||||||
|
setarg(3, Node, Val)
|
||||||
|
;
|
||||||
|
Cmp == (>)
|
||||||
|
->
|
||||||
|
rewrite(Left, Key, OldVal, Val)
|
||||||
|
;
|
||||||
|
rewrite(Right, Key, OldVal, Val)
|
||||||
|
).
|
||||||
|
|
||||||
%% rb_apply(+T, +Key, :G, -TN) is semidet.
|
%% rb_apply(+T, +Key, :G, -TN) is semidet.
|
||||||
%
|
%
|
||||||
% If the value associated with key Key is Val0 in T, and if
|
% If the value associated with key Key is Val0 in T, and if
|
||||||
@ -821,7 +867,7 @@ map(black(L,_,V,R),Goal) :-
|
|||||||
map(L,Goal),
|
map(L,Goal),
|
||||||
map(R,Goal).
|
map(R,Goal).
|
||||||
|
|
||||||
:- meta_predicate rb_accumulate(?,3,?,?). % this is required.
|
:- meta_predicate rb_fold(3,?,?,?). % this is required.
|
||||||
:- meta_predicate map_acc(?,3,?,?). % this is required.
|
:- meta_predicate map_acc(?,3,?,?). % this is required.
|
||||||
|
|
||||||
%% rb_fold(+T, :G, +Acc0, -AccF) is semidet.
|
%% rb_fold(+T, :G, +Acc0, -AccF) is semidet.
|
||||||
@ -833,7 +879,7 @@ map(black(L,_,V,R),Goal) :-
|
|||||||
% if VR is the value of the next node in inorder,
|
% if VR is the value of the next node in inorder,
|
||||||
% call(G,VR,Acc1,_) must hold.
|
% call(G,VR,Acc1,_) must hold.
|
||||||
|
|
||||||
rb_fold(t(_,Tree), Goal, In, Out) :-
|
rb_fold(Goal, t(_,Tree), In, Out) :-
|
||||||
map_acc(Tree, Goal, In, Out).
|
map_acc(Tree, Goal, In, Out).
|
||||||
|
|
||||||
map_acc(black('',_,_,''), _, Acc, Acc) :- !.
|
map_acc(black('',_,_,''), _, Acc, Acc) :- !.
|
||||||
@ -846,6 +892,31 @@ map_acc(black(L,_,V,R), Goal, Left, Right) :-
|
|||||||
once(call(Goal,V, Left1, Right1)),
|
once(call(Goal,V, Left1, Right1)),
|
||||||
map_acc(R,Goal, Right1, Right).
|
map_acc(R,Goal, Right1, Right).
|
||||||
|
|
||||||
|
:- meta_predicate rb_key_fold(4,?,?,?). % this is required.
|
||||||
|
:- meta_predicate map_key_acc(?,3,?,?). % this is required.
|
||||||
|
|
||||||
|
%% rb_key_fold(+T, :G, +Acc0, -AccF) is semidet.
|
||||||
|
%
|
||||||
|
% For all nodes Key in the tree T, if the value associated with
|
||||||
|
% key Key is V in tree T, if call(G,Key,V,Acc1,Acc2) holds, then
|
||||||
|
% if VL is value of the previous node in inorder,
|
||||||
|
% call(G,VL,_,Acc0) must hold, and
|
||||||
|
% if VR is the value of the next node in inorder,
|
||||||
|
% call(G,VR,Acc1,_) must hold.
|
||||||
|
|
||||||
|
rb_key_fold(Goal, t(_,Tree), In, Out) :-
|
||||||
|
map_key_acc(Tree, Goal, In, Out).
|
||||||
|
|
||||||
|
map_key_acc(black('',_,_,''), _, Acc, Acc) :- !.
|
||||||
|
map_key_acc(red(L,Key,V,R), Goal, Left, Right) :-
|
||||||
|
map_key_acc(L,Goal, Left, Left1),
|
||||||
|
once(call(Goal, Key, V, Left1, Right1)),
|
||||||
|
map_key_acc(R,Goal, Right1, Right).
|
||||||
|
map_key_acc(black(L,Key,V,R), Goal, Left, Right) :-
|
||||||
|
map_key_acc(L,Goal, Left, Left1),
|
||||||
|
once(call(Goal, Key, V, Left1, Right1)),
|
||||||
|
map_key_acc(R,Goal, Right1, Right).
|
||||||
|
|
||||||
%% rb_clone(+T, -NT, -Pairs)
|
%% rb_clone(+T, -NT, -Pairs)
|
||||||
%
|
%
|
||||||
% "Clone" the red-back tree into a new tree with the same keys as
|
% "Clone" the red-back tree into a new tree with the same keys as
|
||||||
|
Reference in New Issue
Block a user