lib/integral.js
function(expr, context, subIntegral) {
      if(expr.type === 'OperatorNode' && expr.op === '^') {
        var base = expr.args[0];
        var exponent = expr.args[1];
        if(base.type === 'OperatorNode' && base.op === '*') {
          return subIntegral(new OperatorNode('*', 'multiply', base.args.map(function(baseChild) {
            return new OperatorNode('^', 'pow', [baseChild, exponent]);
          })), context, "distributing power");
        }
      }
    }
function(expr, context, subIntegral) {
      if(expr.type === 'OperatorNode' && expr.op === '^') {
        var base = expr.args[0];
        var exponent = expr.args[1];
        if(base.type === 'OperatorNode' && base.op === '*') {
          return subIntegral(new OperatorNode('*', 'multiply', base.args.map(function(baseChild) {
            return new OperatorNode('^', 'pow', [baseChild, exponent]);
          })), context, "distributing power");
        }
      }
    }
integral((f(x) * g(x))^h(x), x) = integral(f(x)^h(x) * g(x)^h(x))