docs: def seperate_symbols(func):
      """
      Seperate the symbols in symbolic function func. Return them in alphabetical
      order.
  
      :param func: scipy symbolic function.
      :return: (vars, params), a tuple of all variables and parameters, each 
          sorted in alphabetical order.
      :raises TypeError: only symfit Variable and Parameter are allowed, not sympy
          Symbols.
      """
      params = []
      vars = []
      for symbol in func.free_symbols:
          if not isidentifier(str(symbol)):
              continue  # E.g. Indexed objects might print to A[i, j]
          if isinstance(symbol, Parameter):
              params.append(symbol)
          elif isinstance(symbol, Idx):
              # Idx objects are not seen as parameters or vars.
              pass
          elif isinstance(symbol, (MatrixExpr, Expr)):
              vars.append(symbol)
          else:
              raise TypeError('model contains an unknown symbol type, {}'.format(type(symbol)))
  
      for der in func.atoms(sympy.Derivative):
          # Used by jacobians and hessians, where derivatives are treated as
          # Variables. This way of writing it is purposefully discriminatory
          # against derivatives wrt variables, since such derivatives should be
          # performed explicitly in the case of jacs/hess, and are treated
          # differently in the case of ODEModels.
          if der.expr in vars and all(isinstance(s, Parameter) for s in der.variables):
              vars.append(der)
  
      params.sort(key=lambda symbol: symbol.name)
      vars.sort(key=lambda symbol: symbol.name)
      return vars, params