addDowns(L,Out) :- addDowns1(L,[],Out).

addDowns1([],In,In  ).
addDowns1([H|T],In,Out) :- addDown(In,H,Temp), addDowns1(T,Temp,Out).

addDown([], X, [X]). 
addDown([K=V|T], K0=V0, Add) :- 
	compare(Order, K, K0),
	addDown1(Order, K=V, T, K0=V0, Add).

addDown1(<,   Old,  T,  New, [New,Old|T]).
addDown1(=,   Old,  T,  Old, [Old|T]). 
addDown1(=,   Old,  T,  New, [Old,New|T]) :- Old \= New. 
addDown1(>,   Old,  T,  New, [Old    |Add]) :- addDown(T,New,Add).

addUps(L,Out) :- addUps1(L,[],Out).

addUps1([],In,In  ).
addUps1([H|T],In,Out) :- addUp(In,H,Temp), addUps1(T,Temp,Out).

addUp([], X, [X]). 
addUp([K=V|T], K0=V0, Add) :- 
	compare(Order, K, K0),
	addUp1(Order, K=V, T, K0=V0, Add).

addUp1(>,   Old,  T,  New, [New,Old|T]).
addUp1(=,   Old,  T,  New, [Old,New|T]). 
addUp1(<,   Old,  T,  New, [Old    |Add]) :- addUp(T,New,Add).

%%%%-------------
oset_union([], Union, Union).
oset_union([H1|T1], L2, Union) :-
    union2(L2, H1, T1, Union).

union2([], H1, T1, [H1|T1]).
union2([H2|T2], H1, T1, Union) :-
    compare(Order, H1, H2),
    union3(Order, H1, T1, H2, T2, Union).

union3(<, H1, T1,  H2, T2, [H1|Union]) :-
    union2(T1, H2, T2, Union).
union3(=, H1, T1, _H2, T2, [H1|Union]) :-
    oset_union(T1, T2, Union).
union3(>, H1, T1,  H2, T2, [H2|Union]) :-
    union2(T2, H1, T1, Union).
