
% Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     - Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%
%     - Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the
%       distribution.
%
%     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES-- LOSS OF USE, DATA, OR
% PROFITS-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


\spadtype{BalancedBinaryTrees(S)} is the domain
of balanced binary trees with elements of type \spad{S} at the nodes.
\index{tree!balanced binary}
A binary tree is either \spadfun{empty} or else
\index{balanced binary tree}
consists of a \spadfun{node} having a \spadfun{value}
and two branches, each branch a binary tree.
A balanced binary tree is one that is balanced with respect its leaves.
One with \texht{$2^k$}{2^k} leaves is
perfectly ``balanced'': the tree has minimum depth, and
the \spadfun{left} and \spadfun{right}
branch of every interior node is identical in shape.

Balanced binary trees are useful in algebraic computation for
so-called ``divide-and-conquer'' algorithms.
Conceptually, the data for a problem is initially placed at the
root of the tree.
The original data is then split into two subproblems, one for each
subtree.
And so on.
Eventually, the problem is solved at the leaves of the tree.
A solution to the original problem is obtained by some mechanism
that can reassemble the pieces.
In fact, an implementation of the Chinese Remainder Algorithm
\index{Chinese Remainder Algorithm}
using balanced binary trees was first proposed by David Y. Y.
\index{Yun, David Y. Y.}
Yun at the IBM T. J.
Watson Research Center in Yorktown Heights, New York, in 1978.
It served as the prototype for polymorphic algorithms in
\Language{}.

In what follows, rather than perform a series of computations with
a single expression, the expression is reduced modulo a number of
integer primes, a computation is done with modular arithmetic for
each prime, and the Chinese Remainder Algorithm is used to obtain
the answer to the original problem.
We illustrate this principle with the computation of \texht{$12^2
= 144$}{12 ^ 2 = 144}.

\xtc{
A list of moduli.
}{
\spadcommand{lm := [3,5,7,11]\bound{lm}}
}
\xtc{
The expression \spad{modTree(n, lm)}
creates a balanced binary tree with leaf values
\spad{n mod m} for each modulus \spad{m} in \spad{lm}.
}{
\spadcommand{modTree(12,lm)\free{lm}}
}
\xtc{
Operation \spad{modTree} does this using
operations on balanced binary trees.
We trace its steps.
Create a balanced binary tree \spad{t} of zeros with four leaves.
}{
\spadcommand{t := balancedBinaryTree(\#lm, 0)\bound{t}\free{lm}}
}
\xtc{
The leaves of the tree are set to the individual moduli.
}{
\spadcommand{setleaves!(t,lm)\bound{t1}\free{t}}
}
\xtc{
Use \spadfunX{mapUp} to do
a bottom-up traversal of \spad{t}, setting each interior node
to the product of the values at the nodes of its children.
}{
\spadcommand{mapUp!(t,\_*)\bound{t2}\free{t1}}
}
\xtc{
The value at the node of every subtree is the product of the moduli
of the leaves of the subtree.
}{
\spadcommand{t \bound{t3}\free{t2}}
}
\xtc{
Operation \spadfunX{mapDown}\spad{(t,a,fn)} replaces the value
\spad{v} at each node of \spad{t} by \spad{fn(a,v)}.
}{
\spadcommand{mapDown!(t,12,\_rem)\bound{t4}\free{t3}}
}
\xtc{
The operation \spadfun{leaves} returns the leaves of the resulting
tree.
In this case, it returns the list of \spad{12 mod m} for each
modulus \spad{m}.
}{
\spadcommand{leaves \%\bound{t5}\free{t4}}
}
\xtc{
Compute the square of the images of \spad{12} modulo each \spad{m}.
}{
\spadcommand{squares := [x^2 rem m for x in \% for m in lm]\bound{t6}\free{t5}}
}
\xtc{
Call the Chinese Remainder Algorithm to get the
answer for \texht{$12^2$}{12^2}.
}{
\spadcommand{chineseRemainder(\%,lm)\free{t6}}
}
