mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
browser/browse.m:
browser/browser_info.m:
browser/collect_lib.m:
browser/declarative_debugger.m:
browser/declarative_oracle.m:
browser/declarative_user.m:
browser/diff.m:
browser/help.m:
browser/interactive_query.m:
browser/parse.m:
browser/util.m:
Replace implicit streams with explicit streams.
Shorten lines longer than 79 chars.
In some places, simplify some code, often using constructs such as
string.format that either did not exist or were too expensive to use
when the original code was written.
In some places, change predicate names that were not meaningful
without module qualification by *including* the module qualification
in the name (e.g. init -> browser_info_init).
In some places, add XXXs.
In browser_info.m, make the output stream *part* of the debugger type,
because without this, having the debugger type belong to the stream
typeclass does NOT make sense. (The typeclass instance for debugger
used to always write to the current output stream, which this diff
is replacing with the use of explicitly specified streams.)
In browse.m, consistently put stream arguments before other arguments.
In browse.m, when exporting Mercury predicates to C, export them
under names with the standard ML_BROWSE_ prefix, NOT under the name
of a *different* predicate with that prefix.
In diff.m, eliminate an unnecessary difference between what we print
when the difference between two terms is at the root, vs what we print
when the difference between two terms is lower down.
In interactive_query.m, when trying to write a program out to a file,
do NOT write the program to the current output stream if we cannot open
the file, since that would accomplish nothing useful.
Also in interactive_query.m, cleanup .dylib instead of .so on MacOS.
In util.m, delete some unused predicates.
In collect_lib.m, document why some code is not worth updating.
In declarative_oracle.m, rename predicates with previously-ambiguous
names.
browser/MDBFLAGS.in:
Specify --warn-implicit-stream-calls for all Mercury modules
in the browser directory from now.
trace/mercury_trace_browse.c:
trace/mercury_trace_cmd_browsing.c:
ssdb/ssdb.m:
Conform to the changes in browser/*.m.
tests/debugger/queens.{exp,exp2}:
Expect the extra output from browser/diff.m.
1122 lines
38 KiB
Mathematica
1122 lines
38 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1994-1997,1999-2000,2002,2004,2006 The University of Melbourne.
|
|
% Copyright (C) 2015, 2017-2018 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% tree234_cc implements a map (dictionary) using 2-3-4 trees. This is
|
|
% a cut down version of the standard library module library/tree234.m,
|
|
% with the additional change that it uses compare_representation instead
|
|
% of the builtin unification and comparison predicates. It is thus able
|
|
% to work with keys that contain non-canonical terms, such as higher order
|
|
% terms.
|
|
%
|
|
% The drawback of using compare_representation is that sometimes entries
|
|
% that have been inserted in the map will not later be found when looked up.
|
|
% This can happen when the lookup uses a different (but equivalent)
|
|
% representation of the key than the insertion. However, for some
|
|
% applications (for example, the declarative debugging oracle) this
|
|
% behaviour may be acceptable.
|
|
%
|
|
% A flow on effect is that most of the det predicates are now cc_multi,
|
|
% since this is the determinism of compare_representation. Even predicates
|
|
% that used to be semidet are now cc_multi, since they need to be called
|
|
% just after calls to other committed choice procedures which means that
|
|
% they are not allowed to fail. They return all outputs in a maybe type,
|
|
% which indicates success or failure.
|
|
%
|
|
% See library/map.m for documentation of the predicates.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module mdb.tree234_cc.
|
|
|
|
:- interface.
|
|
|
|
:- import_module maybe.
|
|
|
|
:- type tree234_cc(K, V).
|
|
|
|
:- pred init(tree234_cc(K, V)::uo) is det.
|
|
|
|
:- pred is_empty(tree234_cc(K, V)::in) is semidet.
|
|
|
|
:- pred search(tree234_cc(K, V)::in, K::in, maybe(V)::out) is cc_multi.
|
|
|
|
:- pred set(tree234_cc(K, V)::in, K::in, V::in, tree234_cc(K, V)::out)
|
|
is cc_multi.
|
|
|
|
:- pred delete(tree234_cc(K, V)::in, K::in, tree234_cc(K, V)::out) is cc_multi.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module int.
|
|
:- import_module require.
|
|
|
|
:- type tree234_cc(K, V)
|
|
---> empty
|
|
; two(K, V, tree234_cc(K, V), tree234_cc(K, V))
|
|
; three(K, V, K, V, tree234_cc(K, V), tree234_cc(K, V),
|
|
tree234_cc(K, V))
|
|
; four(K, V, K, V, K, V, tree234_cc(K, V), tree234_cc(K, V),
|
|
tree234_cc(K, V), tree234_cc(K, V)).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
init(empty).
|
|
|
|
is_empty(Tree) :-
|
|
Tree = empty.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
search(T, K, MaybeV) :-
|
|
(
|
|
T = empty,
|
|
MaybeV = no
|
|
;
|
|
T = two(K0, V0, T0, T1),
|
|
compare_representation(Result, K, K0),
|
|
(
|
|
Result = (<),
|
|
search(T0, K, MaybeV)
|
|
;
|
|
Result = (=),
|
|
MaybeV = yes(V0)
|
|
;
|
|
Result = (>),
|
|
search(T1, K, MaybeV)
|
|
)
|
|
;
|
|
T = three(K0, V0, K1, V1, T0, T1, T2),
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
search(T0, K, MaybeV)
|
|
;
|
|
Result0 = (=),
|
|
MaybeV = yes(V0)
|
|
;
|
|
Result0 = (>),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
search(T1, K, MaybeV)
|
|
;
|
|
Result1 = (=),
|
|
MaybeV = yes(V1)
|
|
;
|
|
Result1 = (>),
|
|
search(T2, K, MaybeV)
|
|
)
|
|
)
|
|
;
|
|
T = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
search(T0, K, MaybeV)
|
|
;
|
|
Result0 = (=),
|
|
MaybeV = yes(V0)
|
|
;
|
|
Result0 = (>),
|
|
search(T1, K, MaybeV)
|
|
)
|
|
;
|
|
Result1 = (=),
|
|
MaybeV = yes(V1)
|
|
;
|
|
Result1 = (>),
|
|
compare_representation(Result2, K, K2),
|
|
(
|
|
Result2 = (<),
|
|
search(T2, K, MaybeV)
|
|
;
|
|
Result2 = (=),
|
|
MaybeV = yes(V2)
|
|
;
|
|
Result2 = (>),
|
|
search(T3, K, MaybeV)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- inst two(K, V, T) for tree234_cc/2
|
|
---> two(K, V, T, T).
|
|
:- inst three(K, V, T) for tree234_cc/2
|
|
---> three(K, V, K, V, T, T, T).
|
|
:- inst four(K, V, T) for tree234_cc/2
|
|
---> four(K, V, K, V, K, V, T, T, T, T).
|
|
|
|
:- mode out_two == out(two(ground, ground, ground)).
|
|
:- mode in_two == in(two(ground, ground, ground)).
|
|
:- mode in_three == in(three(ground, ground, ground)).
|
|
:- mode in_four == in(four(ground, ground, ground)).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred split_four(tree234_cc(K, V)::in_four, K::out, V::out,
|
|
tree234_cc(K, V)::out_two, tree234_cc(K, V)::out_two) is det.
|
|
|
|
split_four(Tin, MidK, MidV, Sub0, Sub1) :-
|
|
Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
Sub0 = two(K0, V0, T0, T1),
|
|
MidK = K1,
|
|
MidV = V1,
|
|
Sub1 = two(K2, V2, T2, T3).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% set is implemented using the simple top-down approach
|
|
% described in eg Sedgewick which splits 4 nodes into two 2 nodes on the
|
|
% downward traversal of the tree as we search for the right place to
|
|
% insert the new key-value pair. We know we have the right place if the
|
|
% subtrees of the node are empty (in which case we expand the node - which
|
|
% will always work because we already split 4 nodes into 2 nodes), or if
|
|
% the tree itself is empty. This algorithm is O(lgN).
|
|
|
|
set(Tin, K, V, Tout) :-
|
|
(
|
|
Tin = empty,
|
|
Tout = two(K, V, empty, empty)
|
|
;
|
|
Tin = two(_, _, _, _),
|
|
set2(Tin, K, V, Tout)
|
|
;
|
|
Tin = three(_, _, _, _, _, _, _),
|
|
set3(Tin, K, V, Tout)
|
|
;
|
|
Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
Sub0 = two(K0, V0, T0, T1),
|
|
Sub1 = two(K2, V2, T2, T3),
|
|
set2(Sub0, K, V, NewSub0),
|
|
Tout = two(K1, V1, NewSub0, Sub1)
|
|
;
|
|
Result1 = (=),
|
|
Tout = four(K0, V0, K1, V, K2, V2, T0, T1, T2, T3)
|
|
;
|
|
Result1 = (>),
|
|
Sub0 = two(K0, V0, T0, T1),
|
|
Sub1 = two(K2, V2, T2, T3),
|
|
set2(Sub1, K, V, NewSub1),
|
|
Tout = two(K1, V1, Sub0, NewSub1)
|
|
)
|
|
).
|
|
|
|
:- pred set2(tree234_cc(K, V)::in_two, K::in, V::in, tree234_cc(K, V)::out)
|
|
is cc_multi.
|
|
|
|
set2(two(K0, V0, T0, T1), K, V, Tout) :-
|
|
( if
|
|
T0 = empty
|
|
% T1 = empty implied by T0 = empty
|
|
then
|
|
compare_representation(Result, K, K0),
|
|
(
|
|
Result = (<),
|
|
Tout = three(K, V, K0, V0, empty, empty, empty)
|
|
;
|
|
Result = (=),
|
|
Tout = two(K, V, T0, T1)
|
|
;
|
|
Result = (>),
|
|
Tout = three(K0, V0, K, V, empty, empty, empty)
|
|
)
|
|
else
|
|
compare_representation(Result, K, K0),
|
|
(
|
|
Result = (<),
|
|
(
|
|
T0 = four(_, _, _, _, _, _, _, _, _, _),
|
|
split_four(T0, MT0K, MT0V, T00, T01),
|
|
compare_representation(Result1, K, MT0K),
|
|
(
|
|
Result1 = (<),
|
|
set2(T00, K, V, NewT00),
|
|
Tout = three(MT0K, MT0V, K0, V0, NewT00, T01, T1)
|
|
;
|
|
Result1 = (=),
|
|
Tout = three(MT0K, V, K0, V0, T00, T01, T1)
|
|
;
|
|
Result1 = (>),
|
|
set2(T01, K, V, NewT01),
|
|
Tout = three(MT0K, MT0V, K0, V0, T00, NewT01, T1)
|
|
)
|
|
;
|
|
T0 = three(_, _, _, _, _, _, _),
|
|
set3(T0, K, V, NewT0),
|
|
Tout = two(K0, V0, NewT0, T1)
|
|
;
|
|
T0 = two(_, _, _, _),
|
|
set2(T0, K, V, NewT0),
|
|
Tout = two(K0, V0, NewT0, T1)
|
|
;
|
|
T0 = empty,
|
|
NewT0 = two(K, V, empty, empty),
|
|
Tout = two(K0, V0, NewT0, T1)
|
|
)
|
|
;
|
|
Result = (=),
|
|
Tout = two(K, V, T0, T1)
|
|
;
|
|
Result = (>),
|
|
(
|
|
T1 = four(_, _, _, _, _, _, _, _, _, _),
|
|
split_four(T1, MT1K, MT1V, T10, T11),
|
|
compare_representation(Result1, K, MT1K),
|
|
(
|
|
Result1 = (<),
|
|
set2(T10, K, V, NewT10),
|
|
Tout = three(K0, V0, MT1K, MT1V, T0, NewT10, T11)
|
|
;
|
|
Result1 = (=),
|
|
Tout = three(K0, V0, MT1K, V, T0, T10, T11)
|
|
;
|
|
Result1 = (>),
|
|
set2(T11, K, V, NewT11),
|
|
Tout = three(K0, V0, MT1K, MT1V, T0, T10, NewT11)
|
|
)
|
|
;
|
|
T1 = three(_, _, _, _, _, _, _),
|
|
set3(T1, K, V, NewT1),
|
|
Tout = two(K0, V0, T0, NewT1)
|
|
;
|
|
T1 = two(_, _, _, _),
|
|
set2(T1, K, V, NewT1),
|
|
Tout = two(K0, V0, T0, NewT1)
|
|
;
|
|
T1 = empty,
|
|
NewT1 = two(K, V, empty, empty),
|
|
Tout = two(K0, V0, T0, NewT1)
|
|
)
|
|
)
|
|
).
|
|
|
|
:- pred set3(tree234_cc(K, V), K, V, tree234_cc(K, V)).
|
|
:- mode set3(in_three, in, in, out) is cc_multi.
|
|
|
|
set3(three(K0, V0, K1, V1, T0, T1, T2), K, V, Tout) :-
|
|
( if
|
|
T0 = empty
|
|
% T1 = empty implied by T0 = empty
|
|
% T2 = empty implied by T0 = empty
|
|
then
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
Tout = four(K, V, K0, V0, K1, V1, empty, empty, empty, empty)
|
|
;
|
|
Result0 = (=),
|
|
Tout = three(K0, V, K1, V1, empty, empty, empty)
|
|
;
|
|
Result0 = (>),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
Tout = four(K0, V0, K, V, K1, V1, empty, empty, empty, empty)
|
|
;
|
|
Result1 = (=),
|
|
Tout = three(K0, V0, K1, V, empty, empty, empty)
|
|
;
|
|
Result1 = (>),
|
|
Tout = four(K0, V0, K1, V1, K, V, empty, empty, empty, empty)
|
|
)
|
|
)
|
|
else
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
(
|
|
T0 = four(_, _, _, _, _, _, _, _, _, _),
|
|
split_four(T0, MT0K, MT0V, T00, T01),
|
|
compare_representation(ResultM, K, MT0K),
|
|
(
|
|
ResultM = (<),
|
|
set2(T00, K, V, NewT00),
|
|
Tout = four(MT0K, MT0V, K0, V0, K1, V1,
|
|
NewT00, T01, T1, T2)
|
|
;
|
|
ResultM = (=),
|
|
Tout = four(MT0K, V, K0, V0, K1, V1,
|
|
T00, T01, T1, T2)
|
|
;
|
|
ResultM = (>),
|
|
set2(T01, K, V, NewT01),
|
|
Tout = four(MT0K, MT0V, K0, V0, K1, V1,
|
|
T00, NewT01, T1, T2)
|
|
)
|
|
;
|
|
T0 = three(_, _, _, _, _, _, _),
|
|
set3(T0, K, V, NewT0),
|
|
Tout = three(K0, V0, K1, V1, NewT0, T1, T2)
|
|
;
|
|
T0 = two(_, _, _, _),
|
|
set2(T0, K, V, NewT0),
|
|
Tout = three(K0, V0, K1, V1, NewT0, T1, T2)
|
|
;
|
|
T0 = empty,
|
|
NewT0 = two(K, V, empty, empty),
|
|
Tout = three(K0, V0, K1, V1, NewT0, T1, T2)
|
|
)
|
|
;
|
|
Result0 = (=),
|
|
Tout = three(K0, V, K1, V1, T0, T1, T2)
|
|
;
|
|
Result0 = (>),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
(
|
|
T1 = four(_, _, _, _, _, _, _, _, _, _),
|
|
split_four(T1, MT1K, MT1V, T10, T11),
|
|
compare_representation(ResultM, K, MT1K),
|
|
(
|
|
ResultM = (<),
|
|
set2(T10, K, V, NewT10),
|
|
Tout = four(K0, V0, MT1K, MT1V, K1, V1,
|
|
T0, NewT10, T11, T2)
|
|
;
|
|
ResultM = (=),
|
|
Tout = four(K0, V0, MT1K, V, K1, V1,
|
|
T0, T10, T11, T2)
|
|
;
|
|
ResultM = (>),
|
|
set2(T11, K, V, NewT11),
|
|
Tout = four(K0, V0, MT1K, MT1V, K1, V1,
|
|
T0, T10, NewT11, T2)
|
|
)
|
|
;
|
|
T1 = three(_, _, _, _, _, _, _),
|
|
set3(T1, K, V, NewT1),
|
|
Tout = three(K0, V0, K1, V1, T0, NewT1, T2)
|
|
;
|
|
T1 = two(_, _, _, _),
|
|
set2(T1, K, V, NewT1),
|
|
Tout = three(K0, V0, K1, V1, T0, NewT1, T2)
|
|
;
|
|
T1 = empty,
|
|
NewT1 = two(K, V, empty, empty),
|
|
Tout = three(K0, V0, K1, V1, T0, NewT1, T2)
|
|
)
|
|
;
|
|
Result1 = (=),
|
|
Tout = three(K0, V0, K, V, T0, T1, T2)
|
|
;
|
|
Result1 = (>),
|
|
(
|
|
T2 = four(_, _, _, _, _, _, _, _, _, _),
|
|
split_four(T2, MT2K, MT2V, T20, T21),
|
|
compare_representation(ResultM, K, MT2K),
|
|
(
|
|
ResultM = (<),
|
|
set2(T20, K, V, NewT20),
|
|
Tout = four(K0, V0, K1, V1, MT2K, MT2V,
|
|
T0, T1, NewT20, T21)
|
|
;
|
|
ResultM = (=),
|
|
Tout = four(K0, V0, K1, V1, MT2K, V,
|
|
T0, T1, T20, T21)
|
|
;
|
|
ResultM = (>),
|
|
set2(T21, K, V, NewT21),
|
|
Tout = four(K0, V0, K1, V1, MT2K, MT2V,
|
|
T0, T1, T20, NewT21)
|
|
)
|
|
;
|
|
T2 = three(_, _, _, _, _, _, _),
|
|
set3(T2, K, V, NewT2),
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT2)
|
|
;
|
|
T2 = two(_, _, _, _),
|
|
set2(T2, K, V, NewT2),
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT2)
|
|
;
|
|
T2 = empty,
|
|
NewT2 = two(K, V, empty, empty),
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT2)
|
|
)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
delete(Tin, K, Tout) :-
|
|
delete_2(Tin, K, Tout, _).
|
|
|
|
% When deleting an item from a tree, the height of the tree may be
|
|
% reduced by one. The last argument says whether this has occurred.
|
|
|
|
:- pred delete_2(tree234_cc(K, V)::in, K::in, tree234_cc(K, V)::out, bool::out)
|
|
is cc_multi.
|
|
|
|
delete_2(Tin, K, Tout, RH) :-
|
|
(
|
|
Tin = empty,
|
|
Tout = empty,
|
|
RH = no
|
|
;
|
|
Tin = two(K0, V0, T0, T1),
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
delete_2(T0, K, NewT0, RHT0),
|
|
(
|
|
RHT0 = yes,
|
|
fix_2node_t0(K0, V0, NewT0, T1, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = two(K0, V0, NewT0, T1),
|
|
RH = no
|
|
)
|
|
;
|
|
Result0 = (=),
|
|
remove_smallest(T1, Removed),
|
|
(
|
|
Removed = yes({ST1K, ST1V, NewT1, RHT1}),
|
|
(
|
|
RHT1 = yes,
|
|
fix_2node_t1(ST1K, ST1V, T0, NewT1, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = two(ST1K, ST1V, T0, NewT1),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T1 must be empty
|
|
Tout = T0,
|
|
RH = yes
|
|
)
|
|
;
|
|
Result0 = (>),
|
|
delete_2(T1, K, NewT1, RHT1),
|
|
(
|
|
RHT1 = yes,
|
|
fix_2node_t1(K0, V0, T0, NewT1, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = two(K0, V0, T0, NewT1),
|
|
RH = no
|
|
)
|
|
)
|
|
;
|
|
Tin = three(K0, V0, K1, V1, T0, T1, T2),
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
delete_2(T0, K, NewT0, RHT0),
|
|
(
|
|
RHT0 = yes,
|
|
fix_3node_t0(K0, V0, K1, V1, NewT0, T1, T2, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = three(K0, V0, K1, V1, NewT0, T1, T2),
|
|
RH = no
|
|
)
|
|
;
|
|
Result0 = (=),
|
|
remove_smallest(T1, Removed),
|
|
(
|
|
Removed = yes({ST1K, ST1V, NewT1, RHT1}),
|
|
(
|
|
RHT1 = yes,
|
|
fix_3node_t1(ST1K, ST1V, K1, V1, T0, NewT1, T2, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = three(ST1K, ST1V, K1, V1, T0, NewT1, T2),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T1 must be empty
|
|
Tout = two(K1, V1, T0, T2),
|
|
RH = no
|
|
)
|
|
;
|
|
Result0 = (>),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
delete_2(T1, K, NewT1, RHT1),
|
|
(
|
|
RHT1 = yes,
|
|
fix_3node_t1(K0, V0, K1, V1, T0, NewT1, T2, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = three(K0, V0, K1, V1, T0, NewT1, T2),
|
|
RH = no
|
|
)
|
|
;
|
|
Result1 = (=),
|
|
remove_smallest(T2, Removed),
|
|
(
|
|
Removed = yes({ST2K, ST2V, NewT2, RHT2}),
|
|
(
|
|
RHT2 = yes,
|
|
fix_3node_t2(K0, V0, ST2K, ST2V,
|
|
T0, T1, NewT2, Tout, RH)
|
|
;
|
|
RHT2 = no,
|
|
Tout = three(K0, V0, ST2K, ST2V, T0, T1, NewT2),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T2 must be empty
|
|
Tout = two(K0, V0, T0, T1),
|
|
RH = no
|
|
)
|
|
;
|
|
Result1 = (>),
|
|
delete_2(T2, K, NewT2, RHT2),
|
|
(
|
|
RHT2 = yes,
|
|
fix_3node_t2(K0, V0, K1, V1, T0, T1, NewT2, Tout, RH)
|
|
;
|
|
RHT2 = no,
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT2),
|
|
RH = no
|
|
)
|
|
)
|
|
)
|
|
;
|
|
Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
compare_representation(Result1, K, K1),
|
|
(
|
|
Result1 = (<),
|
|
compare_representation(Result0, K, K0),
|
|
(
|
|
Result0 = (<),
|
|
delete_2(T0, K, NewT0, RHT0),
|
|
(
|
|
RHT0 = yes,
|
|
fix_4node_t0(K0, V0, K1, V1, K2, V2,
|
|
NewT0, T1, T2, T3, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = four(K0, V0, K1, V1, K2, V2, NewT0, T1, T2, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Result0 = (=),
|
|
remove_smallest(T1, Removed),
|
|
(
|
|
Removed = yes({ST1K, ST1V, NewT1, RHT1}),
|
|
(
|
|
RHT1 = yes,
|
|
fix_4node_t1(ST1K, ST1V, K1, V1, K2, V2,
|
|
T0, NewT1, T2, T3, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = four(ST1K, ST1V, K1, V1, K2, V2,
|
|
T0, NewT1, T2, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T1 must be empty
|
|
Tout = three(K1, V1, K2, V2, T0, T2, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Result0 = (>),
|
|
delete_2(T1, K, NewT1, RHT1),
|
|
(
|
|
RHT1 = yes,
|
|
fix_4node_t1(K0, V0, K1, V1, K2, V2,
|
|
T0, NewT1, T2, T3, Tout, RH)
|
|
;
|
|
RHT1 = no,
|
|
Tout = four(K0, V0, K1, V1, K2, V2, T0, NewT1, T2, T3),
|
|
RH = no
|
|
)
|
|
)
|
|
;
|
|
Result1 = (=),
|
|
remove_smallest(T2, Removed),
|
|
(
|
|
Removed = yes({ST2K, ST2V, NewT2, RHT2}),
|
|
(
|
|
RHT2 = yes,
|
|
fix_4node_t2(K0, V0, ST2K, ST2V, K2, V2,
|
|
T0, T1, NewT2, T3, Tout, RH)
|
|
;
|
|
RHT2 = no,
|
|
Tout = four(K0, V0, ST2K, ST2V, K2, V2, T0, T1, NewT2, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T2 must be empty
|
|
Tout = three(K0, V0, K2, V2, T0, T1, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Result1 = (>),
|
|
compare_representation(Result2, K, K2),
|
|
(
|
|
Result2 = (<),
|
|
delete_2(T2, K, NewT2, RHT2),
|
|
(
|
|
RHT2 = yes,
|
|
fix_4node_t2(K0, V0, K1, V1, K2, V2,
|
|
T0, T1, NewT2, T3, Tout, RH)
|
|
;
|
|
RHT2 = no,
|
|
Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, NewT2, T3),
|
|
RH = no
|
|
)
|
|
;
|
|
Result2 = (=),
|
|
remove_smallest(T3, Removed),
|
|
(
|
|
Removed = yes({ST3K, ST3V, NewT3,
|
|
RHT3}),
|
|
(
|
|
RHT3 = yes,
|
|
fix_4node_t3(K0, V0, K1, V1, ST3K, ST3V,
|
|
T0, T1, T2, NewT3, Tout, RH)
|
|
;
|
|
RHT3 = no,
|
|
Tout = four(K0, V0, K1, V1, ST3K, ST3V,
|
|
T0, T1, T2, NewT3),
|
|
RH = no
|
|
)
|
|
;
|
|
Removed = no,
|
|
% T3 must be empty
|
|
Tout = three(K0, V0, K1, V1, T0, T1, T2),
|
|
RH = no
|
|
)
|
|
;
|
|
Result2 = (>),
|
|
delete_2(T3, K, NewT3, RHT3),
|
|
(
|
|
RHT3 = yes,
|
|
fix_4node_t3(K0, V0, K1, V1, K2, V2,
|
|
T0, T1, T2, NewT3, Tout, RH)
|
|
;
|
|
RHT3 = no,
|
|
Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, NewT3),
|
|
RH = no
|
|
)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The algorithm we use similar to delete, except that we
|
|
% always go down the left subtree.
|
|
|
|
:- pred remove_smallest(tree234_cc(K, V)::in,
|
|
maybe({K, V, tree234_cc(K, V), bool})::out) is cc_multi.
|
|
|
|
remove_smallest(Tin, Result) :-
|
|
(
|
|
Tin = empty,
|
|
Result = no
|
|
;
|
|
Tin = two(K0, V0, T0, T1),
|
|
( if
|
|
T0 = empty
|
|
then
|
|
K = K0,
|
|
V = V0,
|
|
Tout = T1,
|
|
RH = yes
|
|
else
|
|
remove_smallest(T0, Removed),
|
|
(
|
|
Removed = no,
|
|
error("remove_smallest: failure two")
|
|
;
|
|
Removed = yes({K, V, NewT0, RHT0})
|
|
),
|
|
(
|
|
RHT0 = yes,
|
|
fix_2node_t0(K0, V0, NewT0, T1, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = two(K0, V0, NewT0, T1),
|
|
RH = no
|
|
)
|
|
),
|
|
Result = yes({K, V, Tout, RH})
|
|
;
|
|
Tin = three(K0, V0, K1, V1, T0, T1, T2),
|
|
( if
|
|
T0 = empty
|
|
then
|
|
K = K0,
|
|
V = V0,
|
|
Tout = two(K1, V1, T1, T2),
|
|
RH = no
|
|
else
|
|
remove_smallest(T0, ThreeResult),
|
|
(
|
|
ThreeResult = no,
|
|
error("remove_smallest: failure three")
|
|
;
|
|
ThreeResult = yes({K, V, NewT0, RHT0})
|
|
),
|
|
(
|
|
RHT0 = yes,
|
|
fix_3node_t0(K0, V0, K1, V1, NewT0, T1, T2, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = three(K0, V0, K1, V1, NewT0, T1, T2),
|
|
RH = no
|
|
)
|
|
),
|
|
Result = yes({K, V, Tout, RH})
|
|
;
|
|
Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
( if
|
|
T0 = empty
|
|
then
|
|
K = K0,
|
|
V = V0,
|
|
Tout = three(K1, V1, K2, V2, T1, T2, T3),
|
|
RH = no
|
|
else
|
|
remove_smallest(T0, FourResult),
|
|
(
|
|
FourResult = no,
|
|
error("remove_smallest: failure four")
|
|
;
|
|
FourResult = yes({K, V, NewT0, RHT0})
|
|
),
|
|
(
|
|
RHT0 = yes,
|
|
fix_4node_t0(K0, V0, K1, V1, K2, V2,
|
|
NewT0, T1, T2, T3, Tout, RH)
|
|
;
|
|
RHT0 = no,
|
|
Tout = four(K0, V0, K1, V1, K2, V2, NewT0, T1, T2, T3),
|
|
RH = no
|
|
)
|
|
),
|
|
Result = yes({K, V, Tout, RH})
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The input to the following group of predicates are the components
|
|
% of a two-, three- or four-node in which the height of the indicated
|
|
% subtree is one less that it should be. If it is possible to increase
|
|
% the height of that subtree by moving into it elements from its
|
|
% neighboring subtrees, do so, and return the resulting tree with RH
|
|
% set to no. Otherwise, return a balanced tree whose height is reduced
|
|
% by one, with RH set to yes to indicate the reduced height.
|
|
|
|
:- pred fix_2node_t0(K::in, V::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::out, bool::out) is det.
|
|
|
|
fix_2node_t0(K0, V0, T0, T1, Tout, RH) :-
|
|
(
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = four(K10, V10, K11, V11, K12, V12, T10, T11, T12, T13),
|
|
NewT1 = three(K11, V11, K12, V12, T11, T12, T13),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = two(K10, V10, Node, NewT1),
|
|
RH = no
|
|
;
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = three(K10, V10, K11, V11, T10, T11, T12),
|
|
NewT1 = two(K11, V11, T11, T12),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = two(K10, V10, Node, NewT1),
|
|
RH = no
|
|
;
|
|
% move T0 one level down and combine it with the subtrees of T1
|
|
% this reduces the depth of the tree
|
|
T1 = two(K10, V10, T10, T11),
|
|
Tout = three(K0, V0, K10, V10, T0, T10, T11),
|
|
RH = yes
|
|
;
|
|
T1 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = two(K0, V0, T0, T1),
|
|
% RH = yes
|
|
).
|
|
|
|
:- pred fix_2node_t1(K::in, V::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::out, bool::out) is det.
|
|
|
|
fix_2node_t1(K0, V0, T0, T1, Tout, RH) :-
|
|
(
|
|
% steal T0's leftmost subtree and combine it with T1
|
|
T0 = four(K00, V00, K01, V01, K02, V02, T00, T01, T02, T03),
|
|
NewT0 = three(K00, V00, K01, V01, T00, T01, T02),
|
|
Node = two(K0, V0, T03, T1),
|
|
Tout = two(K02, V02, NewT0, Node),
|
|
RH = no
|
|
;
|
|
% steal T0's leftmost subtree and combine it with T1
|
|
T0 = three(K00, V00, K01, V01, T00, T01, T02),
|
|
NewT0 = two(K00, V00, T00, T01),
|
|
Node = two(K0, V0, T02, T1),
|
|
Tout = two(K01, V01, NewT0, Node),
|
|
RH = no
|
|
;
|
|
% move T1 one level down and combine it with the subtrees of T0
|
|
% this reduces the depth of the tree
|
|
T0 = two(K00, V00, T00, T01),
|
|
Tout = three(K00, V00, K0, V0, T00, T01, T1),
|
|
RH = yes
|
|
;
|
|
T0 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = two(K0, V0, T0, T1),
|
|
% RH = yes
|
|
).
|
|
|
|
:- pred fix_3node_t0(K::in, V::in, K::in, V::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::out,
|
|
bool::out) is det.
|
|
|
|
fix_3node_t0(K0, V0, K1, V1, T0, T1, T2, Tout, RH) :-
|
|
(
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = four(K10, V10, K11, V11, K12, V12, T10, T11, T12, T13),
|
|
NewT1 = three(K11, V11, K12, V12, T11, T12, T13),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = three(K10, V10, K1, V1, Node, NewT1, T2),
|
|
RH = no
|
|
;
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = three(K10, V10, K11, V11, T10, T11, T12),
|
|
NewT1 = two(K11, V11, T11, T12),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = three(K10, V10, K1, V1, Node, NewT1, T2),
|
|
RH = no
|
|
;
|
|
% move T0 one level down to become the leftmost subtree of T1
|
|
T1 = two(K10, V10, T10, T11),
|
|
NewT1 = three(K0, V0, K10, V10, T0, T10, T11),
|
|
Tout = two(K1, V1, NewT1, T2),
|
|
RH = no
|
|
;
|
|
T1 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = three(K0, V0, K1, V1, T0, T1, T2),
|
|
% The heights of T1 and T2 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_3node_t1(K::in, V::in, K::in, V::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::out,
|
|
bool::out) is det.
|
|
|
|
fix_3node_t1(K0, V0, K1, V1, T0, T1, T2, Tout, RH) :-
|
|
(
|
|
% steal T0's rightmost subtree and combine it with T1
|
|
T0 = four(K00, V00, K01, V01, K02, V02, T00, T01, T02, T03),
|
|
NewT0 = three(K00, V00, K01, V01, T00, T01, T02),
|
|
Node = two(K0, V0, T03, T1),
|
|
Tout = three(K02, V02, K1, V1, NewT0, Node, T2),
|
|
RH = no
|
|
;
|
|
% steal T0's rightmost subtree and combine it with T1
|
|
T0 = three(K00, V00, K01, V01, T00, T01, T02),
|
|
NewT0 = two(K00, V00, T00, T01),
|
|
Node = two(K0, V0, T02, T1),
|
|
Tout = three(K01, V01, K1, V1, NewT0, Node, T2),
|
|
RH = no
|
|
;
|
|
% move T1 one level down to become the rightmost subtree of T0
|
|
T0 = two(K00, V00, T00, T01),
|
|
NewT0 = three(K00, V00, K0, V0, T00, T01, T1),
|
|
Tout = two(K1, V1, NewT0, T2),
|
|
RH = no
|
|
;
|
|
T0 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = three(K0, V0, K1, V1, T0, T1, T2),
|
|
% The heights of T0 and T2 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_3node_t2(K::in, V::in, K::in, V::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::out,
|
|
bool::out) is det.
|
|
|
|
fix_3node_t2(K0, V0, K1, V1, T0, T1, T2, Tout, RH) :-
|
|
(
|
|
% steal T1's rightmost subtree and combine it with T2
|
|
T1 = four(K10, V10, K11, V11, K12, V12, T10, T11, T12, T13),
|
|
NewT1 = three(K10, V10, K11, V11, T10, T11, T12),
|
|
Node = two(K1, V1, T13, T2),
|
|
Tout = three(K0, V0, K12, V12, T0, NewT1, Node),
|
|
RH = no
|
|
;
|
|
% steal T1's rightmost subtree and combine it with T2
|
|
T1 = three(K10, V10, K11, V11, T10, T11, T12),
|
|
NewT1 = two(K10, V10, T10, T11),
|
|
Node = two(K1, V1, T12, T2),
|
|
Tout = three(K0, V0, K11, V11, T0, NewT1, Node),
|
|
RH = no
|
|
;
|
|
% move T2 one level down to become the rightmost subtree of T1
|
|
T1 = two(K10, V10, T10, T11),
|
|
NewT1 = three(K10, V10, K1, V1, T10, T11, T2),
|
|
Tout = two(K0, V0, T0, NewT1),
|
|
RH = no
|
|
;
|
|
T1 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = three(K0, V0, K1, V1, T0, T1, T2),
|
|
% The heights of T0 and T1 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_4node_t0(K::in, V::in, K::in, V::in, K::in, V::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::out, bool::out) is det.
|
|
|
|
fix_4node_t0(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3, Tout, RH) :-
|
|
(
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = four(K10, V10, K11, V11, K12, V12, T10, T11, T12, T13),
|
|
NewT1 = three(K11, V11, K12, V12, T11, T12, T13),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = four(K10, V10, K1, V1, K2, V2, Node, NewT1, T2, T3),
|
|
RH = no
|
|
;
|
|
% steal T1's leftmost subtree and combine it with T0
|
|
T1 = three(K10, V10, K11, V11, T10, T11, T12),
|
|
NewT1 = two(K11, V11, T11, T12),
|
|
Node = two(K0, V0, T0, T10),
|
|
Tout = four(K10, V10, K1, V1, K2, V2, Node, NewT1, T2, T3),
|
|
RH = no
|
|
;
|
|
% move T0 one level down to become the leftmost subtree of T1
|
|
T1 = two(K10, V10, T10, T11),
|
|
NewT1 = three(K0, V0, K10, V10, T0, T10, T11),
|
|
Tout = three(K1, V1, K2, V2, NewT1, T2, T3),
|
|
RH = no
|
|
;
|
|
T1 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
% The heights of T1, T2 and T3 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_4node_t1(K::in, V::in, K::in, V::in, K::in, V::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::out, bool::out) is det.
|
|
|
|
fix_4node_t1(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3, Tout, RH) :-
|
|
(
|
|
% steal T2's leftmost subtree and combine it with T1
|
|
T2 = four(K20, V20, K21, V21, K22, V22, T20, T21, T22, T23),
|
|
NewT2 = three(K21, V21, K22, V22, T21, T22, T23),
|
|
Node = two(K1, V1, T1, T20),
|
|
Tout = four(K0, V0, K20, V20, K2, V2, T0, Node, NewT2, T3),
|
|
RH = no
|
|
;
|
|
% steal T2's leftmost subtree and combine it with T1
|
|
T2 = three(K20, V20, K21, V21, T20, T21, T22),
|
|
NewT2 = two(K21, V21, T21, T22),
|
|
Node = two(K1, V1, T1, T20),
|
|
Tout = four(K0, V0, K20, V20, K2, V2, T0, Node, NewT2, T3),
|
|
RH = no
|
|
;
|
|
% move T1 one level down to become the leftmost subtree of T2
|
|
T2 = two(K20, V20, T20, T21),
|
|
NewT2 = three(K1, V1, K20, V20, T1, T20, T21),
|
|
Tout = three(K0, V0, K2, V2, T0, NewT2, T3),
|
|
RH = no
|
|
;
|
|
T2 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
% The heights of T0, T2 and T3 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_4node_t2(K::in, V::in, K::in, V::in, K::in, V::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::out, bool::out) is det.
|
|
|
|
fix_4node_t2(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3, Tout, RH) :-
|
|
(
|
|
% steal T3's leftmost subtree and combine it with T2
|
|
T3 = four(K30, V30, K31, V31, K32, V32, T30, T31, T32, T33),
|
|
NewT3 = three(K31, V31, K32, V32, T31, T32, T33),
|
|
Node = two(K2, V2, T2, T30),
|
|
Tout = four(K0, V0, K1, V1, K30, V30, T0, T1, Node, NewT3),
|
|
RH = no
|
|
;
|
|
% steal T3's leftmost subtree and combine it with T2
|
|
T3 = three(K30, V30, K31, V31, T30, T31, T32),
|
|
NewT3 = two(K31, V31, T31, T32),
|
|
Node = two(K2, V2, T2, T30),
|
|
Tout = four(K0, V0, K1, V1, K30, V30, T0, T1, Node, NewT3),
|
|
RH = no
|
|
;
|
|
% move T2 one level down to become the leftmost subtree of T3
|
|
T3 = two(K30, V30, T30, T31),
|
|
NewT3 = three(K2, V2, K30, V30, T2, T30, T31),
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT3),
|
|
RH = no
|
|
;
|
|
T3 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
% The heights of T0, T1 and T3 are unchanged
|
|
% RH = no
|
|
).
|
|
|
|
:- pred fix_4node_t3(K::in, V::in, K::in, V::in, K::in, V::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, tree234_cc(K, V)::in,
|
|
tree234_cc(K, V)::in, tree234_cc(K, V)::in, bool::in) is det.
|
|
|
|
fix_4node_t3(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3, Tout, RH) :-
|
|
(
|
|
% steal T2's rightmost subtree and combine it with T3
|
|
T2 = four(K20, V20, K21, V21, K22, V22, T20, T21, T22, T23),
|
|
NewT2 = three(K20, V20, K21, V21, T20, T21, T22),
|
|
Node = two(K2, V2, T23, T3),
|
|
Tout = four(K0, V0, K1, V1, K22, V22, T0, T1, NewT2, Node),
|
|
RH = no
|
|
;
|
|
% steal T2's rightmost subtree and combine it with T3
|
|
T2 = three(K20, V20, K21, V21, T20, T21, T22),
|
|
NewT2 = two(K20, V20, T20, T21),
|
|
Node = two(K2, V2, T22, T3),
|
|
Tout = four(K0, V0, K1, V1, K21, V21, T0, T1, NewT2, Node),
|
|
RH = no
|
|
;
|
|
% move T3 one level down to become the rightmost subtree of T2
|
|
T2 = two(K20, V20, T20, T21),
|
|
NewT2 = three(K20, V20, K2, V2, T20, T21, T3),
|
|
Tout = three(K0, V0, K1, V1, T0, T1, NewT2),
|
|
RH = no
|
|
;
|
|
T2 = empty,
|
|
error("unbalanced 234 tree")
|
|
% Tout = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
|
|
% The heights of T0, T1 and T2 are unchanged
|
|
% RH = no
|
|
).
|