docs: def generate_bqm(graph, table, decision,
                   linear_energy_ranges=None, quadratic_energy_ranges=None, min_classical_gap=2,
                   precision=7, max_decision=8, max_variables=10,
                   return_auxiliary=False):
      """Get a binary quadratic model with specific ground states.
  
      Args:
          graph (:obj:`~networkx.Graph`):
              Defines the structure of the generated binary quadratic model.
  
          table (iterable):
              Iterable of valid configurations (of spin-values). Each configuration is a tuple of
              variable assignments ordered by `decision`.
  
          decision (list/tuple):
              The variables in the binary quadratic model which have specified configurations.
  
          linear_energy_ranges (dict, optional):
              Dict of the form {v: (min, max, ...} where min and max are the range of values allowed
              to v. The default range is [-2, 2].
  
          quadratic_energy_ranges (dict, optional):
              Dict of the form {(u, v): (min, max), ...} where min and max are the range of values
              allowed to (u, v). The default range is [-1, 1].
  
          min_classical_gap (float):
              The minimum energy gap between the highest feasible state and the lowest infeasible
              state.
  
          precision (int, optional, default=7):
              Values returned by the optimization solver are rounded to `precision` digits of
              precision.
  
          max_decision (int, optional, default=4):
              Maximum number of decision variables allowed. The algorithm is valid for arbitrary
              sizes of problem but can be extremely slow.
  
          max_variables (int, optional, default=4):
              Maximum number of variables allowed. The algorithm is valid for arbitrary
              sizes of problem but can be extremely slow.
  
          return_auxiliary (bool, optional, False):
              If True, the auxiliary configurations are returned for each configuration in table.
  
      Returns:
          If return_auxiliary is False:
  
              :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.
  
              float: The classical gap.
  
          If return_auxiliary is True:
  
              :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.
  
              float: The classical gap.
  
              dict: The auxiliary configurations, keyed on the configurations in table.
  
      Raises:
          ImpossiblePenaltyModel: If the penalty model cannot be built. Normally due
              to a non-zero infeasible gap.
  
      """
  
      # Developer note: This function is input checking and output formatting. The logic is
      # in _generate_ising
  
      if not isinstance(graph, nx.Graph):
          raise TypeError("expected input graph to be a NetworkX Graph.")
  
      if not set().union(*table).issubset({-1, 1}):
          raise ValueError("expected table to be spin-valued")
  
      if not isinstance(decision, list):
          decision = list(decision)  # handle iterables
      if not all(v in graph for v in decision):
          raise ValueError("given graph does not match the variable labels in decision variables")
  
      num_var = len(decision)
      if any(len(config) != num_var for config in table):
          raise ValueError("number of decision variables does not match all of the entires in the table")
  
      if len(decision) > max_decision:
          raise ValueError(("The table is too large. Note that larger models can be built by setting "
                            "max_decision to a higher number, but generation could be extremely slow."))
  
      if len(graph) > max_variables:
          raise ValueError(("The graph is too large. Note that larger models can be built by setting "
                            "max_variables to a higher number, but generation could be extremely slow."))
  
      if linear_energy_ranges is None:
          linear_energy_ranges = defaultdict(lambda: (-2, 2))
      if quadratic_energy_ranges is None:
          quadratic_energy_ranges = defaultdict(lambda: (-1, 1))
  
      if not isinstance(table, Mapping):
          table = {config: 0. for config in table}
  
      h, J, offset, gap, aux = _generate_ising(graph, table, decision, min_classical_gap,
                                               linear_energy_ranges, quadratic_energy_ranges)
  
      bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN)
      bqm.add_variables_from((v, round(bias, precision)) for v, bias in h.items())
      bqm.add_interactions_from((u, v, round(bias, precision)) for (u, v), bias in J.items())
      bqm.add_offset(round(offset, precision))
  
      if return_auxiliary:
          return bqm, round(gap, precision), aux
      else:
          return bqm, round(gap, precision)