def calculus_integrate(alphabet_size=26,
                       min_depth=0,
                       max_depth=2,
                       nbr_cases=10000):
  """Generate the calculus integrate dataset.

  Each sample is a symbolic math expression involving unknown variables. The
  task is to take the indefinite integral of the expression. The target is the
  resulting expression.

  Args:
    alphabet_size: How many possible variables there are. Max 26.
    min_depth: Minimum depth of the expression trees on both sides of the
        equals sign in the equation.
    max_depth: Maximum depth of the expression trees on both sides of the
        equals sign in the equation.
    nbr_cases: The number of cases to generate.

  Yields:
    A dictionary {"inputs": input-list, "targets": target-list} where
    input-list are the tokens encoding the variable to integrate with respect
    to and the expression to integrate, and target-list is a list of tokens
    encoding the resulting math expression after integrating.

  Raises:
    ValueError: If `max_depth` < `min_depth`, or if alphabet_size > 26.
  """
  if max_depth < min_depth:
    raise ValueError("max_depth must be greater than or equal to min_depth. "
                     "Got max_depth=%s, min_depth=%s" % (max_depth, min_depth))

  # Don't allow alphabet to use capital letters. Those are reserved for function
  # names.
  if alphabet_size > 26:
    raise ValueError(
        "alphabet_size must not be greater than 26. Got %s." % alphabet_size)

  functions = {"log": "L"}
  alg_cfg = math_dataset_init(alphabet_size, digits=5, functions=functions)
  nbr_case = 0
  while nbr_case < nbr_cases:
    try:
      sample, target = generate_calculus_integrate_sample(
          alg_cfg.vlist,
          list(alg_cfg.ops.values()), min_depth, max_depth, alg_cfg.functions)
      yield {
          "inputs": alg_cfg.int_encoder(sample),
          "targets": alg_cfg.int_encoder(target)
      }
    except:  # pylint:disable=bare-except
      continue
    if nbr_case % 10000 == 0:
      print(" calculus_integrate: generating case %d." % nbr_case)
    nbr_case += 1
Generate the calculus integrate dataset.

  Each sample is a symbolic math expression involving unknown variables. The
  task is to take the indefinite integral of the expression. The target is the
  resulting expression.

  Args:
    alphabet_size: How many possible variables there are. Max 26.
    min_depth: Minimum depth of the expression trees on both sides of the
        equals sign in the equation.
    max_depth: Maximum depth of the expression trees on both sides of the
        equals sign in the equation.
    nbr_cases: The number of cases to generate.

  Yields:
    A dictionary {"inputs": input-list, "targets": target-list} where
    input-list are the tokens encoding the variable to integrate with respect
    to and the expression to integrate, and target-list is a list of tokens
    encoding the resulting math expression after integrating.

  Raises:
    ValueError: If `max_depth` < `min_depth`, or if alphabet_size > 26.