code: def bottom_up(rv, F, atoms=False, nonbasic=False):
      """Apply ``F`` to all expressions in an expression tree from the
      bottom up. If ``atoms`` is True, apply ``F`` even if there are no args;
      if ``nonbasic`` is True, try to apply ``F`` to non-Basic objects.
      """
      args = getattr(rv, "args", None)
      if args is not None:
          if args:
              args = tuple(
                  [bottom_up(a, F, atoms, nonbasic) for a in args]
              )
              if args != rv.args:
                  rv = rv.func(*args)
              rv = F(rv)
          elif atoms:
              rv = F(rv)
      else:
          if nonbasic:
              try:
                  rv = F(rv)
              except TypeError:
                  pass
  
      return rv
  
file_path: sympy/sympy/core/traversal.py
imports: from .basic import Basic
  from .sorting import ordered
  from .sympify import sympify
  from sympy.utilities.iterables import iterable
label_desc: Use image node_id 5 for calling a global function with example usage: bottom_up(rv, F, atoms, nonbasic) and returns: rv