code: def truncated_logprob(op, values, *inputs, **kwargs):
      (value,) = values
  
      *rv_inputs, lower, upper, rng = inputs
      rv_inputs = [rng, *rv_inputs]
  
      base_rv_op = op.base_rv_op
      logp = _logprob(base_rv_op, (value,), *rv_inputs, **kwargs)
      # For left truncated RVs, we don't want to include the lower bound in the
      # normalization term
      lower_value = (
          lower - 1 if base_rv_op.dtype.startswith("int") else lower
      )
      lower_logcdf = _logcdf(
          base_rv_op, lower_value, *rv_inputs, **kwargs
      )
      upper_logcdf = _logcdf(base_rv_op, upper, *rv_inputs, **kwargs)
  
      if base_rv_op.name:
          logp.name = f"{base_rv_op}_logprob"
          lower_logcdf.name = f"{base_rv_op}_lower_logcdf"
          upper_logcdf.name = f"{base_rv_op}_upper_logcdf"
  
      is_lower_bounded = not (
          isinstance(lower, TensorConstant)
          and np.all(np.isneginf(lower.value))
      )
      is_upper_bounded = not (
          isinstance(upper, TensorConstant)
          and np.all(np.isinf(upper.value))
      )
  
      lognorm = 0
      if is_lower_bounded and is_upper_bounded:
          lognorm = logdiffexp(upper_logcdf, lower_logcdf)
      elif is_lower_bounded:
          lognorm = pt.log1mexp(lower_logcdf)
      elif is_upper_bounded:
          lognorm = upper_logcdf
  
      logp = logp - lognorm
  
      if is_lower_bounded:
          logp = pt.switch(value < lower, -np.inf, logp)
  
      if is_upper_bounded:
          logp = pt.switch(value <= upper, logp, -np.inf)
  
      if is_lower_bounded and is_upper_bounded:
          logp = check_parameters(
              logp,
              pt.le(lower, upper),
              msg="lower_bound <= upper_bound",
          )
  
      return logp
  
imports: from functools import singledispatch
  import numpy
  import pytensor
  import pytensor.tensor
  from pytensor import scan
  from pytensor.graph import Op
  from pytensor.graph.basic import Node
  from pytensor.raise_op import CheckAndRaise
  from pytensor.scan import until
  from pytensor.tensor import TensorConstant, TensorVariable
  from pytensor.tensor.random.basic import NormalRV
  from pytensor.tensor.random.op import RandomVariable
  from pymc.distributions.continuous import TruncatedNormal, bounded_cont_transform
  from pymc.distributions.dist_math import check_parameters
  from pymc.distributions.distribution import Distribution, SymbolicRandomVariable, _moment, moment
  from pymc.distributions.shape_utils import _change_dist_size, change_dist_size, to_tuple
  from pymc.distributions.transforms import _default_transform
  from pymc.exceptions import TruncationError
  from pymc.logprob.abstract import _logcdf, _logprob
  from pymc.logprob.basic import icdf, logcdf
  from pymc.math import logdiffexp
  from pymc.util import check_dist_not_registered
label_desc: Use image node_id 5 for calling a global function with example usage: truncated_logprob(op, values) and returns: logp