/*
 * spigot.cpp: Implementation of the Spigot base classes, i.e.
 * methods which convert between a spigot description and the
 * various other output types.
 *
 * This file is where the implementation of the core spigot
 * algorithm lives.
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "spigot.h"
#include "cr.h"

/* ----------------------------------------------------------------------
 * Class definitions private to this source file.
 */

class Core1 : public Core {
    Source *source;
    bool started;
    bigint matrix[4];
    bigint bot, top;
    bool top_is_infinite;
    void endpoints_internal(bigint *endpoints,
                            const bigint *finalmatrix);
  public:
    Core1(Source *asource);
    ~Core1();
    virtual void premultiply(const bigint matrix[4]);
    virtual Core *clone();
    virtual void refine();
    virtual int max_endpoints();
    virtual int endpoints(bigint *endpoints);

    /*
     * Because Core1 has a unique child Source, it passes through the
     * special-case is_rational function to that Source.
     */
    virtual bool is_rational(bigint *n, bigint *d);
};

class GeneratorSource : public BinaryIntervalSource {
    Core *core_orig, *core_cloned;
    BracketingGenerator bg;
    int crState;
  public:
    GeneratorSource(Core *acore);
    virtual ~GeneratorSource();
    virtual GeneratorSource *clone();
    virtual void gen_bin_interval(bigint *ret_lo, bigint *ret_hi,
                                  unsigned *ret_bits);
};

class RationalSource : public Source {
    bigint n, d;
  public:
    RationalSource(const bigint &an, const bigint &ad);

    virtual RationalSource *clone();
    virtual bool gen_interval(bigint *low, bigint *high);
    virtual bool gen_matrix(bigint *matrix);
    virtual bool is_rational(bigint *n, bigint *d);
};

/* ----------------------------------------------------------------------
 * Utility function.
 */

void matmul(bigint outmatrix[4], const bigint a[4], const bigint b[4])
{
    bigint newm0 = a[0]*b[0] + a[1]*b[2];
    bigint newm1 = a[0]*b[1] + a[1]*b[3];
    bigint newm2 = a[2]*b[0] + a[3]*b[2];
    outmatrix[3] = a[2]*b[1] + a[3]*b[3];
    outmatrix[0] = newm0;
    outmatrix[1] = newm1;
    outmatrix[2] = newm2;
}

/* ----------------------------------------------------------------------
 * Diagnostics.
 */

Debuggable::Debuggable()
    : debugging(false)
{
}

Debuggable::~Debuggable()
{
}

void Debuggable::dprintv(const char *fmt, va_list ap)
{
    if (!debugging)
        return;

    printf("[%p] ", this);
    debug_printv(stdout, fmt, ap);
    putchar('\n');
}

/* ----------------------------------------------------------------------
 * Administrivia: tiny functions in abstract base classes.
 */

bool Coreable::is_rational(bigint * /*n*/, bigint * /*d*/)
{
    return false;
}

Core *Source::toCore()
{
    return new Core1(this);
}

Core *Core::toCore()
{
    return this;
}

Source *Source::toSource()
{
    return this;
}

Source *Core::toSource()
{
    return new GeneratorSource(this);
}

/* ----------------------------------------------------------------------
 * Core1, the primary default implementation of Core.
 */

Core1::Core1(Source *asource)
    : source(asource)
    , started(false)
{
    dprint("hello Core1 %p", asource);
}

Core1::~Core1()
{
    delete source;
}

void Core1::premultiply(const bigint inmatrix[4])
{
    dprint("premultiply: %4m %4m", inmatrix, matrix);
    matmul(matrix, inmatrix, matrix);
    dprint("matrix after premult %4m", matrix);
}

Core *Core1::clone()
{
    return new Core1(source->clone());
}

void Core1::refine()
{
    bool force_absorb = false;

    dprint("refine started");

    if (!started) {
        /*
         * Initialise with the identity matrix, and fetch the
         * interval bounds.
         */
        matrix[0] = matrix[3] = 1;
        matrix[1] = matrix[2] = 0;
        source->gen_interval(&bot, &top);
        top_is_infinite = (top == 0);  /* special case meaning infinity */
        started = true;
        dprint("Core1 init: interval [%b,%b]", &bot, &top);
    }

    do {
        bigint inmatrix[4];
        force_absorb = source->gen_matrix(inmatrix);
        dprint("postmultiply: %4m %4m", matrix, inmatrix);
        matmul(matrix, matrix, inmatrix);
        dprint("matrix after postmult %4m", matrix);
    } while (force_absorb);
}

int Core1::max_endpoints()
{
    return 2;
}

int Core1::endpoints(bigint *endpoints)
{
    dprint("endpoints for %4m", matrix);
    endpoints[0] = matrix[0] * bot + matrix[1];
    endpoints[1] = matrix[2] * bot + matrix[3];
    dprint("  1st endpoint %b / %b", &endpoints[0], &endpoints[1]);
    if (!top_is_infinite) {
        endpoints[2] = matrix[0] * top + matrix[1];
        endpoints[3] = matrix[2] * top + matrix[3];
        dprint("  finite 2nd endpoint %b / %b", &endpoints[2], &endpoints[3]);
    } else {
        /*
         * To evaluate a Mobius function at infinity, we take the
         * limit as x -> inf of its value at x.
         *
         * If at least one of a,c is nonzero, then the constant terms
         * b,d become insignificant, and the limit of (ax+b)/(cx+d) is
         * the same as the limit of ax/cx. But if a,c are both zero,
         * so that we have a constant function, then (ax+b)/(cx+d) =
         * b/d for any finite x, and hence the limit at infinity is
         * b/d as well.
         */
        if (matrix[0] == 0 && matrix[2] == 0) {
            endpoints[2] = matrix[1];
            endpoints[3] = matrix[3];
        } else {
            endpoints[2] = matrix[0];
            endpoints[3] = matrix[2];
        }
        dprint("  infinite 2nd endpoint %b / %b", &endpoints[2], &endpoints[3]);
    }
    return 2;
}

bool Core1::is_rational(bigint *n, bigint *d)
{
    return source->is_rational(n, d);
}

/* ----------------------------------------------------------------------
 * The Generator class.
 */

Generator::Generator(Coreable *acore)
    : started(false), we_are_now_constant(false)
{
    core = acore->toCore();
    max_endpoints = core->max_endpoints();
    assert(max_endpoints > 0);
    endpoints = new bigint[2 * max_endpoints];
    dprint("hello Generator %p", core);
}

Generator::~Generator()
{
    delete core;
    delete[] endpoints;
}

void Generator::ensure_started()
{
    if (!started) {
        core->refine();
        started = true;
    }
}

int Generator::iterate_spigot_algorithm(bool force)
{
    /*
     * This is the main loop of the spigot algorithm. It bounces on
     * core->refine() until the core's current state describes a
     * sensible interval rather than something with a pole in it, then
     * returns the current set of endpoints so that one of its wrapper
     * functions can check in turn whether there's enough detail to
     * satisfy the client.
     *
     * Returns the number of endpoints currently known.
     *
     * If 'force' is true, core->refine() will be called at least
     * once; otherwise we'll check first to see if we have enough data
     * already.
     */

    ensure_started();

    dprint("iterate_spigot_algorithm beginning");

    while (1) {
        if (!we_are_now_constant && force)
            core->refine();
        force = true;

        spigot_check_exception();

        int n_endpoints = core->endpoints(endpoints);

        dprint("iterate_spigot_algorithm got endpoints:");
        for (int i = 0; i < n_endpoints; ++i)
            dprint("  %d: %b / %b", i, &endpoints[2*i], &endpoints[2*i+1]);

        int d_sign = bigint_sign(endpoints[1]);
        bool d_signs_ok = (d_sign != 0);
        bool all_constant = true;
        for (int i = 1; i < n_endpoints; ++i) {
            if (endpoints[2*i] != endpoints[0] ||
                endpoints[2*i+1] != endpoints[1])
                all_constant = false;
            if (bigint_sign(endpoints[2*i+1]) != bigint_sign(endpoints[1]))
                d_signs_ok = false;
        }

        /*
         * We return if the interval is bounded, or if we have a
         * constant function. (The constant function returning
         * infinity counts as bounded, and is the _only_ thing
         * touching the point at infinity which does so!)
         */
        if (d_signs_ok || all_constant) {
            /*
             * If our interval is a single point, set the
             * we_are_now_constant flag, which will inhibit any
             * further calls to core->refine(). (This is necessary
             * because spigot sources which return a matrix intended
             * to terminate the stream in this way cannot deal
             * gracefully with being called again afterwards.)
             */
            if (all_constant)
                we_are_now_constant = true;

            dprint("iterate_spigot_algorithm returning");
            return n_endpoints;
        }
    }
}

static void divide_with_exactness(bigint *q, bool *remainder,
                                  const bigint &n, const bigint &d)
{
    *q = fdiv(n, d);
    *remainder = (*q) * d != n;
}

void Generator::iterate_to_bounds(bigint *rlo, bigint *rhi,
                                  bool *rlo_open, bool *rhi_open,
                                  int minwidth,
                                  const bigint *scale,
                                  bool force_refine)
{
    /*
     * Returns a bounding interval for the number, bounded by the two
     * integers 'lo' and 'hi'.
     *
     * Also optionally (if lo_open and hi_open are non-NULL) returns
     * information about whether those endpoints are open or closed,
     * i.e. distinguishes between (a,b), (a,b], [a,b) and [a,b].
     *
     * If minwidth is nonzero, this function iterates until hi-lo is
     * at most that. (Passing minwidth==1 risks never returning due to
     * an exactness hazard, but minwidth>=2 should reliably return.)
     * If minwidth is zero, we just return whatever bounding interval
     * we first get (though we do at least one refinement step first).
     *
     * If scale is provided, the bounding interval is not for the
     * number itself but for the number times 'scale'. (scale must be
     * positive.)
     */

    while (1) {
        int n_endpoints = iterate_spigot_algorithm(force_refine);
        force_refine = true;           // for next time

        bigint &lo = *rlo, &hi = *rhi;
        bool lo_extra, hi_extra;

        // In this mode, we never expect the constant-inf output function.
        assert(endpoints[1] != 0);

        if (scale) {
            for (int i = 0; i < n_endpoints; ++i)
                endpoints[2*i+0] *= *scale;
        }

        divide_with_exactness(&lo, &lo_extra, endpoints[0], endpoints[1]);
        hi = lo;
        hi_extra = lo_extra;
        for (int i = 1; i < n_endpoints; ++i) {
            bigint tmp;
            bool tmp_extra;
            divide_with_exactness(&tmp, &tmp_extra,
                                  endpoints[2*i+0], endpoints[2*i+1]);
            if (tmp < lo || (tmp == lo && !tmp_extra && lo_extra)) {
                lo = tmp;
                lo_extra = tmp_extra;
            }
            if (tmp > hi || (tmp == hi && tmp_extra && !hi_extra)) {
                hi = tmp;
                hi_extra = tmp_extra;
            }
        }

        /*
         * Our numbers are currently in the form (integer, boolean
         * saying whether there's a nonzero fraction part to go
         * with it). For the lower interval bound, that's
         * equivalent to (integer bound, boolean saying if it's an
         * open bound). For the higher bound, we must round the
         * integer part up if the fraction is nonzero.
         */
        if (hi_extra)
            ++hi;

        if (!minwidth || hi - lo <= minwidth) {
            /*
             * OK, return.
             */
            if (rlo_open) *rlo_open = lo_extra;
            if (rhi_open) *rhi_open = hi_extra;
            return;
        }
    }
}

bool Generator::iterate_to_floor_or_inf(bigint *rfloor, bool *rconstant)
{
    /*
     * Iterates until the number has a constant integer part (that is,
     * really a constant _floor_), and returns it.
     *
     * Also fills in 'constant', if non-NULL, indicating whether the
     * number is _exactly_ its constant integer part.
     *
     * A second possibility is that the spigot matrix might have
     * turned into the constant function always returning infinity
     * (which signals termination in continued fraction output mode).
     * Returning the boolean 'false' indicates this; 'true' indicates
     * that a sensible integer was returned.
     */
    bool force = false;
    while (1) {
        int n_endpoints = iterate_spigot_algorithm(force);
        force = true;                  // for next time

        // iterate_spigot_algorithm has ensured that all the
        // denominators of the endpoints have the same sign. Hence, we
        // need only test the first denominator for zero to tell
        // whether they're all zero and we have the constant-inf
        // function.
        if (endpoints[1] == 0)
            return false;

        bigint &n = *rfloor;

        // See if everything has the same integer part.
        bool ok = true;
        n = fdiv(endpoints[0], endpoints[1]);
        bool constant = endpoints[0] == n * endpoints[1];
        for (int i = 1; i < n_endpoints; ++i) {
            bigint tmp = fdiv(endpoints[2*i+0], endpoints[2*i+1]);
            if (rconstant && endpoints[2*i+0] != n * endpoints[2*i+1])
                constant = false;
            if (tmp != n) {
                ok = false;
                break;
            }
        }

        // If so, return it (it's already in *rfloor). Otherwise go
        // round again.
        if (ok) {
            if (rconstant)
                *rconstant = constant;
            return true;
        }
    }
}

bigint Generator::iterate_to_floor(bool *constant)
{
    /*
     * Wrapper around iterate_to_floor_or_inf, which asserts that the
     * inf case never comes up.
     */
    bigint ret;

#ifndef NDEBUG
    bool finite =
#endif
        iterate_to_floor_or_inf(&ret, constant);
    assert(finite);

    return ret;
}

/* ----------------------------------------------------------------------
 * CfracGenerator: convert a Core into a stream of continued fraction
 * terms.
 */

CfracGenerator::CfracGenerator(Coreable *acore)
    : Generator(acore)
    , done(false)
{
    dprint("hello CfracGenerator %p", core);
}

bool CfracGenerator::get_term(bigint *term)
{
    bool ret;
    bigint outmatrix[4];

    if (done)
        return false;

    ret = iterate_to_floor_or_inf(term);

    if (!ret) {
        /*
         * An infinite return value means that the continued
         * fraction has terminated. At this point, and forever
         * hereafter, we return false.
         */
        dprint("terminated");
        done = true;
        return false;
    } else {
        /*
         * Otherwise, we return this term, and premultiply in a
         * matrix which represents subtracting it off and taking the
         * reciprocal: that is, x |-> 1/(x-a) = (0x+1)/(1x-a),
         * represented by the matrix (0  1)
         *                           (1 -a).
         */
        outmatrix[0] = 0;
        outmatrix[1] = outmatrix[2] = 1;
        outmatrix[3] = -*term;
        dprint("extract cfrac term %b: %4m", term, outmatrix);
        core->premultiply(outmatrix);
        return true;
    }
}

/* ----------------------------------------------------------------------
 * ConvergentsGenerator: wrap CfracGenerator so that it returns
 * rational convergents reconstituted from the raw continued fraction
 * terms.
 */

ConvergentsGenerator::ConvergentsGenerator(Coreable *acore)
    : cfg(acore)
    , cvn(1)
    , pcvn(0)
    , cvd(0)
    , pcvd(1)
{
}

bool ConvergentsGenerator::get_convergent(bigint *n, bigint *d)
{
    bigint term;
    bool ret;

    /*
     * Fetch a continued fraction term, if one is available, and
     * fold it in to the current stored convergent.
     */
    if ((ret = cfg.get_term(&term))) {
        bigint newcvn = cvn * term + pcvn;
        bigint newcvd = cvd * term + pcvd;
        pcvn = cvn;
        pcvd = cvd;
        cvn = newcvn;
        cvd = newcvd;
    }

    /*
     * Return the current convergent.
     */
    *n = cvn;
    *d = cvd;

    /*
     * Tell our caller whether this convergent is any different from
     * the last one, in case they want to stop outputting if so.
     */
    return ret;
}

/* ----------------------------------------------------------------------
 * BracketingGenerator: generate pairs of rationals converging to a
 * target, avoiding exactness hazards.
 */
BracketingGenerator::BracketingGenerator(Coreable *acore)
    : Generator(acore)
    , bits(0)
    , prevbits(0)
    , started(false)
{
    dprint("hello BracketingGenerator %p", core);
}

void BracketingGenerator::set_denominator_lower_bound_shift(unsigned newbits)
{
    if (bits < newbits)
        bits = newbits;
}

void BracketingGenerator::set_denominator_lower_bound(bigint ad)
{
    set_denominator_lower_bound_shift(bigint_approxlog2(ad) + 1);
}

void BracketingGenerator::get_bracket_shift(bigint *ret_nlo, bigint *ret_nhi,
                                            unsigned *dbits)
{
    bigint matrix[4];

    ensure_started();    // prerequisite for calling core->premultiply

    bits += 2;
    matrix[0] = (bigint)1 << (bits - prevbits);
    matrix[1] = matrix[2] = 0;
    matrix[3] = 1;
    core->premultiply(matrix);

    prevbits = bits;

    *dbits = bits;
    iterate_to_bounds(ret_nlo, ret_nhi, NULL, NULL, 2, NULL, false);
    dprint("returning: (%b,%b) / 2^%d", ret_nlo, ret_nhi, (int)bits);
}

void BracketingGenerator::get_bracket(bigint *ret_nlo, bigint *ret_nhi,
                                      bigint *ret_d)
{
    unsigned dbits;
    get_bracket_shift(ret_nlo, ret_nhi, &dbits);
    *ret_d = (bigint)1 << dbits;
}

/* ----------------------------------------------------------------------
 * StaticGenerator: answer queries which don't require modifying the
 * underlying core.
 */

StaticGenerator::StaticGenerator(Coreable *acore)
    : Generator(acore)
{
}

bigint StaticGenerator::get_floor(bool *constant)
{
    return iterate_to_floor(constant);
}

bigint StaticGenerator::get_approximate_approximant(const bigint &d)
{
    bigint n1, n2;

    /*
     * This function returns an integer somewhere near d*x
     * (specifically, within 2 of it), but avoids exactness hazards by
     * not necessarily returning the exact floor(d*x). Useful in range
     * reduction, when 'nearly' is generally good enough and 'exactly'
     * is hazardous.
     */
    iterate_to_bounds(&n1, &n2, NULL, NULL, 2, &d, false);

    return n1;
}

int StaticGenerator::get_sign()
{
    bigint a, b;
    bool a_open, b_open;
    int a_sign, b_sign;

    /*
     * Treat rationals specially, since they might be exactly zero.
     */
    if (core->is_rational(&a, &b)) {
        assert(b > 0);
        return bigint_sign(a);
    }

    /*
     * Otherwise, just iterate until we can agree on the sign of the
     * number.
     */
    while (1) {
        iterate_to_bounds(&a, &b, &a_open, &b_open, 0, NULL, true);
        a_sign = bigint_sign(a);
        b_sign = bigint_sign(b);

        if (a_sign > 0 || (a_sign == 0 && a_open))
            return +1;
        if (b_sign < 0 || (b_sign == 0 && b_open))
            return -1;
        if (a_sign == 0 && b_sign == 0)
            return 0;
    }
}

int StaticGenerator::try_get_sign()
{
    bigint a, b;
    bool a_open, b_open;
    int a_sign, b_sign;

    /*
     * Like get_sign(), but only does a single iteration, and returns
     * 0 if a (nonzero) sign was not successfully obtained.
     */

    iterate_to_bounds(&a, &b, &a_open, &b_open, 0, NULL, true);
    a_sign = bigint_sign(a);
    b_sign = bigint_sign(b);

    if (a_sign > 0 || (a_sign == 0 && a_open))
        return +1;
    if (b_sign < 0 || (b_sign == 0 && b_open))
        return -1;

    return 0;
}

void StaticGenerator::premultiply(const bigint matrix[4])
{
    core->premultiply(matrix);
}

/* ----------------------------------------------------------------------
 * BaseSource: abstract implementation of a spigot data source which
 * requires its subclass to provide a stream of digits in a specified
 * base.
 *
 * A number expressed in base b as
 * 
 *   intpart . d1 d2 d3 ...
 * 
 * is expressed as a spigot composition of the functions
 * 
 *   ( x |-> intpart + x/b ) o ( x |-> d1 + x/b) o ( x |-> d2 + x/b) o ...
 * 
 * applied to the initial interval [0,1].
 */

BaseSource::BaseSource(bigint abase, bool anegate)
    : first_digit(true)
    , base(abase)
    , negate(anegate)
{
    assert(base > 0);
    dprint("hello BaseSource %b", &base);
}

bool BaseSource::gen_interval(bigint *low, bigint *high)
{
    *low = 0;
    *high = base;

    /*
     * Force absorption of the initial integer part, which probably
     * won't be within that interval.
     */
    return true;
}

bool BaseSource::gen_matrix(bigint *matrix)
{
    bigint digit;
    if (!gen_digit(&digit)) {
        /*
         * The positional expansion has terminated. We therefore
         * return the matrix corresponding to the zero function,
         * which is (0 0) representing x |-> (0x+0)/(0x+1).
         *          (0 1)
         */
        matrix[0] = matrix[1] = matrix[2] = 0;
        matrix[3] = 1;
        dprint("termination matrix %4m", matrix);
    } else {
        if (!negate || digit >= 0 || !first_digit) {
            /*
             * We want a function which maps x to x/b + k. As a
             * Mobius transformation, this is equivalent to
             * (1x + kb)/(0x + b), so we output the matrix (1 kb)
             *                                             (0  b).
             */
            matrix[0] = 1;
            matrix[1] = digit * base;
            matrix[2] = 0;
            matrix[3] = base;
            dprint("normal digit %b matrix %4m", &digit, matrix);
        } else {
            /*
             * Special case of a negative first digit and
             * display-mode input, just as in the output side. So
             * digit < 0; the 'real' digit we've received is
             * digit+1; and we therefore want to map x to
             * (digit+1) - x/b. Our matrix is therefore (-1 b(digit+1))
             *                                          ( 0     b     ).
             */
            matrix[0] = -1;
            matrix[1] = (digit + 1) * base;
            matrix[2] = 0;
            matrix[3] = base;
            dprint("neg first digit %b matrix %4m", &digit, matrix);
        }
        first_digit = false;
    }

    return false;
}

/* ----------------------------------------------------------------------
 * CfracSource: abstract implementation of a spigot data source which
 * requires its subclass to provide a stream of continued fraction
 * terms.
 *
 * A number whose continued fraction expansion is
 * 
 *   t1 + 1/(t2 + 1/(t3 + 1/(...)))
 * 
 * is expressed as a spigot composition of the functions
 * 
 *   ( x |-> t1 + 1/x ) o ( x |-> t2 + 1/x ) o ( x |-> t3 + 1/x ) o ...
 * 
 * applied to the initial interval [0,infinity].
 */

bool CfracSource::gen_interval(bigint *low, bigint *high)
{
    *low = 0;
    *high = 0;                         /* represents infinity */

    /*
     * Force absorption of the first matrix, in case the integer part
     * is negative.
     */
    return true;
}

bool CfracSource::gen_matrix(bigint *matrix)
{
    if (gen_term(&matrix[0])) {
        /*
         * We want a function which maps x to k + 1/x. As a Mobius
         * transformation, this is equivalent to (kx + 1)/(1x + 0),
         * so we output the matrix (k 1)
         *                         (1 0).
         */
        matrix[1] = matrix[2] = 1;
        matrix[3] = 0;
        dprint("normal term %b matrix %4m", &matrix[0], matrix);
    } else {
        /*
         * The positional expansion has terminated. We therefore
         * return the matrix corresponding to the function that
         * always returns infinity, which is (0 1) representing
         *                                   (0 0)
         * x |-> (0x+1)/(0x+0).
         *
         * This is the correct way to terminate a continued
         * fraction: the previous term (k+1/x) becomes
         * (k+1/infinity), which is exactly k.
         */
        matrix[0] = matrix[2] = matrix[3] = 0;
        matrix[1] = 1;
        dprint("termination matrix %4m", matrix);
    }

    return false;
}

/* ----------------------------------------------------------------------
 * BinaryIntervalSource: turn a stream of rational intervals with
 * power-of-2 denominators into a spigot source.
 */

BinaryIntervalSource::BinaryIntervalSource()
    : started(false)
{
    dprint("hello BinaryIntervalSource");
}

bool BinaryIntervalSource::gen_interval(bigint *low, bigint *high)
{
    *low = 0;
    *high = 1;
    /*
     * Those numbers are almost certainly lies, so enforce the
     * absorption of at least one matrix.
     */
    return true;
}

bool BinaryIntervalSource::gen_matrix(bigint *matrix)
{
    bigint this_lo, this_hi;
    unsigned this_bits;

    gen_bin_interval(&this_lo, &this_hi, &this_bits);
    dprint("got interval (%b,%b) / 2^%d", &this_lo, &this_hi, (int)this_bits);

    if (!started) {
        /*
         * Initial matrix just maps the starting [0,1] directly to the
         * first interval we just received.
         */
        matrix[0] = this_hi - this_lo;
        matrix[1] = this_lo;
        matrix[2] = 0;
        matrix[3] = (bigint)1 << this_bits;
        dprint("initial matrix %4m", matrix);
        started = true;
        lo = this_lo;
        hi = this_hi;
        bits = this_bits;
        return false;
    }

    /*
     * Start by putting our old and new intervals over a common
     * denominator, i.e. equalising bits and this_bits.
     */
    if (bits < this_bits) {
        lo <<= (this_bits - bits);
        hi <<= (this_bits - bits);
        bits = this_bits;
    }
    if (this_bits < bits) {
        this_lo <<= (bits - this_bits);
        this_hi <<= (bits - this_bits);
        this_bits = bits;
    }
    dprint("old interval (%b,%b) / 2^%d", &lo, &hi, (int)bits);

    /*
     * Now intersect the new interval with the old one, in case the
     * client isn't passing us a stream of strictly nested intervals.
     */
    if (this_lo < lo)
        this_lo = lo;
    if (this_hi > hi)
        this_hi = hi;
    dprint("new interval (%b,%b) / 2^%d", &this_lo, &this_hi, (int)bits);
    assert(this_lo <= this_hi);

    /*
     * Construct a matrix which narrows from the old interval to the
     * new one.
     */
    matrix[0] = this_hi - this_lo;
    matrix[1] = this_lo - lo;
    matrix[2] = 0;
    matrix[3] = hi - lo;
    if (matrix[3] == 0)
        matrix[3] = 1;
    dprint("refining matrix %4m", matrix);

    /*
     * And update our current interval.
     */
    lo = this_lo;
    hi = this_hi;

    return false;
}

/* ----------------------------------------------------------------------
 * RationalSource: turn an exact rational number provided as input
 * into a spigot source.
 *
 * This is a trivial spigot description: it consists of the single
 * function (x |-> n/d).
 */

RationalSource::RationalSource(const bigint &an, const bigint &ad)
    : n(an), d(ad)
{
    assert(d > 0);
}

RationalSource *RationalSource::clone()
{
    return new RationalSource(n, d);
}

bool RationalSource::gen_interval(bigint *low, bigint *high)
{
    // It really doesn't matter what these are
    *low = 0;
    *high = 1;
    return true;
}

bool RationalSource::gen_matrix(bigint *matrix)
{
    /*
     * We want a constant function which maps any x to n/d. As a
     * Mobius transformation, this is equivalent to (0x + n)/(0x +
     * d), so we output the matrix (0 n)
     *                             (0 d).
     */
    matrix[1] = n;
    matrix[3] = d;
    matrix[0] = matrix[2] = 0;
    return false;
}

bool RationalSource::is_rational(bigint *rn, bigint *rd)
{
    *rn = n;
    *rd = d;
    return true;
}

/*
 * Trivial constructors for integers and rationals, which might as
 * well go here rather than put them in a pointless extra source file.
 */
Spigot *spigot_integer(bigint const &n)
{
    return new RationalSource(n, 1);
}

Spigot *spigot_rational(bigint const &an, bigint const &ad)
{
    assert(ad != 0);

    /*
     * Reduce the fraction to its lowest terms. This is partly a
     * space-saving measure, and partly functional: reliably doing
     * this means that other parts of the code can depend on it. For
     * instance, spigot_cbrt() will recognise a rational that's a
     * perfect cube divided by another perfect cube, but can't easily
     * recognise one that's (say) twice a perfect cube over twice
     * another perfect cube.
     */
    bigint a = gcd(an, ad);

    /*
     * Normalise the sign of d to 1.
     */
    if (ad < 0) {
        a = -a;
    }

    return new RationalSource(an / a, ad / a);
}

/* ----------------------------------------------------------------------
 * GeneratorSource: turn a Core back into a Source, by reconstructing
 * a stream of matrices converging to the same value.
 *
 * This is done by the completely trivial method of feeding the output
 * of a BracketingGenerator straight to our base class of
 * BinaryIntervalSource.
 */

GeneratorSource::GeneratorSource(Core *acore)
    : core_orig(acore)
    , core_cloned(acore->clone())
    , bg(core_cloned)
{
    crState = -1;
    dprint("hello GeneratorSource %p", core_cloned);
}

GeneratorSource::~GeneratorSource()
{
    delete core_orig;
}

GeneratorSource *GeneratorSource::clone()
{
    return new GeneratorSource(core_orig->clone());
}

void GeneratorSource::gen_bin_interval(bigint *ret_lo, bigint *ret_hi,
                                       unsigned *ret_bits)
{
    bg.get_bracket_shift(ret_lo, ret_hi, ret_bits);
}
