Generate the algebra inverse dataset.

  Each sample is a symbolic math equation involving unknown variables. The
  task is to solve for the given variable. The target is the resulting
  expression.

  Args:
    alphabet_size: How many possible variables there are. Max 52.
    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 solve for and the math
    equation, and target-list is a list of tokens encoding the resulting math
    expression after solving for the variable.

  Raises:
    ValueError: If `max_depth` < `min_depth`.

def algebra_inverse(alphabet_size=26, min_depth=0, max_depth=2,
                    nbr_cases=10000):
  """Generate the algebra inverse dataset.

  Each sample is a symbolic math equation involving unknown variables. The
  task is to solve for the given variable. The target is the resulting
  expression.

  Args:
    alphabet_size: How many possible variables there are. Max 52.
    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 solve for and the math
    equation, and target-list is a list of tokens encoding the resulting math
    expression after solving for the variable.

  Raises:
    ValueError: If `max_depth` < `min_depth`.
  """

  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))

  alg_cfg = math_dataset_init(alphabet_size)
  for _ in range(nbr_cases):
    sample, target = generate_algebra_inverse_sample(
        alg_cfg.vlist,
        list(alg_cfg.ops.values()), alg_cfg.solve_ops, min_depth, max_depth)
    yield {
        "inputs": alg_cfg.int_encoder(sample),
        "targets": alg_cfg.int_encoder(target)
    }