code: def apply_replacements_to_text(
      text: str,
      replacements: List[Tuple[int, int, str, float]],
      min_prob: float = 0.5,
      replace_hyphen_to_space: bool = False,
      dp_data: Tuple[defaultdict, defaultdict, defaultdict, int] = None,
      min_dp_score_per_symbol: float = -99.9,
  ) -> str:
      """Filter and apply replacements to the input sentence.
      Args:
          text: input sentence;
          replacements: list of proposed replacements (probably intersecting), each is a tuple (begin, end, text, probability);
          min_prob: threshold on replacement probability;
          replace_hyphen_to_space: if True, hyphens in replacements will be converted to spaces;
          dp_data: n-gram mapping vocabularies used by dynamic programming, if None - dynamic programming is not used;
          min_dp_score_per_symbol: threshold on dynamic programming sum score averaged by hypothesis length
      Returns:
          corrected sentence
      """
      # sort replacements by positions
      replacements.sort()
      # filter replacements
      # Note that we do not skip replacements with same text, otherwise intersecting candidates with lower probability can win
      filtered_replacements = []
      for j in range(len(replacements)):
          replacement = replacements[j]
          begin, end, candidate, prob = replacement
          fragment = text[begin:end]
          candidate_spaced = " ".join(list(candidate.replace(" ", "_")))
          fragment_spaced = " ".join(list(fragment.replace(" ", "_")))
          # apply penalty if candidate length is bigger than fragment length
          # to avoid cases like "forward-looking" replacing "looking" in "forward looking" resulting in "forward forward looking"
          if len(candidate) > len(fragment):
              penalty = len(fragment) / len(candidate)
              prob *= penalty
          # skip replacement with low probability
          if prob < min_prob:
              continue
          # skip replacements with some predefined templates, e.g. "*'s" => "*s"
          if check_banned_replacements(fragment, candidate):
              continue
          if dp_data is not None:
              path = get_alignment_by_dp(
                  candidate_spaced, fragment_spaced, dp_data
              )
              # path[-1][3] is the sum of logprobs for best path of dynamic programming: divide sum_score by length
              if (
                  path[-1][3] / (len(fragment))
                  < min_dp_score_per_symbol
              ):
                  continue
  
          # skip replacement if it intersects with previous replacement and has lower probability, otherwise remove previous replacement
          if (
              len(filtered_replacements) > 0
              and filtered_replacements[-1][1] > begin
          ):
              if filtered_replacements[-1][3] > prob:
                  continue
              else:
                  filtered_replacements.pop()
          filtered_replacements.append((begin, end, candidate, prob))
  
      return substitute_replacements_in_text(
          text, filtered_replacements, replace_hyphen_to_space
      )
  
imports: import json
  import math
  import random
  import re
  from collections import defaultdict, namedtuple
  from typing import Dict, List, Set, Tuple, Union
  import numpy
  from numba import jit
label_desc: Use image node_id 12 for calling a global function with example usage: apply_replacements_to_text(text, replacements, min_prob, replace_hyphen_to_space, dp_data, min_dp_score_per_symbol) and returns: substitute_replacements_in_text