
    \h                       S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	J
r
Jr  SSKJrJrJr  SSKJr  SSKJrJr  SS	KJrJrJr  SS
KJrJrJr  SSKJrJrJ r J!r!  S r" " S S\5      r# " S S\#5      r$ " S S\$5      r%\%" 5       r& " S S\$5      r'\'" 5       r( " S S\$5      r)\)" 5       r* " S S\#5      r+ " S S\+5      r, " S S\+5      r- " S S\-5      r. " S S \-5      r/ " S! S"\-5      r0 " S# S$\-5      r1 " S% S&\-5      r2\.\/\0\1\24 V s0 s H  o Rf                  U _M     sn r4S' r5 " S( S)\#5      r6 " S* S+\$5      r7 " S, S-\\$5      r8 " S. S/\85      r9 " S0 S1\85      r: " S2 S3\$5      r; " S4 S5\$5      r< " S6 S7\<5      r= " S8 S9\=5      r> " S: S;\>5      r? " S< S=\>5      r@\" S>5      rA " S? S@\<5      rB " SA SB\B5      rC " SC SD\B5      rD " SE SF\D\C5      rE\=" SG5      rF\=" SH5      rG\?" SISJ5      rH\?" SKSL5      rI\?" SMSN5      rJ\?" SOSP5      rK\@" SQSJ5      rL\@" SRSL5      rM\@" SSSN5      rN\@" STSP5      rO\C" SUSLSVSWSX9rP\C" SYSNSJSZSX9rQ\C" S[SPS\S]SX9rR\C" S^S_S`SaSX9rS\C" SbScS`SdSX9rT\C" SeSfSgShSX9rU\E" SSiSP0\QR                  SjSk9D6rW\E" SSiSc0\RR                  SjSk9D6rX\<" Sl5      rY\B" Sm5      rZ\=" Sn5      r[\D" So5      r\\<" Sp5      r] " Sq Sr\$5      r^\^" Ss5      r_\^" St5      r` " Su Sv\;5      ra " Sw Sx\a5      rb " Sy Sz\$5      rc " S{ S|\$5      rd " S} S~\$5      re " S S\$5      rf " S S\$5      rg\g" S5      rh\g" S5      ri " S S\$5      rj " S S\;5      rk " S S\k5      rl " S S\$5      rm " S S\$\5      rn " S S\$5      ro " S S\$5      rpgs  sn f )a|  
Types used to represent a full function/module as an Abstract Syntax Tree.

Most types are small, and are merely used as tokens in the AST. A tree diagram
has been included below to illustrate the relationships between the AST types.


AST Type Tree
-------------
::

  *Basic*
       |
       |
   CodegenAST
       |
       |--->AssignmentBase
       |             |--->Assignment
       |             |--->AugmentedAssignment
       |                                    |--->AddAugmentedAssignment
       |                                    |--->SubAugmentedAssignment
       |                                    |--->MulAugmentedAssignment
       |                                    |--->DivAugmentedAssignment
       |                                    |--->ModAugmentedAssignment
       |
       |--->CodeBlock
       |
       |
       |--->Token
                |--->Attribute
                |--->For
                |--->String
                |       |--->QuotedString
                |       |--->Comment
                |--->Type
                |       |--->IntBaseType
                |       |              |--->_SizedIntType
                |       |                               |--->SignedIntType
                |       |                               |--->UnsignedIntType
                |       |--->FloatBaseType
                |                        |--->FloatType
                |                        |--->ComplexBaseType
                |                                           |--->ComplexType
                |--->Node
                |       |--->Variable
                |       |           |---> Pointer
                |       |--->FunctionPrototype
                |                            |--->FunctionDefinition
                |--->Element
                |--->Declaration
                |--->While
                |--->Scope
                |--->Stream
                |--->Print
                |--->FunctionCall
                |--->BreakToken
                |--->ContinueToken
                |--->NoneToken
                |--->Return


Predefined types
----------------

A number of ``Type`` instances are provided in the ``sympy.codegen.ast`` module
for convenience. Perhaps the two most common ones for code-generation (of numeric
codes) are ``float32`` and ``float64`` (known as single and double precision respectively).
There are also precision generic versions of Types (for which the codeprinters selects the
underlying data type at time of printing): ``real``, ``integer``, ``complex_``, ``bool_``.

The other ``Type`` instances defined are:

- ``intc``: Integer type used by C's "int".
- ``intp``: Integer type used by C's "unsigned".
- ``int8``, ``int16``, ``int32``, ``int64``: n-bit integers.
- ``uint8``, ``uint16``, ``uint32``, ``uint64``: n-bit unsigned integers.
- ``float80``: known as "extended precision" on modern x86/amd64 hardware.
- ``complex64``: Complex number represented by two ``float32`` numbers
- ``complex128``: Complex number represented by two ``float64`` numbers

Using the nodes
---------------

It is possible to construct simple algorithms using the AST nodes. Let's construct a loop applying
Newton's method::

    >>> from sympy import symbols, cos
    >>> from sympy.codegen.ast import While, Assignment, aug_assign, Print, QuotedString
    >>> t, dx, x = symbols('tol delta val')
    >>> expr = cos(x) - x**3
    >>> whl = While(abs(dx) > t, [
    ...     Assignment(dx, -expr/expr.diff(x)),
    ...     aug_assign(x, '+', dx),
    ...     Print([x])
    ... ])
    >>> from sympy import pycode
    >>> py_str = pycode(whl)
    >>> print(py_str)
    while (abs(delta) > tol):
        delta = (val**3 - math.cos(val))/(-3*val**2 - math.sin(val))
        val += delta
        print(val)
    >>> import math
    >>> tol, val, delta = 1e-5, 0.5, float('inf')
    >>> exec(py_str)
    1.1121416371
    0.909672693737
    0.867263818209
    0.865477135298
    0.865474033111
    >>> print('%3.1g' % (math.cos(val) - val**3))
    -3e-11

If we want to generate Fortran code for the same while loop we simple call ``fcode``::

    >>> from sympy import fcode
    >>> print(fcode(whl, standard=2003, source_format='free'))
    do while (abs(delta) > tol)
       delta = (val**3 - cos(val))/(-3*val**2 - sin(val))
       val = val + delta
       print *, val
    end do

There is a function constructing a loop (or a complete function) like this in
:mod:`sympy.codegen.algorithms`.

    )annotations)Any)defaultdict)GeGtLeLt)SymbolTupleDummy)Basic)ExprAtom)FloatIntegeroo)_sympifysympifySympifyError)iterabletopological_sortnumbered_symbolsfilter_symbolsc                    U  Vs/ s H%  n[        U[        5      (       a  [        U5      OUPM'     n n[        U 6 $ s  snf )z
Create a SymPy Tuple object from an iterable, converting Python strings to
AST strings.

Parameters
==========

args: iterable
    Arguments to :class:`sympy.Tuple`.

Returns
=======

sympy.Tuple
)
isinstancestrStringr   )argsargs     I/var/www/auris/envauris/lib/python3.13/site-packages/sympy/codegen/ast.py	_mk_Tupler!      s?      EIIDS:c3//F3KS8DDI$< Js   ,;c                      \ rS rSrSrSrg)
CodegenAST    N)__name__
__module____qualname____firstlineno__	__slots____static_attributes__r%       r    r#   r#      s    Ir,   r#   c                     ^  \ rS rSr% SrSrS\S'   \r0 rS\S'   / r	S\S	'   S
/r
\S 5       r\S 5       r\S 5       rS rS rS rU 4S jrS rS rSS.S jr\rS rSS jrSrU =r$ )Token   a  Base class for the AST types.

Explanation
===========

Defining fields are set in ``_fields``. Attributes (defined in _fields)
are only allowed to contain instances of Basic (unless atomic, see
``String``). The arguments to ``__new__()`` correspond to the attributes in
the order defined in ``_fields`. The ``defaults`` class attribute is a
dictionary mapping attribute names to their default values.

Subclasses should not need to override the ``__new__()`` method. They may
define a class or static method named ``_construct_<attr>`` for each
attribute to process the value passed to ``__new__()``. Attributes listed
in the class attribute ``not_in_args`` are not passed to :class:`~.Basic`.
r%   tuple[str, ...]r*   dict[str, Any]defaultsz	list[str]not_in_argsbodyc                2    [        U R                  5      S:H  $ Nr   )len_fieldsselfs    r    is_AtomToken.is_Atom   s    4<< A%%r,   c                $    [        U SU-  S 5      $ )z7Get the constructor function for an attribute by name. z_construct_%sc                    U $ Nr%   )xs    r    <lambda>(Token._get_constructor.<locals>.<lambda>   s    ar,   )getattr)clsattrs     r    _get_constructorToken._get_constructor   s     sOd2K@@r,   c                    US:X  a   U R                   R                  U[        5      $ [        U[        5      (       a  U$ U R                  U5      " U5      $ )zDConstruct an attribute value from argument passed to ``__new__()``. N)r2   getnoner   r   rF   )rD   rE   r   s      r    
_constructToken._construct   sJ     $;<<##D$//#u%%
++D1#66r,   c                   [        U5      S:X  a   U(       d  [        US   U 5      (       a  US   $ [        U5      [        U R                  5      :  a,  [        S[        U5      [        U R                  5      4-  5      e/ n[	        U R                  U5       H8  u  pEXB;   a  [        SU-  5      eUR                  U R                  XE5      5        M:     U R                  [        U5      S   Hg  nXB;   a  UR                  U5      nO-X@R                  ;   a  U R                  U   nO[        SU-  5      eUR                  U R                  XE5      5        Mi     U(       a  [        SSR                  U5      -  5      e[	        U R                  U5       VVs/ s H  u  pgX`R                  ;  d  M  UPM     nnn[        R                  " U /UQ76 n	[	        U R                  U5       H  u  pj[        XU
5        M     U	$ s  snnf )N   r   z,Too many arguments (%d), expected at most %dz$Got multiple values for attribute %rz2No value for %r given and attribute has no defaultzUnknown keyword arguments: %s )r7   r   r8   
ValueErrorzip	TypeErrorappendrK   popr2   joinr3   r#   __new__setattr)rD   r   kwargsattrvalsattrnameargvalrE   val
basic_argsobjr   s              r    rV   Token.__new__   s   t9>&ZQ-E-E7Nt9s3;;''KsSWyZ]^a^i^iZjNkkll !$CKK 6H! F QRROOCNN8<=	 !7 CIJ/H!H-\\)h/   TW_ _``OOCNN8<= 0 <sxx?OOPP "%S[[(!;
!;ID??* !; 	 
   2z2 S[[(3IDCs# 4 

s   G8+G8c                    [        XR                  5      (       d  gU R                   H  n[        X5      [        X5      :w  d  M    g   g)NFT)r   	__class__r8   rC   )r:   otherrE   s      r    __eq__Token.__eq__  s<    %00LLDt"ge&:: ! r,   c           	     j    [        U R                   Vs/ s H  n[        X5      PM     sn5      $ s  snf r?   )tupler8   rC   )r:   rE   s     r    _hashable_contentToken._hashable_content  s(    dllCldgd)lCDDCs   0c                    > [         TU ]  5       $ r?   super__hash__r:   ra   s    r    rl   Token.__hash__      w!!r,   c                4    XR                   ;   a  SSU-  -   $ S$ )N,
rO   , )indented_args)r:   kindent_levels      r    _joinerToken._joiner  s"    -.2D2D-DL((N$Nr,   c                  ^ ^^^^^	 TR                   S   m	UU	UUUU 4S jn[        U[        5      (       a  T R                  TT	5      R	                  UR
                   Vs/ s H
  ov" U5      PM     sn5      nTT R                  ;   a  SST	-  -   U-   S-   ST	S-
  -  -   S-   $ [        UR
                  5      S:X  a  S	R                  U5      $ S
R                  U5      $ U" U5      $ s  snf )Nru   c                   > [        U [        5      (       a(  TR                  " U /TQ7STR                  TT5      0TD6$ TR                  " U /TQ70 TD6$ )Njoiner)r   r.   _printrv   )r   r   ilrt   rX   printerr:   s    r    r{   Token._indented.<locals>._print  sS    #u%%~~cWDWa9LWPVWW~~c;D;F;;r,   z(
rO   rq      )rN   z({0},)z({0}))	_contextr   r   rv   rU   r   rs   r7   format)
r:   r}   rt   vr   rX   r{   r   joinedr|   s
   ``` ``   @r    	_indentedToken._indented  s    n-	< 	< a\\!R(--aff.Mfsvc{f.MNFD&&&s2v~.6b1fEKK$'K1$4II&QQ'II&QQ!9 /Ns   C$rr   )rz   c                  SSK Jn  UR                  SS5      nU R                   Vs/ s H  n[	        X5      PM     nnUR
                  R                  SS5      n	/ n
[        [        U R                  U5      5       H  u  nu  pX;   a  M  XR                  ;   a  XR                  U   :X  a  M2  XR                  ;   a  U	S-   OSnU" XS9   U R                  " XU/UQ70 UD6nS S S 5        U
R                  US:X  a  SOS	R                  UWR                  5       5      5        M     S
R                  U R                  R                  UR!                  U
5      5      $ s  snf ! , (       d  f       N= f)Nr   )printer_contextexcluder%   ru   r   )ru   z{1}z{0}={1}z{}({}))sympy.printing.printerr   rI   r8   rC   r   	enumeraterQ   r2   rs   r   rS   r   lstripra   r&   rU   )r:   r}   rz   r   rX   r   r   rt   valuesru   	arg_reprsirE   valueilvlindenteds                   r    
_sympyreprToken._sympyrepr%  s2   :**Y+,0LL9Lq'$"L9''++NA>	 )#dllF*C DA} }}$--2E)E'+/A/A'A<!#qD <>>'PPP =qAve9DDT8??K\]^ !E t~~66I8NOO% : =<s   E	E
E,	c                    SSK Jn  U" U 5      $ )Nr   )srepr)sympy.printingr   )r:   r   s     r    __repr__Token.__repr__>  s    (T{r,   c                    U R                    Vs0 s H  o3U;  d  M
  U[        X5      _M     nnUb+  UR                  5        VVs0 s H  u  p5X2" U5      _M     snn$ U$ s  snf s  snnf )zGet instance's attributes as dict of keyword arguments.

Parameters
==========

exclude : collection of str
    Collection of keywords to exclude.

apply : callable, optional
    Function to apply to all values.
)r8   rC   items)r:   r   applyrt   rX   r   s         r    rX   Token.kwargsB  sg     04||P|!?O%!WT%%|P,2LLN;NDAAuQxKN;;M	 Q;s   	AAA#r%   N)r&   r'   r(   r)   __doc__r*   __annotations__r8   r2   r3   rs   propertyr;   classmethodrF   rK   rV   rc   rg   rl   rv   r   r   	_sympystrr   rX   r+   __classcell__ra   s   @r    r.   r.      s    " "$I#G!Hn!KHM& & A A 	7 	7,\E"O" 15 P. I r,   r.   c                      \ rS rSrSrSrg)
BreakTokeniT  a  Represents 'break' in C/Python ('exit' in Fortran).

Use the premade instance ``break_`` or instantiate manually.

Examples
========

>>> from sympy import ccode, fcode
>>> from sympy.codegen.ast import break_
>>> ccode(break_)
'break'
>>> fcode(break_, source_format='free')
'exit'
r%   Nr&   r'   r(   r)   r   r+   r%   r,   r    r   r   T      r,   r   c                      \ rS rSrSrSrg)ContinueTokenig  a.  Represents 'continue' in C/Python ('cycle' in Fortran)

Use the premade instance ``continue_`` or instantiate manually.

Examples
========

>>> from sympy import ccode, fcode
>>> from sympy.codegen.ast import continue_
>>> ccode(continue_)
'continue'
>>> fcode(continue_, source_format='free')
'cycle'
r%   Nr   r%   r,   r    r   r   g  r   r,   r   c                  8   ^  \ rS rSrSrS rS rU 4S jrSrU =r	$ )	NoneTokeniy  a  The AST equivalence of Python's NoneType

The corresponding instance of Python's ``None`` is ``none``.

Examples
========

>>> from sympy.codegen.ast import none, Variable
>>> from sympy import pycode
>>> print(pycode(Variable('x').as_Declaration(value=none)))
x = None

c                8    US L =(       d    [        U[        5      $ r?   )r   r   r:   rb   s     r    rc   NoneToken.__eq__  s    }<
5) <<r,   c                    g)Nr%   r%   r9   s    r    rg   NoneToken._hashable_content  s    r,   c                    > [         TU ]  5       $ r?   rj   rm   s    r    rl   NoneToken.__hash__  ro   r,   r%   )
r&   r'   r(   r)   r   rc   rg   rl   r+   r   r   s   @r    r   r   y  s    =" "r,   r   c                  \   ^  \ rS rSrSrU 4S jr\S 5       r\S 5       r\	S 5       r
SrU =r$ )AssignmentBasei  zAbstract base class for Assignment and AugmentedAssignment.

Attributes:
===========

op : str
    Symbol for assignment operator, e.g. "=", "+=", etc.
c                r   > [        U5      n[        U5      nU R                  X5        [        TU ]  XU5      $ r?   )r   _check_argsrk   rV   )rD   lhsrhsra   s      r    rV   AssignmentBase.__new__  s2    smsm!ws--r,   c                     U R                   S   $ r6   r   r9   s    r    r   AssignmentBase.lhs      yy|r,   c                     U R                   S   $ )NrN   r   r9   s    r    r   AssignmentBase.rhs  r   r,   c                   SSK JnJn  SSKJn  SSKJn  [        XCU[        [        U4n[        X5      (       d  [        S[        U5      -  5      e[        US5      =(       a    [        X5      (       + n[        US5      =(       a    [        X%5      (       + n	U(       a8  U	(       d  [        S5      eUR                  UR                  :w  a  [        S5      eg
U	(       a  U(       d  [        S	5      eg
g
)zrCheck arguments to __new__ and raise exception if any problems found.

Derived classes may wish to override this.
r   )MatrixElementMatrixSymbol)Indexed)ArrayElementz Cannot assign to lhs of type %s.shapez#Cannot assign a scalar to a matrix.z'Dimensions of lhs and rhs do not align.z#Cannot assign a matrix to a scalar.N)"sympy.matrices.expressions.matexprr   r   sympy.tensor.indexedr   sympy.tensor.array.expressionsr   r
   ElementVariabler   rR   typehasattrrP   r   )
rD   r   r   r   r   r   r   
assignable
lhs_is_mat
rhs_is_mats
             r    r   AssignmentBase._check_args  s    	)0? l7GX
#**>cJKK
 S'*K:c3K/K
S'*K:c3K/K
  !FGGcii' !JKK (
BCC !+Zr,   r%   )r&   r'   r(   r)   r   rV   r   r   r   r   r   r+   r   r   s   @r    r   r     sK    .     D Dr,   r   c                      \ rS rSrSrSrSrg)
Assignmenti  a  
Represents variable assignment for code generation.

Parameters
==========

lhs : Expr
    SymPy object representing the lhs of the expression. These should be
    singular objects, such as one would use in writing code. Notable types
    include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that
    subclass these types are also supported.

rhs : Expr
    SymPy object representing the rhs of the expression. This can be any
    type, provided its shape corresponds to that of the lhs. For example,
    a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as
    the dimensions will not align.

Examples
========

>>> from sympy import symbols, MatrixSymbol, Matrix
>>> from sympy.codegen.ast import Assignment
>>> x, y, z = symbols('x, y, z')
>>> Assignment(x, y)
Assignment(x, y)
>>> Assignment(x, 0)
Assignment(x, 0)
>>> A = MatrixSymbol('A', 1, 3)
>>> mat = Matrix([x, y, z]).T
>>> Assignment(A, mat)
Assignment(A, Matrix([[x, y, z]]))
>>> Assignment(A[0, 1], x)
Assignment(A[0, 1], x)
z:=r%   N)r&   r'   r(   r)   r   opr+   r%   r,   r    r   r     s    "H 
Br,   r   c                  4    \ rS rSr% SrS\S'   \S 5       rSrg)AugmentedAssignmenti  z
Base class for augmented assignments.

Attributes:
===========

binop : str
   Symbol for binary operation being applied in the assignment, such as "+",
   "*", etc.
z
str | Nonebinopc                     U R                   S-   $ )N=)r   r9   s    r    r   AugmentedAssignment.op  s    zzCr,   r%   N)	r&   r'   r(   r)   r   r   r   r   r+   r%   r,   r    r   r     s!    	    r,   r   c                      \ rS rSrSrSrg)AddAugmentedAssignmenti	  +r%   Nr&   r'   r(   r)   r   r+   r%   r,   r    r   r   	      Er,   r   c                      \ rS rSrSrSrg)SubAugmentedAssignmenti  -r%   Nr   r%   r,   r    r   r     r   r,   r   c                      \ rS rSrSrSrg)MulAugmentedAssignmenti  *r%   Nr   r%   r,   r    r   r     r   r,   r   c                      \ rS rSrSrSrg)DivAugmentedAssignmenti  /r%   Nr   r%   r,   r    r   r     r   r,   r   c                      \ rS rSrSrSrg)ModAugmentedAssignmenti  %r%   Nr   r%   r,   r    r   r     r   r,   r   c                P    U[         ;  a  [        SU-  5      e[         U   " X5      $ )a  
Create 'lhs op= rhs'.

Explanation
===========

Represents augmented variable assignment for code generation. This is a
convenience function. You can also use the AugmentedAssignment classes
directly, like AddAugmentedAssignment(x, y).

Parameters
==========

lhs : Expr
    SymPy object representing the lhs of the expression. These should be
    singular objects, such as one would use in writing code. Notable types
    include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that
    subclass these types are also supported.

op : str
    Operator (+, -, /, \*, %).

rhs : Expr
    SymPy object representing the rhs of the expression. This can be any
    type, provided its shape corresponds to that of the lhs. For example,
    a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as
    the dimensions will not align.

Examples
========

>>> from sympy import symbols
>>> from sympy.codegen.ast import aug_assign
>>> x, y = symbols('x, y')
>>> aug_assign(x, '+', y)
AddAugmentedAssignment(x, y)
zUnrecognized operator %s)augassign_classesrP   )r   r   r   s      r    
aug_assignr   &  s/    L 
""3b899R **r,   c                  j   ^  \ rS rSrSrS rS rS r\r\	U 4S j5       r
\S 5       r  S
S jrS	rU =r$ )	CodeBlockiQ  a  
Represents a block of code.

Explanation
===========

For now only assignments are supported. This restriction will be lifted in
the future.

Useful attributes on this object are:

``left_hand_sides``:
    Tuple of left-hand sides of assignments, in order.
``left_hand_sides``:
    Tuple of right-hand sides of assignments, in order.
``free_symbols``: Free symbols of the expressions in the right-hand sides
    which do not appear in the left-hand side of an assignment.

Useful methods on this object are:

``topological_sort``:
    Class method. Return a CodeBlock with assignments
    sorted so that variables are assigned before they
    are used.
``cse``:
    Return a new CodeBlock with common subexpressions eliminated and
    pulled out as assignments.

Examples
========

>>> from sympy import symbols, ccode
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y = symbols('x y')
>>> c = CodeBlock(Assignment(x, 1), Assignment(y, x + 1))
>>> print(ccode(c))
x = 1;
y = x + 1;

c                   / n/ nU HJ  n[        U[        5      (       d  M  UR                  u  pVUR                  U5        UR                  U5        ML     [        R
                  " U /UQ76 n[        U6 Ul        [        U6 Ul        U$ r?   )	r   r   r   rS   r#   rV   r   left_hand_sidesright_hand_sides)rD   r   r   r   r   r   r   r^   s           r    rV   CodeBlock.__new__z  s    A!Z((66&&s+ '',	    ,t,#_5$&67
r,   c                ,    [        U R                  5      $ r?   )iterr   r9   s    r    __iter__CodeBlock.__iter__  s    DIIr,   c                4   UR                   R                  SS5      nSSU-  -   nUR                  [        UR                  U R
                  5      5      nSR                  SUS-
  -  U R                  R                  -   5      SU-  -   U-   S-   SUS-
  -  -   S-   $ )	Nru   r   rq   rO   z{}(
r   
r   )	r   rI   rU   mapr{   r   r   ra   r&   )r:   r}   r   rX   r|   rz   r   s          r    r   CodeBlock._sympyrepr  s    !!.!4RS;<sBqDzDNN,C,CCEB "&'),b1f68;< 	=r,   c                D   > [         TU ]  [        U R                  5      -
  $ r?   )rk   free_symbolssetr   rm   s    r    r   CodeBlock.free_symbols  s    w#c$*>*>&???r,   c                   [        S U 5       5      (       d  [        S5      e[        S U 5       5      (       a  [        S5      e[        [	        U5      5      n[        [        5      nU H$  nUu  pVX6R                     R                  U5        M&     / nU HA  nUu  pVUR                  R                   H   n	X9    H  n
UR                  X45        M     M"     MC     [        X'/5      nU " U VVs/ s H  u  pVUPM	     snn6 $ s  snnf )a  
Return a CodeBlock with topologically sorted assignments so that
variables are assigned before they are used.

Examples
========

The existing order of assignments is preserved as much as possible.

This function assumes that variables are assigned to only once.

This is a class constructor so that the default constructor for
CodeBlock can error when variables are used before they are assigned.

>>> from sympy import symbols
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y, z = symbols('x y z')

>>> assignments = [
...     Assignment(x, y + z),
...     Assignment(y, z + 1),
...     Assignment(z, 2),
... ]
>>> CodeBlock.topological_sort(assignments)
CodeBlock(
    Assignment(z, 2),
    Assignment(y, z + 1),
    Assignment(x, y + z)
)

c              3  B   #    U  H  n[        U[        5      v   M     g 7fr?   r   r   .0r   s     r    	<genexpr>-CodeBlock.topological_sort.<locals>.<genexpr>  s     Bk:a,,k   z4CodeBlock.topological_sort only supports Assignmentsc              3  B   #    U  H  n[        U[        5      v   M     g 7fr?   r   r   r  s     r    r  r    s     G;az!011;r	  zFCodeBlock.topological_sort does not yet work with AugmentedAssignments)allNotImplementedErroranylistr   r   r   rS   r   r   r   )rD   assignmentsAvar_mapnoder   aEdst_nodessrc_nodeordered_assignmentss               r    r   CodeBlock.topological_sort  s    D BkBBB%&\]]G;GGG%&noo( ;'( d#DDAEEN!!$' 
 HDAUU'' '
HHHh12 !+ (  /v6 #67#641Q#67887s   .D
c                   SSK Jn  [        S U R                   5       5      (       d  [	        S5      e[        S U R                   5       5      (       a  [	        S5      e[        U R                  5       H%  u  pgXpR                  SU ;   d  M  [	        SU-  5      e   U R                  [        5      nUc
  [        5       n[        X5      nU" [        U R                  5      XUUS	9u  p[        U R                  U
5       VVs/ s H  u  p[        X5      PM     nnnU	 VVs/ s H  u  p[        X5      PM     nnnU R!                  X-   5      $ s  snnf s  snnf )
a6  
Return a new code block with common subexpressions eliminated.

Explanation
===========

See the docstring of :func:`sympy.simplify.cse_main.cse` for more
information.

Examples
========

>>> from sympy import symbols, sin
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y, z = symbols('x y z')

>>> c = CodeBlock(
...     Assignment(x, 1),
...     Assignment(y, sin(x) + 1),
...     Assignment(z, sin(x) - 1),
... )
...
>>> c.cse()
CodeBlock(
    Assignment(x, 1),
    Assignment(x0, sin(x)),
    Assignment(y, x0 + 1),
    Assignment(z, x0 - 1)
)

r   )csec              3  B   #    U  H  n[        U[        5      v   M     g 7fr?   r  r  s     r    r   CodeBlock.cse.<locals>.<genexpr>  s     @i:a,,ir	  z'CodeBlock.cse only supports Assignmentsc              3  B   #    U  H  n[        U[        5      v   M     g 7fr?   r  r  s     r    r  r    s     E9az!0119r	  z9CodeBlock.cse does not yet work with AugmentedAssignmentsNzEDuplicate assignments to the same variable are not yet supported (%s))symbolsoptimizationspostprocessorder)sympy.simplify.cse_mainr  r  r   r  r  r   r   atomsr
   r   r   r  r   rQ   r   r   )r:   r   r!  r"  r#  r  r   r   existing_symbolsreplacementsreduced_exprsvarexpr	new_blocknew_assignmentss                  r    r  CodeBlock.cse  sJ   B 	0 @dii@@@%&OPPE499EEE%&abb 4 45FA**2A..) +:<?+@ A A 6  ::f-?&(G ;&)$t/D/D*Ek'#
 $$m464 09sZ*4 	 6BNO,YS:c0,O$$_%@AA6Os   E Er%   )NNN	canonical)r&   r'   r(   r)   r   rV   r   r   r   r   r   r   r   r  r+   r   r   s   @r    r   r   Q  s`    'P= I@ @ N9 N9` AE=B =Br,   r   c                  P    \ rS rSrSrS=rr\" \5      r	\
S 5       r\
S 5       rSrg)Fori*  a  Represents a 'for-loop' in the code.

    Expressions are of the form:
        "for target in iter:
            body..."

    Parameters
    ==========

    target : symbol
    iter : iterable
    body : CodeBlock or iterable
!        When passed an iterable it is used to instantiate a CodeBlock.

    Examples
    ========

    >>> from sympy import symbols, Range
    >>> from sympy.codegen.ast import aug_assign, For
    >>> x, i, j, k = symbols('x i j k')
    >>> for_i = For(i, Range(10), [aug_assign(x, '+', i*j*k)])
    >>> for_i  # doctest: -NORMALIZE_WHITESPACE
    For(i, iterable=Range(0, 10, 1), body=CodeBlock(
        AddAugmentedAssignment(x, i*j*k)
    ))
    >>> for_ji = For(j, Range(7), [for_i])
    >>> for_ji  # doctest: -NORMALIZE_WHITESPACE
    For(j, iterable=Range(0, 7, 1), body=CodeBlock(
        For(i, iterable=Range(0, 10, 1), body=CodeBlock(
            AddAugmentedAssignment(x, i*j*k)
        ))
    ))
    >>> for_kji =For(k, Range(5), [for_ji])
    >>> for_kji  # doctest: -NORMALIZE_WHITESPACE
    For(k, iterable=Range(0, 5, 1), body=CodeBlock(
        For(j, iterable=Range(0, 7, 1), body=CodeBlock(
            For(i, iterable=Range(0, 10, 1), body=CodeBlock(
                AddAugmentedAssignment(x, i*j*k)
            ))
        ))
    ))
    )targetr   r4   c                @    [        U[        5      (       a  U$ [        U6 $ r?   r   r   rD   itrs     r    _construct_bodyFor._construct_bodyX      c9%%Jc?"r,   c                    [        U5      (       d  [        S5      e[        U[        5      (       a  [	        U5      n[        U5      $ )Nziterable must be an iterable)r   rR   r   r  rf   r   r4  s     r    _construct_iterableFor._construct_iterable_  s7    }}:;;c4  *C}r,   r%   N)r&   r'   r(   r)   r   r*   r8   staticmethodr   _construct_targetr   r6  r:  r+   r%   r,   r    r0  r0  *  sE    )T 98I$X.# #  r,   r0  c                  `    \ rS rSrSrS=rrS/rSr\	S 5       r
S rSS
 jr\S 5       rS rSrg	)r   ih  a*  SymPy object representing a string.

Atomic object which is not an expression (as opposed to Symbol).

Parameters
==========

text : str

Examples
========

>>> from sympy.codegen.ast import String
>>> f = String('foo')
>>> f
foo
>>> str(f)
'foo'
>>> f.text
'foo'
>>> print(repr(f))
String('foo')

textr@  Tc                F    [        U[        5      (       d  [        S5      eU$ )Nz#Argument text is not a string type.)r   r   rR   )rD   r@  s     r    _construct_textString._construct_text  s     $$$ABBr,   c                    U R                   $ r?   r?  r:   r}   r   rX   s       r    r   String._sympystr  s    yyr,   r%   Nc                    0 $ r?   r%   )r:   r   r   s      r    rX   String.kwargs  s    	r,   c                   ^  U 4S j$ )Nc                    > T $ r?   r%   r9   s   r    rA   String.func.<locals>.<lambda>  s    tr,   r%   r9   s   `r    funcString.func  s	    r,   c                P    SSK Jn  SR                  U" U R                  5      5      $ )Nr   latex_escapez\texttt{{"{}"}})sympy.printing.latexrP  r   r@  )r:   r}   rP  s      r    _latexString._latex  s    5!((dii)@AAr,   r   )r&   r'   r(   r)   r   r*   r8   r3   r;   r   rB  r   rX   r   rL  rR  r+   r%   r,   r    r   r   h  sU    0 $#I(KG 
  Br,   r   c                      \ rS rSrSrSrg)QuotedStringi  z9Represents a string which should be printed with quotes. r%   Nr   r%   r,   r    rU  rU    s    Dr,   rU  c                      \ rS rSrSrSrg)Commenti  zRepresents a comment. r%   Nr   r%   r,   r    rW  rW    s    !r,   rW  c                  ^    \ rS rSr% SrSrS\S'   \rS\" 5       0r	S\S'   \
" \5      rS	 rS
rg)Nodei  a?  Subclass of Token, carrying the attribute 'attrs' (Tuple)

Examples
========

>>> from sympy.codegen.ast import Node, value_const, pointer_const
>>> n1 = Node([value_const])
>>> n1.attr_params('value_const')  # get the parameters of attribute (by name)
()
>>> from sympy.codegen.fnodes import dimension
>>> n2 = Node([value_const, dimension(5, 3)])
>>> n2.attr_params(value_const)  # get the parameters of attribute (by Attribute instance)
()
>>> n2.attr_params('dimension')  # get the parameters of attribute (by name)
(5, 3)
>>> n2.attr_params(pointer_const) is None
True

)attrsr0   r*   rZ  r1   r2   c                    U R                    H3  n[        UR                  5      [        U5      :X  d  M'  UR                  s  $    g)zPReturns the parameters of the Attribute with name ``looking_for`` in self.attrs N)rZ  r   name
parameters)r:   looking_forrE   s      r    attr_paramsNode.attr_params  s/    JJD499~[!11& r,   r%   N)r&   r'   r(   r)   r   r*   r   r8   r   r2   r<  r!   _construct_attrsr_  r+   r%   r,   r    rY  rY    s9    ( ",I+G '1Hn1#I.'r,   rY  c                  \    \ rS rSr% SrSrS\S'   \r\r	S r
\S 5       rS rSS
 jrS rSrg	)Typei  aI  Represents a type.

Explanation
===========

The naming is a super-set of NumPy naming. Type has a classmethod
``from_expr`` which offer type deduction. It also has a method
``cast_check`` which casts the argument to its type, possibly raising an
exception if rounding error is not within tolerances, or if the value is not
representable by the underlying data type (e.g. unsigned integers).

Parameters
==========

name : str
    Name of the type, e.g. ``object``, ``int16``, ``float16`` (where the latter two
    would use the ``Type`` sub-classes ``IntType`` and ``FloatType`` respectively).
    If a ``Type`` instance is given, the said instance is returned.

Examples
========

>>> from sympy.codegen.ast import Type
>>> t = Type.from_expr(42)
>>> t
integer
>>> print(repr(t))
IntBaseType(String('integer'))
>>> from sympy.codegen.ast import uint8
>>> uint8.cast_check(-1)   # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Minimum value for data type bigger than new value.
>>> from sympy.codegen.ast import float32
>>> v6 = 0.123456
>>> float32.cast_check(v6)
0.123456
>>> v10 = 12345.67894
>>> float32.cast_check(v10)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> boost_mp50 = Type('boost::multiprecision::cpp_dec_float_50')
>>> from sympy import cxxcode
>>> from sympy.codegen.ast import Declaration, Variable
>>> cxxcode(Declaration(Variable('x', type=boost_mp50)))
'boost::multiprecision::cpp_dec_float_50 x'

References
==========

.. [1] https://numpy.org/doc/stable/user/basics.types.html

r\  r0   r*   c                ,    [        U R                  5      $ r?   )r   r\  rE  s       r    r   Type._sympystr  s    499~r,   c                   [        U[        [        45      (       a  [        $ [        U[        [
        45      (       d  [        USS5      (       a  [        $ [        USS5      (       a  [        $ [        U[        5      (       d  [        USS5      (       a  [        $ [        U[        5      (       d  [        USS5      (       a  [        $ [        S5      e)a(  Deduces type from an expression or a ``Symbol``.

Parameters
==========

expr : number or SymPy object
    The type will be deduced from type or properties.

Examples
========

>>> from sympy.codegen.ast import Type, integer, complex_
>>> Type.from_expr(2) == integer
True
>>> from sympy import Symbol
>>> Type.from_expr(Symbol('z', complex=True)) == complex_
True
>>> Type.from_expr(sum)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Could not deduce type from expr.

Raises
======

ValueError when type deduction fails.


is_integerFis_real
is_complexis_Relationalz Could not deduce type from expr.)r   floatr   realintr   rC   integercomplexcomplex_boolbool_rP   )rD   r*  s     r    	from_exprType.from_expr  s    < dUEN++KdS'N++wt\5/Q/QN4E**KdG$$lE(J(JOdD!!WT?E%J%JL?@@r,   c                    g r?   r%   r:   r   s     r    _checkType._check-  s    r,   Nc                
  ^^ [        U5      n[        S5      n[        U SS5      nTc  Uc  SOSXg* -  -  mUU4S jnU R                  U5      n	U R	                  U	5        X-
  n
[        U
5      U" U5      :  a  [        S5      eU	$ )a  Casts a value to the data type of the instance.

Parameters
==========

value : number
rtol : floating point number
    Relative tolerance. (will be deduced if not given).
atol : floating point number
    Absolute tolerance (in addition to ``rtol``).
type_aliases : dict
    Maps substitutions for Type, e.g. {integer: int64, real: float32}

Examples
========

>>> from sympy.codegen.ast import integer, float32, int8
>>> integer.cast_check(3.0) == 3
True
>>> float32.cast_check(1e-40)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Minimum value for data type bigger than new value.
>>> int8.cast_check(256)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Maximum value for data type smaller than new value.
>>> v10 = 12345.67894
>>> float32.cast_check(v10)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> from sympy.codegen.ast import float64
>>> float64.cast_check(v10)
12345.67894
>>> from sympy import Float
>>> v18 = Float('0.123456789012345646')
>>> float64.cast_check(v18)
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> from sympy.codegen.ast import float80
>>> float80.cast_check(v18)
0.123456789012345649


   decimal_digNgV瞯<g       @c                &   > TT[        U 5      -  -   $ r?   )abs)numatolrtols    r    tolType.cast_check.<locals>.tolg  s    $s3x-''r,   z.Casting gives a significantly different value.)r   r   rC   cast_nocheckrx  r~  rP   )r:   r   r  r  precision_targetsr\   tenexp10r  new_valdeltas     ``       r    
cast_checkType.cast_check0  s    ^ enbkmT2<!M5s3=/@D	( ##E*Gu:C MNNr,   c                    SSK Jn  U" U R                  R                  5      nU" U R                  R
                  5      nSR                  X45      $ )Nr   rO  z%\text{{{}}}\left(\texttt{{{}}}\right))rQ  rP  ra   r&   r\  r@  r   )r:   r}   rP  	type_namer\  s        r    rR  Type._latexs  s<    5 !8!89	DIINN+7>>yOOr,   r%   )Nr   N)r&   r'   r(   r)   r   r*   r   r8   r   _construct_namer   r   rt  rx  r  rR  r+   r%   r,   r    rc  rc    sL    5l "+I*GO (A (ATAFPr,   rc  c                  "    \ rS rSrSrSrS rSrg)IntBaseTypeiz  z1Integer base type, contains no size information. r%   c                *    [        [        U5      5      $ r?   )r   rn  )r:   r   s     r    rA   IntBaseType.<lambda>}  s    73q6?r,   N)r&   r'   r(   r)   r   r*   r  r+   r%   r,   r    r  r  z  s    <I2Lr,   r  c                  @    \ rS rSrSr\R                  \-   r\rS r	Sr
g)_SizedIntTypei  nbitsc                    XR                   :  a  [        SXR                   4-  5      eXR                  :  a  [        SXR                  4-  5      eg )NValue is too small: %d < %dValue is too big: %d > %d)minrP   maxrw  s     r    rx  _SizedIntType._check  sK    88:eXX=NNOO888E88;LLMM r,   r%   N)r&   r'   r(   r)   r*   rc  r8   r   _construct_nbitsrx  r+   r%   r,   r    r  r    s!    IllY&GNr,   r  c                  <    \ rS rSrSrSr\S 5       r\S 5       rSr	g)SignedIntTypei  z"Represents a signed integer type. r%   c                (    SU R                   S-
  -  * $ N   rN   r  r9   s    r    r  SignedIntType.min  s    DJJqL!!!r,   c                ,    SU R                   S-
  -  S-
  $ r  r  r9   s    r    r  SignedIntType.max  s    4::a< 1$$r,   N
r&   r'   r(   r)   r   r*   r   r  r  r+   r%   r,   r    r  r    s0    -I" " % %r,   r  c                  <    \ rS rSrSrSr\S 5       r\S 5       rSr	g)UnsignedIntTypei  z%Represents an unsigned integer type. r%   c                    gr6   r%   r9   s    r    r  UnsignedIntType.min  s    r,   c                &    SU R                   -  S-
  $ r  r  r9   s    r    r  UnsignedIntType.max  s    $**}q  r,   Nr  r%   r,   r    r  r    s0    0I  ! !r,   r  r  c                       \ rS rSrSrSr\rSrg)FloatBaseTypei  z)Represents a floating point number type. r%   N)	r&   r'   r(   r)   r   r*   r   r  r+   r%   r,   r    r  r    s    4ILr,   r  c                      \ rS rSrSrSr\R                  \-   r\=r	=r
r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S	 5       r\S
 5       rS rS rSrg)	FloatTypei  ah  Represents a floating point type with fixed bit width.

Base 2 & one sign bit is assumed.

Parameters
==========

name : str
    Name of the type.
nbits : integer
    Number of bits used (storage).
nmant : integer
    Number of bits used to represent the mantissa.
nexp : integer
    Number of bits used to represent the mantissa.

Examples
========

>>> from sympy import S
>>> from sympy.codegen.ast import FloatType
>>> half_precision = FloatType('f16', nbits=16, nmant=10, nexp=5)
>>> half_precision.max
65504
>>> half_precision.tiny == S(2)**-14
True
>>> half_precision.eps == S(2)**-10
True
>>> half_precision.dig == 3
True
>>> half_precision.decimal_dig == 5
True
>>> half_precision.cast_check(1.0)
1.0
>>> half_precision.cast_check(1e5)  # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
ValueError: Maximum value for data type smaller than new value.
)r  nmantnexpc                .    [         U R                  S-
  -  $ )zUThe largest positive number n, such that 2**(n - 1) is a representable finite value. rN   )twor  r9   s    r    max_exponentFloatType.max_exponent  s     TYY]##r,   c                     SU R                   -
  $ )zQThe lowest negative number n, such that 2**(n - 1) is a valid normalized number.    )r  r9   s    r    min_exponentFloatType.min_exponent  s     4$$$$r,   c                ^    S[         U R                  S-   * -  -
  [         U R                  -  -  $ )zMaximum value representable. rN   )r  r  r  r9   s    r    r  FloatType.max  s.     C4::a<((#t/@/@*@@@r,   c                .    [         U R                  S-
  -  $ )z'The minimum positive normalized value. rN   )r  r  r9   s    r    tinyFloatType.tiny  s     T&&*++r,   c                *    [         U R                  * -  $ )z9Difference between 1.0 and the next representable value. )r  r  r9   s    r    epsFloatType.eps  s     djj[!!r,   c                Z    SSK JnJn  U" U R                  U" S5      -  U" S5      -  5      $ )zNumber of decimal digits that are guaranteed to be preserved in text.

When converting text -> float -> text, you are guaranteed that at least ``dig``
number of digits are preserved with respect to rounding or overflow.
r   )floorlogr  r{  )sympy.functionsr  r  r  )r:   r  r  s      r    digFloatType.dig  s(     	/TZZ#a&(R011r,   c                f    SSK JnJn  U" U R                  S-   U" S5      -  U" S5      -  S-   5      $ )aD  Number of digits needed to store & load without loss.

Explanation
===========

Number of decimal digits needed to guarantee that two consecutive conversions
(float -> text -> float) to be idempotent. This is useful when one do not want
to loose precision due to rounding errors when storing a floating point value
as text.
r   )ceilingr  rN   r  r{  )r  r  r  r  )r:   r  r  s      r    r|  FloatType.decimal_dig  s1     	1

Q#a&0R81<==r,   c                    U[         :X  a  [        [         5      $ U[         * :X  a  [        [         * 5      $ [        [        [	        U5      R                  U R                  5      5      U R                  5      $ )6Casts without checking if out of bounds or subnormal. )r   rl  r   r   r   evalfr|  rw  s     r    r  FloatType.cast_nocheck  sU    B;9rc\":S--d.>.>?@$BRBRSSr,   c                    XR                   * :  a  [        SXR                   * 4-  5      eXR                   :  a  [        SXR                   4-  5      e[        U5      U R                  :  a  [        S5      eg )Nr  r  z>Smallest (absolute) value for data type bigger than new value.)r  rP   r~  r  rw  s     r    rx  FloatType._check  sk    HH9:ehhY=OOPP888E88;LLMMu:		!]^^ "r,   r%   N)r&   r'   r(   r)   r   r*   rc  r8   r   r  _construct_nmant_construct_nexpr   r  r  r  r  r  r  r|  r  rx  r+   r%   r,   r    r  r    s    &P ,IllY&G<CCC'/ $ $
 % %
 A A , , " " 2 2 > >T_r,   r  c                  8   ^  \ rS rSrSrU 4S jrU 4S jrSrU =r$ )ComplexBaseTypei"  r%   c                p   > SSK JnJn  [        TU ]  U" U5      5      [        TU ]  U" U5      5      S-  -   $ )r  r   reimy              ?)r  r  r  rk   r  r:   r   r  r  ra   s       r    r  ComplexBaseType.cast_nocheck&  s7    *G E+G E+B./	
r,   c                j   > SSK JnJn  [        TU ]  U" U5      5        [        TU ]  U" U5      5        g )Nr   r  )r  r  r  rk   rx  r  s       r    rx  ComplexBaseType._check.  s&    *r%y!r%y!r,   )	r&   r'   r(   r)   r*   r  rx  r+   r   r   s   @r    r  r  "  s    I
" "r,   r  c                      \ rS rSrSrSrSrg)ComplexTypei4  z,Represents a complex floating point number. r%   N)r&   r'   r(   r)   r   r*   r+   r%   r,   r    r  r  4  s
    7Ir,   r  intcintpint8   int16   int32    int64@   uint8uint16uint32uint64float16   r{  )r  r  float32   float64   4   float80P      ?   float128   p   float256         r  )r\  r  r   untypedrm  ro  rp  rr  c                  L    \ rS rSrSrS=rrS\" 5       0r\	r
\" \5      rS rSrg)	AttributeiV  a  Attribute (possibly parametrized)

For use with :class:`sympy.codegen.ast.Node` (which takes instances of
``Attribute`` as ``attrs``).

Parameters
==========

name : str
parameters : Tuple

Examples
========

>>> from sympy.codegen.ast import Attribute
>>> volatile = Attribute('volatile')
>>> volatile
volatile
>>> print(repr(volatile))
Attribute(String('volatile'))
>>> a = Attribute('foo', [1, 2, 3])
>>> a
foo(1, 2, 3)
>>> a.parameters == (1, 2, 3)
True
)r\  r]  r]  c                   ^^^ [        U R                  5      nU R                  (       a-  USSR                  UUU4S jU R                   5       5      -  -  nU$ )Nz(%s)rr   c              3  P   >#    U  H  nTR                   " U/TQ70 TD6v   M     g 7fr?   )r{   )r  r   r   rX   r}   s     r    r  &Attribute._sympystr.<locals>.<genexpr>z  s5      *B1@# +2..+&+&$+&1@s   #&)r   r\  r]  rU   )r:   r}   r   rX   results    ``` r    r   Attribute._sympystrw  sN    TYY??ftyy *B15*B  C C CFr,   r%   N)r&   r'   r(   r)   r   r*   r8   r   r2   r   r  r<  r!   _construct_parametersr   r+   r%   r,   r    r  r  V  s4    4 10Ieg&HO(3r,   r  value_constpointer_constc                      \ rS rSrSrSr\\R                  -   r\R                  R                  5       r\R                  \\S.5        \" \5      r\" \5      r\S\" 5       S4S j5       rS rS	 rS
 rS rS rS rSrg)r   i  a  Represents a variable.

Parameters
==========

symbol : Symbol
type : Type (optional)
    Type of the variable.
attrs : iterable of Attribute instances
    Will be stored as a Tuple.

Examples
========

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Variable, float32, integer
>>> x = Symbol('x')
>>> v = Variable(x, type=float32)
>>> v.attrs
()
>>> v == Variable('x')
False
>>> v == Variable('x', type=float32)
True
>>> v
Variable(x, type=float32)

One may also construct a ``Variable`` instance with the type deduced from
assumptions about the symbol using the ``deduced`` classmethod:

>>> i = Symbol('i', integer=True)
>>> v = Variable.deduced(i)
>>> v.type == integer
True
>>> v == Variable('i')
False
>>> from sympy.codegen.ast import value_const
>>> value_const in v.attrs
False
>>> w = Variable('w', attrs=[value_const])
>>> w
Variable(w, attrs=(value_const,))
>>> value_const in w.attrs
True
>>> w.as_Declaration(value=42)
Declaration(Variable(w, value=42, attrs=(value_const,)))

)symbolr   r   )r   r   NTc                    [        U[        5      (       a  U$  [        R                  U5      nUb  U(       a  UR                  U5      nU " XX#S9$ ! [         a    [        R                  U5      n NCf = f)a  Alt. constructor with type deduction from ``Type.from_expr``.

Deduces type primarily from ``symbol``, secondarily from ``value``.

Parameters
==========

symbol : Symbol
value : expr
    (optional) value of the variable.
attrs : iterable of Attribute instances
cast_check : bool
    Whether to apply ``Type.cast_check`` on ``value``.

Examples
========

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Variable, complex_
>>> n = Symbol('n', integer=True)
>>> str(Variable.deduced(n).type)
'integer'
>>> x = Symbol('x', real=True)
>>> v = Variable.deduced(x)
>>> v.type
real
>>> z = Symbol('z', complex=True)
>>> Variable.deduced(z).type == complex_
True

)r   r   rZ  )r   r   rc  rt  rP   r  )rD   r  r   rZ  r  type_s         r    deducedVariable.deduced  sp    B fh''M	*NN6*E $$U+E6U@@  	*NN5)E	*s   A A21A2c                z    U R                  5       nUR                  U5        [        U R                  " S0 UD65      $ )a  Convenience method for creating a Declaration instance.

Explanation
===========

If the variable of the Declaration need to wrap a modified
variable keyword arguments may be passed (overriding e.g.
the ``value`` of the Variable instance).

Examples
========

>>> from sympy.codegen.ast import Variable, NoneToken
>>> x = Variable('x')
>>> decl1 = x.as_Declaration()
>>> # value is special NoneToken() which must be tested with == operator
>>> decl1.variable.value is None  # won't work
False
>>> decl1.variable.value == None  # not PEP-8 compliant
True
>>> decl1.variable.value == NoneToken()  # OK
True
>>> decl2 = x.as_Declaration(value=42.0)
>>> decl2.variable.value == 42.0
True

r%   )rX   updateDeclarationrL  )r:   rX   kws      r    as_DeclarationVariable.as_Declaration  s0    8 [[]
		&499?r?++r,   c                j     [        U5      nU" XSS9$ ! [         a    [        SU < SU< 35      ef = f)NzInvalid comparison z < F)evaluate)r   r   rR   )r:   r   r   s      r    	_relationVariable._relation
  sC    	H3-C $e,,  	HD#FGG	Hs    2c                .    U R                  U[        5      $ r?   )r  r	   r   s     r    rA   Variable.<lambda>      r!:r,   c                .    U R                  U[        5      $ r?   )r  r   r   s     r    rA   r    r  r,   c                .    U R                  U[        5      $ r?   )r  r   r   s     r    rA   r    r  r,   c                .    U R                  U[        5      $ r?   )r  r   r   s     r    rA   r    r  r,   r%   )r&   r'   r(   r)   r   r*   rY  r8   r2   copyr  r  rJ   r<  r   _construct_symbol_construct_valuer   r   r  r  r  __lt____le____ge____gt__r+   r%   r,   r    r   r     s    /b ,I$,,&G}}!!#HOOWt45$W-#G,#'uw4 *A *AX,@- ;F:F:F:Fr,   r   c                  "    \ rS rSrSrSrS rSrg)Pointeri  a	  Represents a pointer. See ``Variable``.

Examples
========

Can create instances of ``Element``:

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Pointer
>>> i = Symbol('i', integer=True)
>>> p = Pointer('x')
>>> p[i+1]
Element(x, indices=(i + 1,))

r%   c                ~     [        U R                  U5      $ ! [         a    [        U R                  U45      s $ f = fr?   )r   r  rR   )r:   keys     r    __getitem__Pointer.__getitem__(  s:    	04;;,, 	04;;//	0s    !<<N)r&   r'   r(   r)   r   r*   r.  r+   r%   r,   r    r+  r+    s     I0r,   r+  c                  n    \ rS rSrSrS=rr\\S.r\	" \
5      r\	" S 5      r\	" S 5      r\	" \
5      rSrg)	r   i/  aS  Element in (a possibly N-dimensional) array.

Examples
========

>>> from sympy.codegen.ast import Element
>>> elem = Element('x', 'ijk')
>>> elem.symbol.name == 'x'
True
>>> elem.indices
(i, j, k)
>>> from sympy import ccode
>>> ccode(elem)
'x[i][j][k]'
>>> ccode(Element('x', 'ijk', strides='lmn', offset='o'))
'x[i*l + j*m + k*n + o]'

)r  indicesstridesoffset)r2  r3  c                    [        U 6 $ r?   r   r   s    r    rA   Element.<lambda>E      %+r,   c                    [        U 6 $ r?   r5  r6  s    r    rA   r7  F  r8  r,   r%   N)r&   r'   r(   r)   r   r*   r8   rJ   r2   r<  r   r$  _construct_indices_construct_strides_construct_offsetr+   r%   r,   r    r   r   /  sL    $ EDI40H$W-%&=>%&=>$W-r,   r   c                  $    \ rS rSrSrS=rr\rSr	g)r  iJ  a  Represents a variable declaration

Parameters
==========

variable : Variable

Examples
========

>>> from sympy.codegen.ast import Declaration, NoneToken, untyped
>>> z = Declaration('z')
>>> z.variable.type == untyped
True
>>> # value is special NoneToken() which must be tested with == operator
>>> z.variable.value is None  # won't work
False
>>> z.variable.value == None  # not PEP-8 compliant
True
>>> z.variable.value == NoneToken()  # OK
True
)variabler%   N)
r&   r'   r(   r)   r   r*   r8   r   _construct_variabler+   r%   r,   r    r  r  J  s    , ('I"r,   r  c                  B    \ rS rSrSrS=rr\" S 5      r\	S 5       r
Srg)Whileie  a0  Represents a 'for-loop' in the code.

Expressions are of the form:
    "while condition:
         body..."

Parameters
==========

condition : expression convertible to Boolean
body : CodeBlock or iterable
    When passed an iterable it is used to instantiate a CodeBlock.

Examples
========

>>> from sympy import symbols, Gt, Abs
>>> from sympy.codegen import aug_assign, Assignment, While
>>> x, dx = symbols('x dx')
>>> expr = 1 - x**2
>>> whl = While(Gt(Abs(dx), 1e-9), [
...     Assignment(dx, -expr/expr.diff(x)),
...     aug_assign(x, '+', dx)
... ])

)	conditionr4   c                    [        U 5      $ r?   )r   )conds    r    rA   While.<lambda>  s    Xd^r,   c                @    [        U[        5      (       a  U$ [        U6 $ r?   r3  r4  s     r    r6  While._construct_body  r8  r,   r%   N)r&   r'   r(   r)   r   r*   r8   r<  _construct_conditionr   r6  r+   r%   r,   r    rA  rA  e  s1    4 0/I'(CD# #r,   rA  c                  0    \ rS rSrSrS=rr\S 5       rSr	g)Scopei  zRepresents a scope in the code.

Parameters
==========

body : CodeBlock or iterable
    When passed an iterable it is used to instantiate a CodeBlock.

r4   c                @    [        U[        5      (       a  U$ [        U6 $ r?   r3  r4  s     r    r6  Scope._construct_body  r8  r,   r%   N)
r&   r'   r(   r)   r   r*   r8   r   r6  r+   r%   r,   r    rJ  rJ    s%     $#I# #r,   rJ  c                  $    \ rS rSrSrS=rr\rSr	g)Streami  a  Represents a stream.

There are two predefined Stream instances ``stdout`` & ``stderr``.

Parameters
==========

name : str

Examples
========

>>> from sympy import pycode, Symbol
>>> from sympy.codegen.ast import Print, stderr, QuotedString
>>> print(pycode(Print(['x'], file=stderr)))
print(x, file=sys.stderr)
>>> x = Symbol('x')
>>> print(pycode(Print([QuotedString('x')], file=stderr)))  # print literally "x"
print("x", file=sys.stderr)

rd  r%   N)
r&   r'   r(   r)   r   r*   r8   r   r  r+   r%   r,   r    rO  rO    s    * $#IOr,   rO  stdoutstderrc                  B    \ rS rSrSrS=rr\\S.r\	" \
5      r\r\rSrg)Printi  aj  Represents print command in the code.

Parameters
==========

formatstring : str
*args : Basic instances (or convertible to such through sympify)

Examples
========

>>> from sympy.codegen.ast import Print
>>> from sympy import pycode
>>> print(pycode(Print('x y'.split(), "coordinate: %12.5g %12.5g\\n")))
print("coordinate: %12.5g %12.5g\n" % (x, y), end="")

)
print_argsformat_stringfile)rU  rV  r%   N)r&   r'   r(   r)   r   r*   r8   rJ   r2   r<  r!   _construct_print_argsrU  _construct_format_stringrO  _construct_filer+   r%   r,   r    rS  rS    s4    $ BAI!%t4H(3+Or,   rS  c                  n    \ rS rSr% SrSr\\R                  -   rS\S'   \	r
\r\S 5       r\S 5       rSrg	)
FunctionPrototypei  a  Represents a function prototype

Allows the user to generate forward declaration in e.g. C/C++.

Parameters
==========

return_type : Type
name : str
parameters: iterable of Variable instances
attrs : iterable of Attribute instances

Examples
========

>>> from sympy import ccode, symbols
>>> from sympy.codegen.ast import real, FunctionPrototype
>>> x, y = symbols('x y', real=True)
>>> fp = FunctionPrototype(real, 'foo', [x, y])
>>> ccode(fp)
'double foo(double x, double y)'

)return_typer\  r]  r0   r8   c                *    S n[        [        X5      6 $ )Nc                    [        U [        5      (       a  U R                  $ [        U [        5      (       a  U $ [        R	                  U 5      $ r?   )r   r  r>  r   r  r6  s    r    _var5FunctionPrototype._construct_parameters.<locals>._var  s<    #{++||#C**
'',,r,   )r   r   )r   r_  s     r    r
  'FunctionPrototype._construct_parameters  s    	- c$o&&r,   c                l    [        U[        5      (       d  [        S5      eU " S0 UR                  SS9D6$ )Nz1func_def is not an instance of FunctionDefinitionrK  r  r%   )r   FunctionDefinitionrR   rX   )rD   func_defs     r    from_FunctionDefinition)FunctionPrototype.from_FunctionDefinition  s5    ($677OPP8X__Y_788r,   r%   N)r&   r'   r(   r)   r   r*   rY  r8   r   rc  _construct_return_typer   r  r<  r
  r   re  r+   r%   r,   r    r[  r[    sR    0 6I(4<<7G_7!O' ' 9 9r,   r[  c                  z    \ rS rSrSrSr\R                  SS \-   \R                  -   r\	S 5       r
\	S 5       rSrg)	rc  i  a  Represents a function definition in the code.

Parameters
==========

return_type : Type
name : str
parameters: iterable of Variable instances
body : CodeBlock or iterable
attrs : iterable of Attribute instances

Examples
========

>>> from sympy import ccode, symbols
>>> from sympy.codegen.ast import real, FunctionPrototype
>>> x, y = symbols('x y', real=True)
>>> fp = FunctionPrototype(real, 'foo', [x, y])
>>> ccode(fp)
'double foo(double x, double y)'
>>> from sympy.codegen.ast import FunctionDefinition, Return
>>> body = [Return(x*y)]
>>> fd = FunctionDefinition.from_FunctionPrototype(fp, body)
>>> print(ccode(fd))
double foo(double x, double y){
    return x*y;
}
rK  Nc                @    [        U[        5      (       a  U$ [        U6 $ r?   r3  r4  s     r    r6  "FunctionDefinition._construct_body)  r8  r,   c                r    [        U[        5      (       d  [        S5      eU " SSU0UR                  5       D6$ )Nz2func_proto is not an instance of FunctionPrototyper4   r%   )r   r[  rR   rX   )rD   
func_protor4   s      r    from_FunctionPrototype)FunctionDefinition.from_FunctionPrototype0  s8    *&788PQQ44
 1 1 344r,   r%   )r&   r'   r(   r)   r   r*   r[  r8   rY  r   r6  rn  r+   r%   r,   r    rc  rc    sT    : I'',y84<<GG# # 5 5r,   rc  c                  0    \ rS rSrSrS=rr\" \5      r	Sr
g)Returni7  a  Represents a return command in the code.

Parameters
==========

return : Basic

Examples
========

>>> from sympy.codegen.ast import Return
>>> from sympy.printing.pycode import pycode
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> print(pycode(Return(x)))
return x

)returnr%   N)r&   r'   r(   r)   r   r*   r8   r<  r   _construct_returnr+   r%   r,   r    rq  rq  7  s    $ &%I"8,r,   rq  c                  6    \ rS rSrSrS=rr\r\	" S 5      r
Srg)FunctionCalliN  a!  Represents a call to a function in the code.

Parameters
==========

name : str
function_args : Tuple

Examples
========

>>> from sympy.codegen.ast import FunctionCall
>>> from sympy import pycode
>>> fcall = FunctionCall('foo', 'bar baz'.split())
>>> print(pycode(fcall))
foo(bar, baz)

)r\  function_argsc                    [        U 6 $ r?   r5  r   s    r    rA   FunctionCall.<lambda>d  s    r,   r%   N)r&   r'   r(   r)   r   r*   r8   r   r  r<  _construct_function_argsr+   r%   r,   r    ru  ru  N  s$    $ 43IO+,EFr,   ru  c                       \ rS rSrSrS=rrSrg)Raiseig  z3Prints as 'raise ...' in Python, 'throw ...' in C++)	exceptionr%   N)r&   r'   r(   r)   r   r*   r8   r+   r%   r,   r    r{  r{  g  s    >((Ir,   r{  c                  $    \ rS rSrSrS=rr\rSr	g)RuntimeError_il  zRepresents 'std::runtime_error' in C++ and 'RuntimeError' in Python.

Note that the latter is uncommon, and you might want to use e.g. ValueError.
)messager%   N)
r&   r'   r(   r)   r   r*   r8   r   _construct_messager+   r%   r,   r    r~  r~  l  s     '&Ir,   r~  N)	complex64)
complex128)qr   
__future__r   typingr   collectionsr   sympy.core.relationalr   r   r   r	   
sympy.corer
   r   r   sympy.core.basicr   sympy.core.exprr   r   sympy.core.numbersr   r   r   sympy.core.sympifyr   r   r   sympy.utilities.iterablesr   r   r   r   r!   r#   r.   r   break_r   	continue_r   rJ   r   r   r   r   r   r   r   r   r   r   r   r   r0  r   rU  rW  rY  rc  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rX   r  r  r  rm  ro  rq  rs  r  r  r  r   r+  r   r  rA  rJ  rO  rP  rQ  rS  r[  rc  rq  ru  r{  r~  )rD   s   0r    <module>r     sX  ~@ #  # 2 2 + + " & 1 1 > >I I( jJ jX   
E   O	" "0 {8DZ 8Dv% %P .  $0 0 0 0 0  	 68N 6sIIsN  (+VVB
 VBr;% ;|0BT5 0BdE6 E"f " '5  'FtP5 tPn3$ 3
NK 
N	%M 	%	!m 	! ajD 
u_ u_n"m "$/9  66VQgr"gr"gr"#	2	&	2	&	2	&
Ir
4
Ir
4
Ir"
5
Ir"
5Z2S9Z2S9[2[HY1Z[	^S^GNNK\N4]^
 y/V
i
 9%V& &P &/*R;t R;h0h 02.e .6#% #6##E ##L#E #(U 2 
			E 6.9 .9b,5* ,5^-U -.G5$ G2)E )
 E  ]*s   	M?