class_docstr: Expression representing addition operation for algebraic group.
  
  .. deprecated:: 1.7
  
     Using arguments that aren't subclasses of :class:`~.Expr` in core
     operators (:class:`~.Mul`, :class:`~.Add`, and :class:`~.Pow`) is
     deprecated. See :ref:`non-expr-args-deprecated` for details.
  
  Every argument of ``Add()`` must be ``Expr``. Infix operator ``+``
  on most scalar objects in SymPy calls this class.
  
  Another use of ``Add()`` is to represent the structure of abstract
  addition so that its arguments can be substituted to return different
  class. Refer to examples section for this.
  
  ``Add()`` evaluates the argument unless ``evaluate=False`` is passed.
  The evaluation logic includes:
  
  1. Flattening
      ``Add(x, Add(y, z))`` -> ``Add(x, y, z)``
  
  2. Identity removing
      ``Add(x, 0, y)`` -> ``Add(x, y)``
  
  3. Coefficient collecting by ``.as_coeff_Mul()``
      ``Add(x, 2*x)`` -> ``Mul(3, x)``
  
  4. Term sorting
      ``Add(y, x, 2)`` -> ``Add(2, x, y)``
  
  If no argument is passed, identity element 0 is returned. If single
  element is passed, that element is returned.
  
  Note that ``Add(*args)`` is more efficient than ``sum(args)`` because
  it flattens the arguments. ``sum(a, b, c, ...)`` recursively adds the
  arguments as ``a + (b + (c + ...))``, which has quadratic complexity.
  On the other hand, ``Add(a, b, c, d)`` does not assume nested
  structure, making the complexity linear.
  
  Since addition is group operation, every argument should have the
  same :obj:`sympy.core.kind.Kind()`.
  
  Examples
  ========
  
  >>> from sympy import Add, I
  >>> from sympy.abc import x, y
  >>> Add(x, 1)
  x + 1
  >>> Add(x, x)
  2*x
  >>> 2*x**2 + 3*x + I*y + 2*y + 2*x/5 + 1.0*y + 1
  2*x**2 + 17*x/5 + 3.0*y + I*y + 1
  
  If ``evaluate=False`` is passed, result is not evaluated.
  
  >>> Add(1, 2, evaluate=False)
  1 + 2
  >>> Add(x, x, evaluate=False)
  x + x
  
  ``Add()`` also represents the general structure of addition operation.
  
  >>> from sympy import MatrixSymbol
  >>> A,B = MatrixSymbol('A', 2,2), MatrixSymbol('B', 2,2)
  >>> expr = Add(x,y).subs({x:A, y:B})
  >>> expr
  A + B
  >>> type(expr)
  <class 'sympy.matrices.expressions.matadd.MatAdd'>
  
  Note that the printers do not display in args order.
  
  >>> Add(x, 1)
  x + 1
  >>> Add(x, 1).args
  (1, x)
  
  See Also
  ========
  
  MatAdd
class_docstr_tok: ["Expression","representing","addition","operation","for","algebraic","group",".","..","deprecated",":",":","1.7","Using","arguments","that","are","n't","subclasses","of",":","class",":","`","~.Expr","`","in","core","operators","(",":","class",":","`","~.Mul","`",",",":","class",":","`","~.Add","`",",","and",":","class",":","`","~.Pow","`",")","is","deprecated",".","See",":","ref",":","`","non-expr-args-deprecated","`","for","details",".","Every","argument","of","``","Add","(",")","``","must","be","``","Expr","``",".","Infix","operator","``","+","``","on","most","scalar","objects","in","SymPy","calls","this","class",".","Another","use","of","``","Add","(",")","``","is","to","represent","the","structure","of","abstract","addition","so","that","its","arguments","can","be","substituted","to","return","different","class",".","Refer","to","examples","section","for","this",".","``","Add","(",")","``","evaluates","the","argument","unless","``","evaluate=False","``","is","passed",".","The","evaluation","logic","includes",":","1",".","Flattening","``","Add","(","x",",","Add","(","y",",","z",")",")","``","-",">","``","Add","(","x",",","y",",","z",")","``","2",".","Identity","removing","``","Add","(","x",",","0",",","y",")","``","-",">","``","Add","(","x",",","y",")","``","3",".","Coefficient","collecting","by","``",".as_coeff_Mul","(",")","``","``","Add","(","x",",","2","*","x",")","``","-",">","``","Mul","(","3",",","x",")","``","4",".","Term","sorting","``","Add","(","y",",","x",",","2",")","``","-",">","``","Add","(","2",",","x",",","y",")","``","If","no","argument","is","passed",",","identity","element","0","is","returned",".","If","single","element","is","passed",",","that","element","is","returned",".","Note","that","``","Add","(","*","args",")","``","is","more","efficient","than","``","sum","(","args",")","``","because","it","flattens","the","arguments",".","``","sum","(","a",",","b",",","c",",","...",")","``","recursively","adds","the","arguments","as","``","a","+","(","b","+","(","c","+","...",")",")","``",",","which","has","quadratic","complexity",".","On","the","other","hand",",","``","Add","(","a",",","b",",","c",",","d",")","``","does","not","assume","nested","structure",",","making","the","complexity","linear",".","Since","addition","is","group","operation",",","every","argument","should","have","the","same",":","obj",":","`","sympy.core.kind.Kind","(",")","`",".","Examples","========",">",">",">","from","sympy","import","Add",",","I",">",">",">","from","sympy.abc","import","x",",","y",">",">",">","Add","(","x",",","1",")","x","+","1",">",">",">","Add","(","x",",","x",")","2","*","x",">",">",">","2","*","x","*","*","2","+","3","*","x","+","I","*","y","+","2","*","y","+","2","*","x\/5","+","1.0","*","y","+","1","2","*","x","*","*","2","+","17","*","x\/5","+","3.0","*","y","+","I","*","y","+","1","If","``","evaluate=False","``","is","passed",",","result","is","not","evaluated",".",">",">",">","Add","(","1",",","2",",","evaluate=False",")","1","+","2",">",">",">","Add","(","x",",","x",",","evaluate=False",")","x","+","x","``","Add","(",")","``","also","represents","the","general","structure","of","addition","operation",".",">",">",">","from","sympy","import","MatrixSymbol",">",">",">","A",",","B","=","MatrixSymbol","(","'","A","'",",","2,2",")",",","MatrixSymbol","(","'","B","'",",","2,2",")",">",">",">","expr","=","Add","(","x",",","y",")",".subs","(","{","x",":","A",",","y",":","B","}",")",">",">",">","expr","A","+","B",">",">",">","type","(","expr",")","<","class","'sympy.matrices.expressions.matadd.MatAdd","'",">","Note","that","the","printers","do","not","display","in","args","order",".",">",">",">","Add","(","x",",","1",")","x","+","1",">",">",">","Add","(","x",",","1",")",".args","(","1",",","x",")","See","Also","========","MatAdd"]
docstr: Takes the sequence "seq" of nested Adds and returns a flatten list.
  
  Returns: (commutative_part, noncommutative_part, order_symbols)
  
  Applies associativity, all terms are commutable with respect to
  addition.
  
  NB: the removal of 0 is already handled by AssocOp.__new__
  
  See Also
  ========
  
  sympy.core.mul.Mul.flatten
docstr_tok: ["Takes","the","sequence","``","seq","''","of","nested","Adds","and","returns","a","flatten","list",".","Returns",":","(","commutative_part",",","noncommutative_part",",","order_symbols",")","Applies","associativity",",","all","terms","are","commutable","with","respect","to","addition",".","NB",":","the","removal","of","0","is","already","handled","by","AssocOp.__new__","See","Also","========","sympy.core.mul.Mul.flatten"]
code: def flatten(cls, seq):
      """
      Takes the sequence "seq" of nested Adds and returns a flatten list.
  
      Returns: (commutative_part, noncommutative_part, order_symbols)
  
      Applies associativity, all terms are commutable with respect to
      addition.
  
      NB: the removal of 0 is already handled by AssocOp.__new__
  
      See Also
      ========
  
      sympy.core.mul.Mul.flatten
  
      """
      from sympy.calculus.accumulationbounds import AccumBounds
      from sympy.matrices.expressions import MatrixExpr
      from sympy.tensor.tensor import TensExpr
  
      rv = None
      if len(seq) == 2:
          a, b = seq
          if b.is_Rational:
              a, b = b, a
          if a.is_Rational:
              if b.is_Mul:
                  rv = [a, b], [], None
          if rv:
              if all(s.is_commutative for s in rv[0]):
                  return rv
              return [], rv[0], None
  
      terms = {}  # term -> coeff
      # e.g. x**2 -> 5   for ... + 5*x**2 + ...
  
      coeff = (
          S.Zero
      )  # coefficient (Number or zoo) to always be in slot 0
      # e.g. 3 + ...
      order_factors = []
  
      extra = []
  
      for o in seq:
          # O(x)
          if o.is_Order:
              if o.expr.is_zero:
                  continue
              for o1 in order_factors:
                  if o1.contains(o):
                      o = None
                      break
              if o is None:
                  continue
              order_factors = [o] + [
                  o1 for o1 in order_factors if not o.contains(o1)
              ]
              continue
  
          # 3 or NaN
          elif o.is_Number:
              if (
                  o is S.NaN
                  or coeff is S.ComplexInfinity
                  and o.is_finite is False
              ) and not extra:
                  # we know for sure the result will be nan
                  return [S.NaN], [], None
              if coeff.is_Number or isinstance(coeff, AccumBounds):
                  coeff += o
                  if coeff is S.NaN and not extra:
                      # we know for sure the result will be nan
                      return [S.NaN], [], None
              continue
  
          elif isinstance(o, AccumBounds):
              coeff = o.__add__(coeff)
              continue
  
          elif isinstance(o, MatrixExpr):
              # can't add 0 to Matrix so make sure coeff is not 0
              extra.append(o)
              continue
  
          elif isinstance(o, TensExpr):
              coeff = o.__add__(coeff) if coeff else o
              continue
  
          elif o is S.ComplexInfinity:
              if coeff.is_finite is False and not extra:
                  # we know for sure the result will be nan
                  return [S.NaN], [], None
              coeff = S.ComplexInfinity
              continue
  
          # Add([...])
          elif o.is_Add:
              # NB: here we assume Add is always commutative
              seq.extend(o.args)  # TODO zerocopy?
              continue
  
          # Mul([...])
          elif o.is_Mul:
              c, s = o.as_coeff_Mul()
  
          # check for unevaluated Pow, e.g. 2**3 or 2**(-1/2)
          elif o.is_Pow:
              b, e = o.as_base_exp()
              if b.is_Number and (
                  e.is_Integer or (e.is_Rational and e.is_negative)
              ):
                  seq.append(b**e)
                  continue
              c, s = S.One, o
  
          else:
              # everything else
              c = S.One
              s = o
  
          # now we have:
          # o = c*s, where
          #
          # c is a Number
          # s is an expression with number factor extracted
          # let's collect terms with the same s, so e.g.
          # 2*x**2 + 3*x**2  ->  5*x**2
          if s in terms:
              terms[s] += c
              if terms[s] is S.NaN and not extra:
                  # we know for sure the result will be nan
                  return [S.NaN], [], None
          else:
              terms[s] = c
  
      # now let's construct new args:
      # [2*x**2, x**3, 7*x**4, pi, ...]
      newseq = []
      noncommutative = False
      for s, c in terms.items():
          # 0*s
          if c.is_zero:
              continue
          # 1*s
          elif c is S.One:
              newseq.append(s)
          # c*s
          else:
              if s.is_Mul:
                  # Mul, already keeps its arguments in perfect order.
                  # so we can simply put c in slot0 and go the fast way.
                  cs = s._new_rawargs(*((c,) + s.args))
                  newseq.append(cs)
              elif s.is_Add:
                  # we just re-create the unevaluated Mul
                  newseq.append(Mul(c, s, evaluate=False))
              else:
                  # alternatively we have to call all Mul's machinery (slow)
                  newseq.append(Mul(c, s))
  
          noncommutative = noncommutative or not s.is_commutative
  
      # oo, -oo
      if coeff is S.Infinity:
          newseq = [
              f
              for f in newseq
              if not (f.is_extended_nonnegative or f.is_real)
          ]
  
      elif coeff is S.NegativeInfinity:
          newseq = [
              f
              for f in newseq
              if not (f.is_extended_nonpositive or f.is_real)
          ]
  
      if coeff is S.ComplexInfinity:
          # zoo might be
          #   infinite_real + finite_im
          #   finite_real + infinite_im
          #   infinite_real + infinite_im
          # addition of a finite real or imaginary number won't be able to
          # change the zoo nature; adding an infinite qualtity would result
          # in a NaN condition if it had sign opposite of the infinite
          # portion of zoo, e.g., infinite_real - infinite_real.
          newseq = [
              c
              for c in newseq
              if not (c.is_finite and c.is_extended_real is not None)
          ]
  
      # process O(x)
      if order_factors:
          newseq2 = []
          for t in newseq:
              for o in order_factors:
                  # x + O(x) -> O(x)
                  if o.contains(t):
                      t = None
                      break
              # x + O(x**2) -> x + O(x**2)
              if t is not None:
                  newseq2.append(t)
          newseq = newseq2 + order_factors
          # 1 + O(1) -> O(1)
          for o in order_factors:
              if o.contains(coeff):
                  coeff = S.Zero
                  break
  
      # order args canonically
      _addsort(newseq)
  
      # current code expects coeff to be first
      if coeff is not S.Zero:
          newseq.insert(0, coeff)
  
      if extra:
          newseq += extra
          noncommutative = True
  
      # we are done
      if noncommutative:
          return [], newseq, None
      else:
          return newseq, [], None
  
imports: from typing import Tuple
  from collections import defaultdict
  from functools import reduce
  from operator import attrgetter
  from .basic import _args_sortkey
  from .parameters import global_parameters
  from .logic import _fuzzy_group, fuzzy_or, fuzzy_not
  from .singleton import S
  from .operations import AssocOp, AssocOpDispatcher
  from .cache import cacheit
  from .numbers import equal_valued
  from .intfunc import ilcm, igcd
  from .expr import Expr
  from .kind import UndefinedKind
  from sympy.utilities.iterables import is_sequence, sift
  from .mul import Mul, _keep_coeff, _unevaluated_Mul
  from .numbers import Rational
label_desc: Use image node_id 1 for calling the Add obj's underlying member method code with example usage: obj.flatten(cls, seq) and returns: list,  newseq,  None, newseq,  list,  None, list,  rv,  None, rv, list,  list,  None, list,  list,  None, list,  list,  None, list,  list,  None