class_docstr: For ``select(cond, a, b)``, there are 2 cases where we can replace it with a single simpler op
  
  1. If ``cond`` is a const scalar (or a const tensor but all elements are the same, which is
     equivalent to a scalar), then we replace ``select(cond, a, b)`` with simply ``a`` or ``b``
  
     .. code-block::
  
          Input graph:
  
              const(scalar cond) -|
                                  |
              a ------------------|-> select -> output
                                  |
              b ------------------|
  
          Output graph:
  
              if cond:
                  a -> output
              else:
                  b -> output
  
  2. If ``cond`` is a more complicated const, and ``a`` is an inf const,
     then we replace ``a`` with ``select(cond, a, 0)``, then return ``a + b``
  
      .. code-block::
  
          Input graph:
  
              const(cond) -|
                           |
              const(±inf) -|-> select -> output
                           |
              b -----------|
  
          Output graph:
  
              select(cond, ±inf, 0) -|
                                     |-> add -> output
              b ---------------------|
  
      Note that ``select(cond, ±inf, 0))`` will further get eliminated by
      ``const_elimination``, so in the end the op in graph is simply ``add``
  
      This replacement is based on floating-point arithmetic
  
      .. code-block::
  
          inf + b = inf
          -inf + b = -inf
          0 + b = b
  
      PS: if ``a`` is not inf const but ``b`` is, then we would swap ``a`` and ``b``
code: def try_to_transform_inf_const_selection(
      select_op: Operation,
      cond_val: np.ndarray,
      a_val: np.ndarray,
      b_val: np.ndarray,
  ) -> Var:
      assert select_op.op_type == "select"
      assert cond_val is not None
  
      # check if a or b is inf const
      # if a is not but b is, then swap a and b
      a: np.ndarray = None
      b: Var = None
      if a_val is not None and np.all(np.abs(a_val) > 1e38):
          a = a_val
          b = select_op.b
      elif b_val is not None and np.all(np.abs(b_val) > 1e38):
          a = b_val
          b = select_op.a
          cond_val = np.logical_not(cond_val)
      else:
          return None
  
      # build add
      cond_val, a = np.broadcast_arrays(cond_val, a)
      a = a.copy()
      a[np.where(np.logical_not(cond_val))] = 0.0
      return mb.add(
          x=a, y=b, before_op=select_op, name=select_op.outputs[0].name
      )
  
imports: import numpy
  from coremltools.converters.mil.mil import Block
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, Var
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.ops.defs._utils import broadcast_shapes
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
label_desc: Use image node_id 4 for calling the select_optimization obj's underlying member method code with example usage: obj.try_to_transform_inf_const_selection(select_op, cond_val, a_val, b_val) and returns: mb, None