def _get_candidates_c_b(rule_a, rule_b, config):
  """Return candidates where `c` can be applied to `b` to form `a`."""
  candidates = set()
  if rule_b.arity > 0:
    source_subs = find_substitutions_for_b(rule_a.source, rule_b.source, False)
    target_subs = find_substitutions_for_b(rule_a.target, rule_b.target,
                                           config["allow_repeated_target_nts"])
    for ((source_lhs, source_rhs, source_nt_subs),
         (target_lhs, target_rhs,
          target_nt_subs)) in itertools.product(source_subs, target_subs):
      if source_lhs != target_lhs or source_nt_subs != target_nt_subs:
        continue
      # Don't allow source to only contain a single non-terminal.
      if _is_single_nt(source_rhs):
        continue
      # Optionally don't allow target to only contain a single non-terminal.
      if not config["allow_single_nt_target"] and _is_single_nt(target_rhs):
        continue
      new_rule = _maybe_make_rule(tuple(source_rhs), tuple(target_rhs))
      if new_rule:
        candidates.add(new_rule)
  return candidates
Return candidates where `c` can be applied to `b` to form `a`.
language/compgen/csl/induction/unification_utils.py