code: def local_useless_switch(fgraph, node):
      """
      This rewrite makes the following changes in a graph:
  
          switch(cond, left, right) ->
              if cond is constant and cond == 0: right
              if cond is constant and cond != 0: left
              if left is right -> left
  
      and
  
          switch(le(shape_i{id}(X), 0), 0, shape_i{id}(X)) -> shape_i{id}(X)
  
      """
  
      left = node.inputs[1]
      right = node.inputs[2]
      cond_var = node.inputs[0]
      cond = extract_constant(cond_var, only_process_constants=True)
      out_bcast = node.outputs[0].type.broadcastable
  
      if (
          isinstance(cond, np.ndarray) and cond.ndim == 0
      ) or isinstance(cond, (np.number, np.bool_)):
          if cond == 0:
              correct_out = right
          else:
              correct_out = left
  
          if correct_out.dtype != node.outputs[0].dtype:
              out = cast(correct_out, node.outputs[0].dtype)
          else:
              out = correct_out
  
          if out.type.broadcastable != out_bcast:
              out = broadcast_arrays(out, *node.inputs)[0]
  
          # Copy over stacktrace from selected output to new output
          copy_stack_trace(node.outputs + correct_out, out)
          return [out]
  
      # if left is right -> left
      if left == right:
          # Note: No need to copy over stacktrace, because the input node
          # already has its own stacktrace
          if left.type.broadcastable == out_bcast:
              return [left]
  
          ret = broadcast_arrays(left, cond)[0]
  
          # Copy over stacktrace from switch output and correct branch
          copy_stack_trace(node.outputs + left, ret)
          return [ret]
  
      # This case happens with scan.
      # Elemwise{switch}(le(shape_i{id}(X), 0), 0, shape_i{id}(X)) -> shape_i{id}(X)
      if (
          cond_var.owner
          and isinstance(cond_var.owner.op, Elemwise)
          and isinstance(cond_var.owner.op.scalar_op, ps.LE)
          and cond_var.owner.inputs[0].owner
          and isinstance(cond_var.owner.inputs[0].owner.op, Shape_i)
          and extract_constant(
              cond_var.owner.inputs[1], only_process_constants=True
          )
          == 0
          and extract_constant(left, only_process_constants=True) == 0
          and right == cond_var.owner.inputs[0]
      ):
          assert node.outputs[0].type.is_super(right.type)
          # No need to copy over stacktrace, because the right input node
          # already has its own stacktrace
          return [right]
  
imports: import logging
  from typing import Union
  import numpy
  import pytensor.scalar.basic
  from pytensor import compile
  from pytensor.compile.ops import ViewOp
  from pytensor.graph import FunctionGraph
  from pytensor.graph.basic import Constant, Variable
  from pytensor.graph.rewriting.basic import NodeRewriter, RemovalNodeRewriter, Rewriter, copy_stack_trace, in2out, node_rewriter
  from pytensor.graph.rewriting.db import RewriteDatabase
  from pytensor.raise_op import Assert, CheckAndRaise, assert_op
  from pytensor.tensor.basic import Alloc, AllocEmpty, Join, MakeVector, ScalarFromTensor, Split, TensorFromScalar, alloc, as_tensor_variable, cast, extract_constant, fill, get_underlying_scalar_constant_value, join, ones_like, register_infer_shape, switch, tensor_copy, zeros, zeros_like
  from pytensor.tensor.elemwise import DimShuffle, Elemwise
  from pytensor.tensor.exceptions import NotScalarConstantError
  from pytensor.tensor.extra_ops import broadcast_arrays
  from pytensor.tensor.math import Sum, add, eq
  from pytensor.tensor.shape import Shape_i, shape_padleft
  from pytensor.tensor.sort import TopKOp
  from pytensor.tensor.type import DenseTensorType, TensorType
  from pytensor.tensor.variable import TensorConstant, TensorVariable
  from pytensor.utils import NoDuplicateOptWarningFilter
label_desc: Use image node_id 28 for calling a global function with example usage: local_useless_switch(fgraph, node) and returns: list, list, list, list