class_docstr: Represents a piecewise function.
  
  Usage:
  
    Piecewise( (expr,cond), (expr,cond), ... )
      - Each argument is a 2-tuple defining an expression and condition
      - The conds are evaluated in turn returning the first that is True.
        If any of the evaluated conds are not explicitly False,
        e.g. ``x < 1``, the function is returned in symbolic form.
      - If the function is evaluated at a place where all conditions are False,
        nan will be returned.
      - Pairs where the cond is explicitly False, will be removed and no pair
        appearing after a True condition will ever be retained. If a single
        pair with a True condition remains, it will be returned, even when
        evaluation is False.
  
  Examples
  ========
  
  >>> from sympy import Piecewise, log, piecewise_fold
  >>> from sympy.abc import x, y
  >>> f = x**2
  >>> g = log(x)
  >>> p = Piecewise((0, x < -1), (f, x <= 1), (g, True))
  >>> p.subs(x,1)
  1
  >>> p.subs(x,5)
  log(5)
  
  Booleans can contain Piecewise elements:
  
  >>> cond = (x < y).subs(x, Piecewise((2, x < 0), (3, True))); cond
  Piecewise((2, x < 0), (3, True)) < y
  
  The folded version of this results in a Piecewise whose
  expressions are Booleans:
  
  >>> folded_cond = piecewise_fold(cond); folded_cond
  Piecewise((2 < y, x < 0), (3 < y, True))
  
  When a Boolean containing Piecewise (like cond) or a Piecewise
  with Boolean expressions (like folded_cond) is used as a condition,
  it is converted to an equivalent :class:`~.ITE` object:
  
  >>> Piecewise((1, folded_cond))
  Piecewise((1, ITE(x < 0, y > 2, y > 3)))
  
  When a condition is an ``ITE``, it will be converted to a simplified
  Boolean expression:
  
  >>> piecewise_fold(_)
  Piecewise((1, ((x >= 0) | (y > 2)) & ((y > 3) | (x < 0))))
  
  See Also
  ========
  
  piecewise_fold
  piecewise_exclusive
  ITE
docstr: Return either None (if the conditions of self depend only on x) else
  a Piecewise expression whose expressions (handled by the handler that
  was passed) are paired with the governing x-independent relationals,
  e.g. Piecewise((A, a(x) & b(y)), (B, c(x) | c(y)) ->
  Piecewise(
      (handler(Piecewise((A, a(x) & True), (B, c(x) | True)), b(y) & c(y)),
      (handler(Piecewise((A, a(x) & True), (B, c(x) | False)), b(y)),
      (handler(Piecewise((A, a(x) & False), (B, c(x) | True)), c(y)),
      (handler(Piecewise((A, a(x) & False), (B, c(x) | False)), True))
docstr_tok: ["Return","either","None","(","if","the","conditions","of","self","depend","only","on","x",")","else","a","Piecewise","expression","whose","expressions","(","handled","by","the","handler","that","was","passed",")","are","paired","with","the","governing","x-independent","relationals",",","e.g",".","Piecewise","(","(","A",",","a","(","x",")","&","b","(","y",")",")",",","(","B",",","c","(","x",")","|","c","(","y",")",")","-",">","Piecewise","(","(","handler","(","Piecewise","(","(","A",",","a","(","x",")","&","True",")",",","(","B",",","c","(","x",")","|","True",")",")",",","b","(","y",")","&","c","(","y",")",")",",","(","handler","(","Piecewise","(","(","A",",","a","(","x",")","&","True",")",",","(","B",",","c","(","x",")","|","False",")",")",",","b","(","y",")",")",",","(","handler","(","Piecewise","(","(","A",",","a","(","x",")","&","False",")",",","(","B",",","c","(","x",")","|","True",")",")",",","c","(","y",")",")",",","(","handler","(","Piecewise","(","(","A",",","a","(","x",")","&","False",")",",","(","B",",","c","(","x",")","|","False",")",")",",","True",")",")"]
code: def _handle_irel(self, x, handler):
      """Return either None (if the conditions of self depend only on x) else
      a Piecewise expression whose expressions (handled by the handler that
      was passed) are paired with the governing x-independent relationals,
      e.g. Piecewise((A, a(x) & b(y)), (B, c(x) | c(y)) ->
      Piecewise(
          (handler(Piecewise((A, a(x) & True), (B, c(x) | True)), b(y) & c(y)),
          (handler(Piecewise((A, a(x) & True), (B, c(x) | False)), b(y)),
          (handler(Piecewise((A, a(x) & False), (B, c(x) | True)), c(y)),
          (handler(Piecewise((A, a(x) & False), (B, c(x) | False)), True))
      """
      # identify governing relationals
      rel = self.atoms(Relational)
      irel = list(
          ordered(
              [
                  r
                  for r in rel
                  if x not in r.free_symbols
                  and r not in (S.true, S.false)
              ]
          )
      )
      if irel:
          args = {}
          exprinorder = []
          for truth in product((1, 0), repeat=len(irel)):
              reps = dict(zip(irel, truth))
              # only store the true conditions since the false are implied
              # when they appear lower in the Piecewise args
              if 1 not in truth:
                  cond = (
                      None  # flag this one so it doesn't get combined
                  )
              else:
                  andargs = Tuple(*[i for i in reps if reps[i]])
                  free = list(andargs.free_symbols)
                  if len(free) == 1:
                      from sympy.solvers.inequalities import (
                          reduce_inequalities,
                          _solve_inequality,
                      )
  
                      try:
                          t = reduce_inequalities(andargs, free[0])
                          # ValueError when there are potentially
                          # nonvanishing imaginary parts
                      except (ValueError, NotImplementedError):
                          # at least isolate free symbol on left
                          t = And(
                              *[
                                  _solve_inequality(
                                      a, free[0], linear=True
                                  )
                                  for a in andargs
                              ]
                          )
                  else:
                      t = And(*andargs)
                  if t is S.false:
                      continue  # an impossible combination
                  cond = t
              expr = handler(self.xreplace(reps))
              if isinstance(expr, self.func) and len(expr.args) == 1:
                  expr, econd = expr.args[0]
                  cond = And(econd, True if cond is None else cond)
              # the ec pairs are being collected since all possibilities
              # are being enumerated, but don't put the last one in since
              # its expr might match a previous expression and it
              # must appear last in the args
              if cond is not None:
                  args.setdefault(expr, []).append(cond)
                  # but since we only store the true conditions we must maintain
                  # the order so that the expression with the most true values
                  # comes first
                  exprinorder.append(expr)
          # convert collected conditions as args of Or
          for k in args:
              args[k] = Or(*args[k])
          # take them in the order obtained
          args = [(e, args[e]) for e in uniq(exprinorder)]
          # add in the last arg
          args.append((expr, True))
          return Piecewise(*args)
  
imports: from sympy.core import S, Function, diff, Tuple, Dummy, Mul
  from sympy.core.basic import Basic, as_Basic
  from sympy.core.numbers import Rational, NumberSymbol, _illegal
  from sympy.core.parameters import global_parameters
  from sympy.core.relational import Lt, Gt, Eq, Ne, Relational, _canonical, _canonical_coeff
  from sympy.core.sorting import ordered
  from sympy.functions.elementary.miscellaneous import Max, Min
  from sympy.logic.boolalg import And, Boolean, distribute_and_over_or, Not, true, false, Or, ITE, simplify_logic, to_cnf, distribute_or_over_and
  from sympy.utilities.iterables import uniq, sift, common_prefix
  from sympy.utilities.misc import filldedent, func_name
  from itertools import product
label_desc: Use image node_id 12 for calling the Piecewise obj's underlying member method code with example usage: obj._handle_irel(x, handler) and returns: Piecewise