def run_inference(source, wrapper, nodes_per_rule_per_cell=1):
  """Determine set of parses given model.

  The set of output parses will be pruned by score, such that each cell
  of the chart contains only at most `nodes_per_rule_per_cell` nodes
  per last applied rule.

  Args:
    source: Input string.
    wrapper: Instance of InferenceWrapper.
    nodes_per_rule_per_cell: Will prune any nodes per cell per rule above this
      number.

  Returns:
    List of (target string, score) for highest scoring derivations, or None
    if there is no parse.
  """
  tokens = source.split(" ")
  node_fn = get_node_fn(wrapper)
  max_cell_size = wrapper.config.get("max_cell_size", None)
  postprocess_cell_fn = get_postprocess_cell_fn(nodes_per_rule_per_cell,
                                                max_cell_size)
  nodes = qcfg_parser.parse(
      tokens,
      wrapper.rules,
      node_fn=node_fn,
      postprocess_cell_fn=postprocess_cell_fn,
      max_single_nt_applications=wrapper.config["max_single_nt_applications"],
      verbose=False)

  if not nodes:
    return None

  # TODO(petershaw): Consider merging nodes with same target.
  targets_and_scores = [
      (node.target_string(), get_root_score(wrapper, node)) for node in nodes
  ]

  random.shuffle(targets_and_scores)
  return sorted(targets_and_scores, key=lambda x: -x[1])
Determine set of parses given model.

  The set of output parses will be pruned by score, such that each cell
  of the chart contains only at most `nodes_per_rule_per_cell` nodes
  per last applied rule.

  Args:
    source: Input string.
    wrapper: Instance of InferenceWrapper.
    nodes_per_rule_per_cell: Will prune any nodes per cell per rule above this
      number.

  Returns:
    List of (target string, score) for highest scoring derivations, or None
    if there is no parse.
  
language/compgen/csl/model/inference/inference_parser.py