code: def _substitute(self, var_map, safe=False):
          
          if self in var_map:
              if not safe or (type(var_map[self]) == type(self)):
                  return var_map[self]
          if isinstance(self.__class__, Singleton):
              return self
          new_args = [substitute(arg, var_map) for arg in self.args]
          new_kwargs = {key: substitute(val, var_map)
                        for (key, val) in self.kwargs.items()}
          if safe:
              return self.__class__(*new_args, **new_kwargs)
          else:
              return self.create(*new_args, **new_kwargs)
docs: Implementation of :meth:`substitute`.
  
          For internal use, the `safe` keyword argument allows to perform a
          substitution on the `args` and `kwargs` of the expression only,
          guaranteeing that the type of the expression does not change, at the
          cost of possibly not returning a maximally simplified expression. The
          `safe` keyword is not handled recursively, i.e. any `args`/`kwargs`
          will be fully simplified, possibly changing their types.