public class DerivVisitor implements ExpressionVisitor {
    protected String var;
    public DerivVisitor(String var) { this.var = var; }
    public Object visitNumericLiteral(NumericLiteral n) {
        return new NumericLiteral(0.0);
    }
    public Object visitVariable(Variable v) {
        return new NumericLiteral(v.same(var) ? 1.0 : 0.0);
    }
    public Object visitSum(Sum s) {
        return new Sum((Expression)(s.addend().visit(this)),
                       (Expression)(s.augend().visit(this)));
    }
    public Object visitProduct(Product p) {
        return new Sum(new Product((Expression)(p.multiplier().visit(this)),
                                   p.multiplicand()),
                       new Product(p.multiplier(),
                                   (Expression)(p.multiplicand().visit(this))));
    }

    public static void main(String [] argv) {
        System.out.println("d/dx of x = "
                           + new Variable("x").visit(new DerivVisitor("x")));
        System.out.println("d/dx of x + 2 = "
                           + new Sum(new Variable("x"),
                                     new NumericLiteral(2.0))
                                     .visit(new DerivVisitor("x")));
        System.out.println("d/dx of y * (x + 2) = "
                           + new Product(new Variable("y"),
                                         new Sum(new Variable("x"),
                                                 new NumericLiteral(2.0)))
                               .visit(new DerivVisitor("x")));
    }

}
