// $Id: AccumulateTest.m4,v 1.5 1999/10/03 02:53:16 leavens Exp leavens $

import lib.*;

public class AccumulateTest extends Tester {

    public static void main(String argv[]) {
        System.out.println("");
        System.out.println("Test $RCSfile: AccumulateTest.m4,v $ of $Date: 1999/10/03 02:53:16 $");
        System.out.println("");

	evalsTo("approxEqual(Accumulate.accumulate(new Addition(), new Ones(), 1.0, 10.0), 10.0)", approxEqual(Accumulate.accumulate(new Addition(), new Ones(), 1.0, 10.0), 10.0), true);
	evalsTo("approxEqual(Accumulate.accumulate(new Addition(), new Ones(), 1.0, 10.0), 10.0)", approxEqual(Accumulate.accumulate(new Addition(), new Ones(), 1.0, 10.0), 10.0), true);
	evalsTo("approxEqual(Accumulate.accumulate(new AddTo5(), new Ones(), 1.0, 10.0), 15.0)", approxEqual(Accumulate.accumulate(new AddTo5(), new Ones(), 1.0, 10.0), 15.0), true);
	evalsTo("approxEqual(Accumulate.accumulate(new Multiplication(), new Ints(), 1.0, 4.0), 24.0)", approxEqual(Accumulate.accumulate(new Multiplication(), new Ints(), 1.0, 4.0), 24.0), true);
	evalsTo("approxEqual(Accumulate.accumulate(new Addition(), new SquaresBy2(), 1.0, 100.0), 166650.0)", approxEqual(Accumulate.accumulate(new Addition(), new SquaresBy2(), 1.0, 100.0), 166650.0), true);

	testReport();
    }

    private static class Addition implements Monoid {
	public double combiner(double x, double y) {
	    return x+y;
	}
	public double nullValue() {
	    return 0.0;
	}
    }

    private static class AddTo5 implements Monoid {
	public double combiner(double x, double y) {
	    return x+y;
	}
	public double nullValue() {
	    return 5.0;
	}
    }

    private static class Multiplication implements Monoid {
	public double combiner(double x, double y) {
	    return x*y;
	}
	public double nullValue() {
	    return 1.0;
	}
    }

    private static class Ones implements Series {
	public double value(double a) {
	    return 1.0;
	}
	public double next(double x) {
	    return x + 1.0;
	}
    }

    private static class Ints implements Series {
	public double value(double a) {
	    return a;
	}
	public double next(double x) {
	    return x + 1.0;
	}
    }

    private static class SquaresBy2 implements Series {
	public double value(double a) {
	    return a * a;
	}
	public double next(double x) {
	    return x + 2.0;
	}
    }

}
