For review: keeping 234 trees balanced during deletions

Zoltan Somogyi zs at cs.mu.oz.au
Thu Apr 10 08:36:56 AEST 1997


Tom, please review this.

Zoltan.

This is the new code of the delete, remove and remove_smallest predicates,
and the new predicates they use. This is smaller and clearer than either
a unified or a context diff.

tree234__delete(Tin, K, Tout) :-
	tree234__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 tree234__delete_2(tree234(K, V), K, tree234(K, V), bool).
:- mode tree234__delete_2(di, in, uo, out) is det.
:- mode tree234__delete_2(in, in, out, out) is det.

tree234__delete_2(Tin, K, Tout, RH) :-
	(
		Tin = empty,
		Tout = empty,
		RH = no
	;
		Tin = two(K0, V0, T0, T1),
		compare(Result0, K, K0),
		(
			Result0 = (<),
			tree234__delete_2(T0, K, NewT0, RHT0),
			( RHT0 = yes ->
				fix_2node_t0(K0, V0, NewT0, T1, Tout, RH)
			;
				Tout = two(K0, V0, NewT0, T1),
				RH = no
			)
		;
			Result0 = (=),
			(
				tree234__remove_smallest_2(T1, ST1K, ST1V,
					NewT1, RHT1)
			->
				( RHT1 = yes ->
					fix_2node_t1(ST1K, ST1V, T0, NewT1,
						Tout, RH)
				;
					Tout = two(ST1K, ST1V, T0, NewT1),
					RH = no
				)
			;
				% T1 must be empty
				Tout = T0,
				RH = yes
			)
		;
			Result0 = (>),
			tree234__delete_2(T1, K, NewT1, RHT1),
			( RHT1 = yes ->
				fix_2node_t1(K0, V0, T0, NewT1, Tout, RH)
			;
				Tout = two(K0, V0, T0, NewT1),
				RH = no
			)
		)
	;
		Tin = three(K0, V0, K1, V1, T0, T1, T2),
		compare(Result0, K, K0),
		(
			Result0 = (<),
			tree234__delete_2(T0, K, NewT0, RHT0),
			( RHT0 = yes ->
				fix_3node_t0(K0, V0, K1, V1, NewT0, T1, T2,
					Tout, RH)
			;
				Tout = three(K0, V0, K1, V1, NewT0, T1, T2),
				RH = no
			)
		;
			Result0 = (=),
			(
				tree234__remove_smallest_2(T1, ST1K, ST1V,
					NewT1, RHT1)
			->
				( RHT1 = yes ->
					fix_3node_t1(ST1K, ST1V, K1, V1,
						T0, NewT1, T2, Tout, RH)
				;
					Tout = three(ST1K, ST1V, K1, V1,
						T0, NewT1, T2),
					RH = no
				)
			;
				% T1 must be empty
				Tout = two(K1, V1, T0, T2),
				RH = no
			)
		;
			Result0 = (>),
			compare(Result1, K, K1),
			(
				Result1 = (<),
				tree234__delete_2(T1, K, NewT1, RHT1),
				( RHT1 = yes ->
					fix_3node_t1(K0, V0, K1, V1,
						T0, NewT1, T2, Tout, RH)
				;
					Tout = three(K0, V0, K1, V1,
						T0, NewT1, T2),
					RH = no
				)
			;
				Result1 = (=),
				(
					tree234__remove_smallest_2(T2,
						ST2K, ST2V, NewT2, RHT2)
				->
					( RHT2 = yes ->
						fix_3node_t2(K0, V0, ST2K, ST2V,
							T0, T1, NewT2, Tout, RH)
					;
						Tout = three(K0, V0, ST2K, ST2V,
							T0, T1, NewT2),
						RH = no
					)
				;
					% T2 must be empty
					Tout = two(K0, V0, T0, T1),
					RH = no
				)
			;
				Result1 = (>),
				tree234__delete_2(T2, K, NewT2, RHT2),
				( RHT2 = yes ->
					fix_3node_t2(K0, V0, K1, V1,
						T0, T1, NewT2, Tout, RH)
				;
					Tout = three(K0, V0, K1, V1,
						T0, T1, NewT2),
					RH = no
				)
			)
		)
	;
		Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
		compare(Result1, K, K1),
		(
			Result1 = (<),
			compare(Result0, K, K0),
			(
				Result0 = (<),
				tree234__delete_2(T0, K, NewT0, RHT0),
				( RHT0 = yes ->
					fix_4node_t0(K0, V0, K1, V1, K2, V2,
						NewT0, T1, T2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						NewT0, T1, T2, T3),
					RH = no
				)
			;
				Result0 = (=),
				(
					tree234__remove_smallest_2(T1,
						ST1K, ST1V, NewT1, RHT1)
				->
					( RHT1 = yes ->
						fix_4node_t1(ST1K, ST1V, K1, V1,
							K2, V2,
							T0, NewT1, T2, T3,
							Tout, RH)
					;
						Tout = four(ST1K, ST1V, K1, V1,
							K2, V2,
							T0, NewT1, T2, T3),
						RH = no
					)
				;
					% T1 must be empty
					Tout = three(K1, V1, K2, V2,
						T0, T2, T3),
					RH = no
				)
			;
				Result0 = (>),
				tree234__delete_2(T1, K, NewT1, RHT1),
				( RHT1 = yes ->
					fix_4node_t1(K0, V0, K1, V1, K2, V2,
						T0, NewT1, T2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, NewT1, T2, T3),
					RH = no
				)
			)
		;
			Result1 = (=),
			(
				tree234__remove_smallest_2(T2, ST2K, ST2V,
					NewT2, RHT2)
			->
				( RHT2 = yes ->
					fix_4node_t2(K0, V0, ST2K, ST2V, K2, V2,
						T0, T1, NewT2, T3, Tout, RH)
				;
					Tout = four(K0, V0, ST2K, ST2V, K2, V2,
						T0, T1, NewT2, T3),
					RH = no
				)
			;
				% T2 must be empty
				Tout = three(K0, V0, K2, V2, T0, T1, T3),
				RH = no
			)
		;
			Result1 = (>),
			compare(Result2, K, K2),
			(
				Result2 = (<),
				tree234__delete_2(T2, K, NewT2, RHT2),
				( RHT2 = yes ->
					fix_4node_t2(K0, V0, K1, V1, K2, V2,
						T0, T1, NewT2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, T1, NewT2, T3),
					RH = no
				)
			;
				Result2 = (=),
				(
					tree234__remove_smallest_2(T3,
						ST3K, ST3V, NewT3, RHT3)
				->
					( RHT3 = yes ->
						fix_4node_t3(K0, V0, K1, V1,
							ST3K, ST3V,
							T0, T1, T2, NewT3,
							Tout, RH)
					;
						Tout = four(K0, V0, K1, V1,
							ST3K, ST3V,
							T0, T1, T2, NewT3),
						RH = no
					)
				;
					% T3 must be empty
					Tout = three(K0, V0, K1, V1,
						T0, T1, T2),
					RH = no
				)
			;
				Result2 = (>),
				tree234__delete_2(T3, K, NewT3, RHT3),
				( RHT3 = yes ->
					fix_4node_t3(K0, V0, K1, V1, K2, V2,
						T0, T1, T2, NewT3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, T1, T2, NewT3),
					RH = no
				)
			)
		)
	).

%------------------------------------------------------------------------------%

	% We use the same algorithm as tree234__delete.

tree234__remove(Tin, K, V, Tout) :-
	tree234__remove_2(Tin, K, V, Tout, _).

:- pred tree234__remove_2(tree234(K, V), K, V, tree234(K, V), bool).
:- mode tree234__remove_2(di, in, uo, uo, out) is semidet.
:- mode tree234__remove_2(in, in, out, out, out) is semidet.

tree234__remove_2(Tin, K, V, Tout, RH) :-
	(
		Tin = empty,
		fail
	;
		Tin = two(K0, V0, T0, T1),
		compare(Result0, K, K0),
		(
			Result0 = (<),
			tree234__remove_2(T0, K, V, NewT0, RHT0),
			( RHT0 = yes ->
				fix_2node_t0(K0, V0, NewT0, T1, Tout, RH)
			;
				Tout = two(K0, V0, NewT0, T1),
				RH = no
			)
		;
			Result0 = (=),
			(
				tree234__remove_smallest_2(T1, ST1K, ST1V,
					NewT1, RHT1)
			->
				( RHT1 = yes ->
					fix_2node_t1(ST1K, ST1V, T0, NewT1,
						Tout, RH)
				;
					Tout = two(ST1K, ST1V, T0, NewT1),
					RH = no
				)
			;
				% T1 must be empty
				Tout = T0,
				RH = yes
			),
			V = V0
		;
			Result0 = (>),
			tree234__remove_2(T1, K, V, NewT1, RHT1),
			( RHT1 = yes ->
				fix_2node_t1(K0, V0, T0, NewT1, Tout, RH)
			;
				Tout = two(K0, V0, T0, NewT1),
				RH = no
			)
		)
	;
		Tin = three(K0, V0, K1, V1, T0, T1, T2),
		compare(Result0, K, K0),
		(
			Result0 = (<),
			tree234__remove_2(T0, K, V, NewT0, RHT0),
			( RHT0 = yes ->
				fix_3node_t0(K0, V0, K1, V1, NewT0, T1, T2,
					Tout, RH)
			;
				Tout = three(K0, V0, K1, V1, NewT0, T1, T2),
				RH = no
			)
		;
			Result0 = (=),
			(
				tree234__remove_smallest_2(T1, ST1K, ST1V,
					NewT1, RHT1)
			->
				( RHT1 = yes ->
					fix_3node_t1(ST1K, ST1V, K1, V1,
						T0, NewT1, T2, Tout, RH)
				;
					Tout = three(ST1K, ST1V, K1, V1,
						T0, NewT1, T2),
					RH = no
				)
			;
				% T1 must be empty
				Tout = two(K1, V1, T0, T2),
				RH = no
			),
			V = V0
		;
			Result0 = (>),
			compare(Result1, K, K1),
			(
				Result1 = (<),
				tree234__remove_2(T1, K, V, NewT1, RHT1),
				( RHT1 = yes ->
					fix_3node_t1(K0, V0, K1, V1,
						T0, NewT1, T2, Tout, RH)
				;
					Tout = three(K0, V0, K1, V1,
						T0, NewT1, T2),
					RH = no
				)
			;
				Result1 = (=),
				(
					tree234__remove_smallest_2(T2,
						ST2K, ST2V, NewT2, RHT2)
				->
					( RHT2 = yes ->
						fix_3node_t2(K0, V0, ST2K, ST2V,
							T0, T1, NewT2, Tout, RH)
					;
						Tout = three(K0, V0, ST2K, ST2V,
							T0, T1, NewT2),
						RH = no
					)
				;
					% T2 must be empty
					Tout = two(K0, V0, T0, T1),
					RH = no
				),
				V = V1
			;
				Result1 = (>),
				tree234__remove_2(T2, K, V, NewT2, RHT2),
				( RHT2 = yes ->
					fix_3node_t2(K0, V0, K1, V1,
						T0, T1, NewT2, Tout, RH)
				;
					Tout = three(K0, V0, K1, V1,
						T0, T1, NewT2),
					RH = no
				)
			)
		)
	;
		Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
		compare(Result1, K, K1),
		(
			Result1 = (<),
			compare(Result0, K, K0),
			(
				Result0 = (<),
				tree234__remove_2(T0, K, V, NewT0, RHT0),
				( RHT0 = yes ->
					fix_4node_t0(K0, V0, K1, V1, K2, V2,
						NewT0, T1, T2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						NewT0, T1, T2, T3),
					RH = no
				)
			;
				Result0 = (=),
				(
					tree234__remove_smallest_2(T1,
						ST1K, ST1V, NewT1, RHT1)
				->
					( RHT1 = yes ->
						fix_4node_t1(ST1K, ST1V, K1, V1,
							K2, V2,
							T0, NewT1, T2, T3,
							Tout, RH)
					;
						Tout = four(ST1K, ST1V, K1, V1,
							K2, V2,
							T0, NewT1, T2, T3),
						RH = no
					)
				;
					% T1 must be empty
					Tout = three(K1, V1, K2, V2,
						T0, T2, T3),
					RH = no
				),
				V = V0
			;
				Result0 = (>),
				tree234__remove_2(T1, K, V, NewT1, RHT1),
				( RHT1 = yes ->
					fix_4node_t1(K0, V0, K1, V1, K2, V2,
						T0, NewT1, T2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, NewT1, T2, T3),
					RH = no
				)
			)
		;
			Result1 = (=),
			(
				tree234__remove_smallest_2(T2, ST2K, ST2V,
					NewT2, RHT2)
			->
				( RHT2 = yes ->
					fix_4node_t2(K0, V0, ST2K, ST2V, K2, V2,
						T0, T1, NewT2, T3, Tout, RH)
				;
					Tout = four(K0, V0, ST2K, ST2V, K2, V2,
						T0, T1, NewT2, T3),
					RH = no
				)
			;
				% T2 must be empty
				Tout = three(K0, V0, K2, V2, T0, T1, T3),
				RH = no
			),
			V = V1
		;
			Result1 = (>),
			compare(Result2, K, K2),
			(
				Result2 = (<),
				tree234__remove_2(T2, K, V, NewT2, RHT2),
				( RHT2 = yes ->
					fix_4node_t2(K0, V0, K1, V1, K2, V2,
						T0, T1, NewT2, T3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, T1, NewT2, T3),
					RH = no
				)
			;
				Result2 = (=),
				(
					tree234__remove_smallest_2(T3,
						ST3K, ST3V, NewT3, RHT3)
				->
					( RHT3 = yes ->
						fix_4node_t3(K0, V0, K1, V1,
							ST3K, ST3V,
							T0, T1, T2, NewT3,
							Tout, RH)
					;
						Tout = four(K0, V0, K1, V1,
							ST3K, ST3V,
							T0, T1, T2, NewT3),
						RH = no
					)
				;
					% T3 must be empty
					Tout = three(K0, V0, K1, V1,
						T0, T1, T2),
					RH = no
				),
				V = V2
			;
				Result2 = (>),
				tree234__remove_2(T3, K, V, NewT3, RHT3),
				( RHT3 = yes ->
					fix_4node_t3(K0, V0, K1, V1, K2, V2,
						T0, T1, T2, NewT3, Tout, RH)
				;
					Tout = four(K0, V0, K1, V1, K2, V2,
						T0, T1, T2, NewT3),
					RH = no
				)
			)
		)
	).

%------------------------------------------------------------------------------%

	% The algorithm we use similar to tree234__delete, except that we
	% always go down the left subtree.

tree234__remove_smallest(Tin, K, V, Tout) :-
	tree234__remove_smallest_2(Tin, K, V, Tout, _).

:- pred tree234__remove_smallest_2(tree234(K, V), K, V, tree234(K, V), bool).
:- mode tree234__remove_smallest_2(di, uo, uo, uo, out) is semidet.
:- mode tree234__remove_smallest_2(in, out, out, out, out) is semidet.

tree234__remove_smallest_2(Tin, K, V, Tout, RH) :-
	(
		Tin = empty,
		fail
	;
		Tin = two(K0, V0, T0, T1),
		(
			T0 = empty
		->
			K = K0,
			V = V0,
			Tout = T1,
			RH = yes
		;
			tree234__remove_smallest_2(T0, K, V, NewT0, RHT0),
			( RHT0 = yes ->
				fix_2node_t0(K0, V0, NewT0, T1, Tout, RH)
			;
				Tout = two(K0, V0, NewT0, T1),
				RH = no
			)
		)
	;
		Tin = three(K0, V0, K1, V1, T0, T1, T2),
		(
			T0 = empty
		->
			K = K0,
			V = V0,
			Tout = two(K1, V1, T1, T2),
			RH = no
		;
			tree234__remove_smallest_2(T0, K, V, NewT0, RHT0),
			( RHT0 = yes ->
				fix_3node_t0(K0, V0, K1, V1, NewT0, T1, T2,
					Tout, RH)
			;
				Tout = three(K0, V0, K1, V1, NewT0, T1, T2),
				RH = no
			)
		)
	;
		Tin = four(K0, V0, K1, V1, K2, V2, T0, T1, T2, T3),
		(
			T0 = empty
		->
			K = K0,
			V = V0,
			Tout = three(K1, V1, K2, V2, T1, T2, T3),
			RH = no
		;
			tree234__remove_smallest_2(T0, K, V, NewT0, RHT0),
			( RHT0 = yes ->
				fix_4node_t0(K0, V0, K1, V1, K2, V2,
					NewT0, T1, T2, T3, Tout, RH)
			;
				Tout = four(K0, V0, K1, V1, K2, V2,
					NewT0, T1, T2, T3),
				RH = no
			)
		)
	).

%------------------------------------------------------------------------------%

	% 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, V, tree234(K, V), tree234(K, V), tree234(K, V), bool).
:- mode fix_2node_t0(di, di, di, di, uo, out) is det.
:- mode fix_2node_t0(in, in, in, in, out, 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, V, tree234(K, V), tree234(K, V), tree234(K, V), bool).
:- mode fix_2node_t1(di, di, di, di, uo, out) is det.
:- mode fix_2node_t1(in, in, in, in, out, 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, V, K, V, tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_3node_t0(di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_3node_t0(in, in, in, in, in, in, in, out, 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, V, K, V, tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_3node_t1(di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_3node_t1(in, in, in, in, in, in, in, out, 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, V, K, V, tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_3node_t2(di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_3node_t2(in, in, in, in, in, in, in, out, 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, V, K, V, K, V,
	tree234(K, V), tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_4node_t0(di, di, di, di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_4node_t0(in, in, in, in, in, in, in, in, in, in, out, 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, V, K, V, K, V,
	tree234(K, V), tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_4node_t1(di, di, di, di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_4node_t1(in, in, in, in, in, in, in, in, in, in, out, 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, V, K, V, K, V,
	tree234(K, V), tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_4node_t2(di, di, di, di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_4node_t2(in, in, in, in, in, in, in, in, in, in, out, 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, V, K, V, K, V,
	tree234(K, V), tree234(K, V), tree234(K, V), tree234(K, V),
	tree234(K, V), bool).
:- mode fix_4node_t3(di, di, di, di, di, di, di, di, di, di, uo, out) is det.
:- mode fix_4node_t3(in, in, in, in, in, in, in, in, in, in, out, out) 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
	).



More information about the developers mailing list