Take the following two pseudocode extracts from Aske Plaat's admirable summary:
[1]
function MTDF(root : node_type; f : integer; d : integer) : integer;
g := f;
upperbound := +INFINITY; ////////////////////// NB1
lowerbound := -INFINITY;
repeat
if g == lowerbound then beta := g + 1 else beta := g;
g := AlphaBetaWithMemory(root, beta - 1, beta, d);
if g < beta then upperbound := g else lowerbound := g;
until lowerbound >= upperbound;
return g;
[2]
function AlphaBetaWithMemory(n : node_type; alpha , beta , d : integer) : integer;
if retrieve(n) == OK then /* Transposition table lookup */
if n.lowerbound >= beta then return n.lowerbound;
if n.upperbound <= alpha then return n.upperbound;
alpha := max(alpha, n.lowerbound);
beta := min(beta, n.upperbound);
if d == 0 then g := evaluate(n); /* leaf node */
else if n == MAXNODE then
g := -INFINITY; a := alpha; /* save original alpha value */
c := firstchild(n);
while (g < beta) and (c != NOCHILD) do
g := max(g, AlphaBetaWithMemory(c, a, beta, d - 1));
a := max(a, g);
c := nextbrother(c);
else /* n is a MINNODE */
g := +INFINITY; b := beta; /* save original beta value */
c := firstchild(n);
while (g > alpha) and (c != NOCHILD) do
g := min(g, AlphaBetaWithMemory(c, alpha, b, d - 1));
b := min(b, g);
c := nextbrother(c);
/* Traditional transposition table storing of bounds */
/* Fail low result implies an upper bound */ ///////////////////////// NB2
if g <= alpha then n.upperbound := g; store n.upperbound;
/* Found an accurate minimax value - will not occur if called with zero window */
if g > alpha and g < beta then
n.lowerbound := g; n.upperbound := g; store n.lowerbound, n.upperbound;
/* Fail high result implies a lower bound */
if g >= beta then n.lowerbound := g; store n.lowerbound;
return g;
Clearly, 'upperbound' and 'lowerbound' are being used with different meanings in the two functions. The MT driver refers to upperbound as, literally an Upper Bound, while the AlphaBetaWithMemory function clearly states "Fail low result implies an upper bound", and implements accordingly. All of which (given the caveat above) is fine, until we look at lines 5ff of the latter code block:
alpha := max(alpha, n.lowerbound);
beta := min(beta, n.upperbound);
Hasn't he totally confused the issue here by reverting to the opposite meanings of upper and lower *as used in the driver*? Or am I the one totally confused??
I've mailed AP, but with no reply so far... anyone else who can shed light here, do please!
Francis

