code: def logprob_MixtureRV(
      op,
      values,
      *inputs: Optional[Union[TensorVariable, slice]],
      name=None,
      **kwargs,
  ):
      (value,) = values
  
      join_axis = cast(Variable, inputs[0])
      indices = cast(TensorVariable, inputs[1 : op.indices_end_idx])
      comp_rvs = cast(TensorVariable, inputs[op.indices_end_idx :])
  
      assert len(indices) > 0
  
      if len(indices) > 1 or indices[0].ndim > 0:
          if isinstance(join_axis.type, NoneTypeT):
              # `join_axis` will be `NoneConst` if the "join" was a `MakeVector`
              # (i.e. scalar measurable variables were combined to make a
              # vector).
              # Since some form of advanced indexing is necessarily occurring, we
              # need to reformat the MakeVector arguments so that they fit the
              # `Join` format expected by the logic below.
              join_axis_val = 0
              comp_rvs = [comp[None] for comp in comp_rvs]
              original_shape = (len(comp_rvs),)
          else:
              join_axis_val = constant_fold((join_axis,))[0].item()
              original_shape = shape_tuple(comp_rvs[0])
  
          bcast_indices = expand_indices(indices, original_shape)
  
          logp_val = pt.empty(bcast_indices[0].shape)
  
          for m, rv in enumerate(comp_rvs):
              idx_m_on_axis = pt.nonzero(
                  pt.eq(bcast_indices[join_axis_val], m)
              )
              m_indices = tuple(
                  v[idx_m_on_axis]
                  for i, v in enumerate(bcast_indices)
                  if i != join_axis_val
              )
              # Drop superfluous join dimension
              rv = rv[0]
              # TODO: Do we really need to do this now?
              # Could we construct this form earlier and
              # do the lifting for everything at once, instead of
              # this intentional one-off?
              rv_m = rv_pull_down(rv[m_indices] if m_indices else rv)
              val_m = value[idx_m_on_axis]
              logp_m = _logprob_helper(rv_m, val_m)
              logp_val = pt.set_subtensor(
                  logp_val[idx_m_on_axis], logp_m
              )
  
      else:
          # FIXME: This logprob implementation does not support mixing across distinct components,
          # but we sometimes use it, because MixtureRV does not keep information about at which
          # dimension scalar indexing actually starts
  
          # If the stacking operation expands the component RVs, we have
          # to expand the value and later squeeze the logprob for everything
          # to work correctly
          join_axis_val = (
              None
              if isinstance(join_axis.type, NoneTypeT)
              else join_axis.data
          )
  
          if join_axis_val is not None:
              value = pt.expand_dims(value, axis=join_axis_val)
  
          logp_val = 0.0
          for i, comp_rv in enumerate(comp_rvs):
              comp_logp = _logprob_helper(comp_rv, value)
              if join_axis_val is not None:
                  comp_logp = pt.squeeze(comp_logp, axis=join_axis_val)
              logp_val += ifelse(
                  pt.eq(indices[0], i),
                  comp_logp,
                  pt.zeros_like(comp_logp),
              )
  
      return logp_val
  
imports: from typing import List, Optional, Tuple, Union, cast
  import pytensor
  import pytensor.tensor
  from pytensor.graph.basic import Apply, Constant, Variable
  from pytensor.graph.fg import FunctionGraph
  from pytensor.graph.op import Op, compute_test_value
  from pytensor.graph.rewriting.basic import EquilibriumGraphRewriter, node_rewriter
  from pytensor.ifelse import IfElse, ifelse
  from pytensor.scalar import Switch
  from pytensor.scalar import switch
  from pytensor.tensor.basic import Join, MakeVector, switch
  from pytensor.tensor.random.rewriting import local_dimshuffle_rv_lift, local_rv_size_lift, local_subtensor_rv_lift
  from pytensor.tensor.rewriting.shape import ShapeFeature
  from pytensor.tensor.shape import shape_tuple
  from pytensor.tensor.subtensor import AdvancedSubtensor, AdvancedSubtensor1, as_index_literal, get_canonical_form_slice, is_basic_idx
  from pytensor.tensor.type import TensorType
  from pytensor.tensor.type_other import NoneConst, NoneTypeT, SliceConstant, SliceType
  from pytensor.tensor.variable import TensorVariable
  from pymc.logprob.abstract import MeasurableElemwise, MeasurableVariable, _logprob, _logprob_helper
  from pymc.logprob.rewriting import PreserveRVMappings, assume_measured_ir_outputs, local_lift_DiracDelta, measurable_ir_rewrites_db, subtensor_ops
  from pymc.logprob.utils import check_potential_measurability, replace_rvs_by_values
  from pymc.pytensorf import constant_fold
label_desc: Use image node_id 6 for calling a global function with example usage: logprob_MixtureRV(op, values) and returns: logp_val