class_docstr: EquilibriumGraphRewriter focused on IR measurable rewrites.
  
  This is a stripped down version of the EquilibriumGraphRewriter,
  which specifically targets nodes in `PreserveRVMAppings.needs_measuring`
  that are not yet measurable.
code: def apply(self, fgraph):
      rv_map_feature: Optional[PreserveRVMappings] = getattr(
          fgraph, "preserve_rv_mappings", None
      )
      if not rv_map_feature:
          return None
  
      change_tracker = ChangeTracker()
      fgraph.attach_feature(change_tracker)
  
      changed = True
      max_use_abort = False
      rewriter_name = None
      global_process_count = {}
  
      for rewriter in self.global_rewriters + list(
          self.get_node_rewriters()
      ):
          global_process_count.setdefault(rewriter, 0)
  
      while changed and not max_use_abort:
          changed = False
          max_nb_nodes = len(fgraph.apply_nodes)
          max_use = max_nb_nodes * self.max_use_ratio
  
          # Apply global rewriters
          for grewrite in self.global_rewriters:
              change_tracker.reset()
              grewrite.apply(fgraph)
              if change_tracker.changed:
                  global_process_count[grewrite] += 1
                  changed = True
                  if global_process_count[grewrite] > max_use:
                      max_use_abort = True
                      rewriter_name = getattr(
                          grewrite, "name", None
                      ) or getattr(grewrite, "__name__", "")
  
          # Apply local node rewriters
          q = deque(io_toposort(fgraph.inputs, fgraph.outputs))
          while q:
              node = q.pop()
              if node not in fgraph.apply_nodes:
                  continue
              # This is where we filter only those nodes we care about:
              # Nodes that have variables that we want to measure and are not yet measurable
              if isinstance(node.op, MeasurableVariable):
                  continue
              if not any(
                  out in rv_map_feature.needs_measuring
                  for out in node.outputs
              ):
                  continue
              for node_rewriter in self.node_tracker.get_trackers(
                  node.op
              ):  # noqa F402
                  node_rewriter_change = self.process_node(
                      fgraph, node, node_rewriter
                  )
                  if not node_rewriter_change:
                      continue
                  global_process_count[node_rewriter] += 1
                  changed = True
                  if global_process_count[node_rewriter] > max_use:
                      max_use_abort = True
                      rewriter_name = getattr(
                          node_rewriter, "name", None
                      ) or getattr(node_rewriter, "__name__", "")
                  # If we converted to a MeasurableVariable we're done here!
                  if node not in fgraph.apply_nodes or isinstance(
                      node.op, MeasurableVariable
                  ):
                      # go to next node
                      break
  
      if max_use_abort:
          msg = (
              f"{type(self).__name__} max'ed out by {rewriter_name}."
              "You can safely raise the current threshold of "
              f"{config.optdb__max_use_ratio} with the option `optdb__max_use_ratio`."
          )
          if config.on_opt_error == "raise":
              raise AssertionError(msg)
          else:
              warnings.warn(msg)
      fgraph.remove_feature(change_tracker)
  
imports: import warnings
  from collections import deque
  from typing import Dict, List, Optional, Sequence, Tuple
  import pytensor.tensor
  from pytensor import config
  from pytensor.compile.mode import optdb
  from pytensor.graph.basic import Constant, Variable, ancestors, io_toposort, truncated_graph_inputs
  from pytensor.graph.features import Feature
  from pytensor.graph.fg import FunctionGraph
  from pytensor.graph.replace import clone_replace
  from pytensor.graph.rewriting.basic import ChangeTracker, EquilibriumGraphRewriter, GraphRewriter, node_rewriter, out2in
  from pytensor.graph.rewriting.db import LocalGroupDB, RewriteDatabase, RewriteDatabaseQuery, SequenceDB, TopoDB
  from pytensor.tensor.basic import Alloc
  from pytensor.tensor.elemwise import DimShuffle, Elemwise
  from pytensor.tensor.random.rewriting import local_subtensor_rv_lift
  from pytensor.tensor.rewriting.basic import register_canonicalize
  from pytensor.tensor.rewriting.math import local_exp_over_1_plus_exp
  from pytensor.tensor.rewriting.shape import ShapeFeature
  from pytensor.tensor.rewriting.uncanonicalize import local_max_and_argmax
  from pytensor.tensor.subtensor import AdvancedIncSubtensor, AdvancedIncSubtensor1, AdvancedSubtensor, AdvancedSubtensor1, IncSubtensor, Subtensor
  from pytensor.tensor.variable import TensorVariable
  from pymc.logprob.abstract import MeasurableVariable
  from pymc.logprob.utils import DiracDelta, indices_from_subtensor
label_desc: Use image node_id 1 for calling the MeasurableEquilibriumGraphRewriter obj's underlying member method code with example usage: obj.apply(fgraph) and returns: None