def _get_controllable_inputs_targets(
      self,
      source_sentences,
      target_sentences,
      evidence,
  ):
    """Constructs the inputs and targets for the controllable setting."""
    # The difference in the controllable setting is that, when we determine what
    # evidence justifies an update, we need to transfer the marker to the
    # associated source sentence.
    inputs_renderables = []
    targets_renderables = []

    source_texts = [str(s.text).strip() for s in source_sentences]
    target_texts = [str(t.text).strip() for t in target_sentences]
    cruncher = difflib.SequenceMatcher(a=source_texts, b=target_texts)
    update_pairs = []
    for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
      if tag == "replace":
        # Compute the best matching
        source_sentences_subset = source_sentences[alo:ahi]
        target_sentences_subset = target_sentences[blo:bhi]
        source_texts_subset = source_texts[alo:ahi]
        target_texts_subset = target_texts[blo:bhi]
        best_match, _ = match_sents(source_texts_subset, target_texts_subset)

        # Depending on whether or not there is a match add an addition, edit,
        # or deletion.
        last_match_idx = 0
        for source_sentence, match_idx in zip(source_sentences_subset,
                                              best_match):
          # If source sent didn't get matched it needs to be deleted and we
          # proceed.
          if match_idx is None:
            inputs_renderables.extend([DELETION_MARKER, source_sentence])
            continue
          # Otherwise, we first check if there is a gap between the last and
          # current match index. If there is then target sentences need to be
          # added.
          if match_idx != last_match_idx:
            for target_sentence in target_sentences_subset[
                last_match_idx:match_idx]:
              placeholder_input = Sentence(ADDITION_MARKER, "",
                                           self.evidence_marker_type)
              inputs_renderables.append(placeholder_input)
              targets_renderables.append(target_sentence)
              update_pairs.append((placeholder_input, target_sentence))
          # We then add the sentence pair and update the last match index.
          inputs_renderables.extend([EDIT_MARKER, source_sentence])
          targets_renderables.append(target_sentences_subset[match_idx])
          update_pairs.append(
              (source_sentence, target_sentences_subset[match_idx]))
          last_match_idx = match_idx + 1
        # Lastly we add any remaining target sentences.
        if last_match_idx != len(target_sentences_subset):
          for target_sentence in target_sentences_subset[last_match_idx:]:
            placeholder_input = Sentence(ADDITION_MARKER, "",
                                         self.evidence_marker_type)
            inputs_renderables.append(placeholder_input)
            targets_renderables.append(target_sentence)
            update_pairs.append((placeholder_input, target_sentence))
      elif tag == "insert":
        for i in range(blo, bhi):
          # We create a placeholder sentence to associate evidence to later
          placeholder_input = Sentence(ADDITION_MARKER, "",
                                       self.evidence_marker_type)
          inputs_renderables.append(placeholder_input)
          targets_renderables.append(target_sentences[i])
          update_pairs.append((placeholder_input, target_sentences[i]))
      elif tag == "equal":
        inputs_renderables.extend(source_sentences[alo:ahi])
        targets_renderables.extend(
            s.delimiter for s in source_sentences[alo:ahi])
      elif tag == "delete":
        for s in source_sentences[alo:ahi]:
          inputs_renderables.extend([DELETION_MARKER, s])

    # Add context
    inputs_renderables.append(CONTEXT_MARKER)
    inputs_temp = render_all(inputs_renderables)
    input_length = self._get_length(inputs_temp)
    for e in evidence:
      evidence_length = self._get_length(str(e))
      if input_length + evidence_length > self.max_input_length:
        continue
      # Check if evidence supports an update
      is_support = False
      for src, tgt in update_pairs:
        # THIS IS WHERE THE MAGIC HAPPENS
        if tgt.entity_ids & e.entity_ids:
          src.evidence.append(e)
          is_support = True
      if (is_support and self.include_evidence) or self.include_distractors:
        inputs_renderables.append(e)
      input_length += evidence_length

    inputs = render_all(inputs_renderables)
    targets = render_all(targets_renderables)

    yield {"inputs": inputs, "targets": targets}
Constructs the inputs and targets for the controllable setting.
language/fruit/rendering_utils.py