
    wgR                    H   d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZ i dddd	d
ddddd ddfd ddfd ddfd ddfd ddfd ddfd ddfgd d! d dfgd"d#d$d%d&d'd(d(d)d)d*d*d+d+d,d,d-d-d.d.d/d/d0d1d2d3d4dd5Zg d6Z G d7 d8e      Zd<d:Zd; Zy9)=a  
Rust code printer

The `RustCodePrinter` converts SymPy expressions into Rust expressions.

A complete code generator, which uses `rust_code` extensively, can be found
in `sympy.utilities.codegen`. The `codegen` module can be used to generate
complete source code files.

    )annotations)Any)SRationalFloatLambdaequal_valued)CodePrinterfloorceilingceilAbsabssignsignumPowc                    t        |d      S )Nr	   baseexps     X/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/printing/rust.py<lambda>r   I   s    |C4     recip   c                    t        |d      S )Ng      ?r	   r   s     r   r   r   J   s    |C5 r   sqrtc                    t        |d      S )Ng      r	   r   s     r   r   r   K   s    |C6 r   zsqrt().recipc                     |t        dd      k(  S )N      )r   r   s     r   r   r   L   s    shq!n4 r   cbrtc                    t        | d      S )Nr   r	   r   s     r   r   r   M   s    |D!4 r   exp2r#   c                    |j                   S N
is_integerr   s     r   r   r   N   s
    s~~ r   powir"   c                    |j                    S r(   r)   r   s     r   r   r   O   s    3>>1 r   powfr   c                     y)NT )r   s    r   r   r   P   s    r   loglnMaxmaxMinminsincostanasinacosatanatan2sinhcoshtanhasinhacoshatanh)r>   r?   r@   rA   rB   r   )4abstractalignofasbecomeboxbreakconstcontinuecratedoelseenumexternfalsefinalfnforifimplinletloopmacromatchmodmovemutoffsetofoverrideprivprocpubpurerefreturnSelfselfsizeofstaticstructsupertraittruetypetypeofunsafeunsizedusevirtualwherewhileyieldc            	      V    e Zd ZU dZdZdZ eej                  fi di d e	       dZde
d<   i fd	Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd+ fd	Zd+ fd	Zd Zd Zd Zd Zd Zd+dZd+dZd+dZd+dZ d+dZ!d+d Z"d+d!Z#d+d"Z$d# Z%d$ Z&d% Z'd& Z(d' Z) fd(Z*d) Z+d* Z, xZ-S ),RustCodePrinterz>A printer to convert SymPy expressions to strings of Rust code
_rust_codeRust   T)	precisionuser_functionscontractdereferencezdict[str, Any]_default_settingsc                   t        j                  | |       t        t              | _        |j	                  di       }| j                  j                  |       t        |j	                  dg             | _        t        t              | _        y )Nr}   r   )	r   __init__dictknown_functionsgetupdateset_dereferencereserved_words)rg   settings	userfuncss      r   r   zRustCodePrinter.__init__   si    T8,#O4LL!126	##I.]B ?@!.1r   c                    |dz  S )N   r/   )rg   ps     r   _rate_index_positionz$RustCodePrinter._rate_index_position   s    s
r   c                    d|z  S )Nz%s;r/   )rg   
codestrings     r   _get_statementzRustCodePrinter._get_statement   s    z!!r   c                    d|z  S )Nz// %sr/   )rg   texts     r   _get_commentzRustCodePrinter._get_comment   s    ~r   c                    d|d|dS )Nzconst z: f64 = ;r/   )rg   namevalues      r   _declare_number_constz%RustCodePrinter._declare_number_const   s    (,e44r   c                $    | j                  |      S r(   )indent_code)rg   liness     r   _format_codezRustCodePrinter._format_code   s    &&r   c                J    |j                   \  }fdt        |      D        S )Nc              3  F   K   | ]  }t              D ]  }||f 
  y wr(   )range).0ijcolss      r   	<genexpr>z;RustCodePrinter._traverse_matrix_indices.<locals>.<genexpr>   s%     A1U4[AAAAs   !)shaper   )rg   matrowsr   s      @r   _traverse_matrix_indicesz(RustCodePrinter._traverse_matrix_indices   s    YY
dAdAAr   c           
         g }g }d}|D ]o  }|j                  || j                  |      | j                  |j                        | j                  |j                  dz         dz         |j                  d       q ||fS )Nz#for %(var)s in %(start)s..%(end)s {r"   )varstartend})append_printlowerupper)rg   indices
open_linesclose_lines	loopstartr   s         r   _get_loop_opening_endingz(RustCodePrinter._get_loop_opening_ending  s    
9	 	$Ai{{1~QWW-{{177Q;/+1 1 2 s#	$ ;&&r   c                    t        |j                        dkD  rd| j                  |      z   dz   S |j                  r| j                  |d      S | j                  |      S )Nr"   ()T)_type)lenargsr   	is_numberrg   exprs     r   _print_caller_varz!RustCodePrinter._print_caller_var  sV    tyy>A T**S00^^;;t4;00;;t$$r   c                    |j                   j                   j                  v r6 j                  |j                   j                     }d}d}t        |t              r|}n|D ]  \  }}} ||j
                   s n ||dk(  r^d j                  |j
                  d         |t        |j
                        dkD  r j                  |j
                  dd d      nddz  }|S |dk(  r&d	 j                  |j
                  d         |d
z  }|S |dk(  r&d	 j                  |j
                  d         |d
z  }|S d| j                  |j
                  d      dz  }|S yt        |d      rBt        |j                  t              r( j                   |j                  |j
                         S |j                   j                   j                  v rm j                  |j                   j                     \  }} j                  |      r5t         fd|D              r  j                  |j!                  |            S yy j#                  |      S )a<  
        basic function for printing `Function`

        Function Style :

        1. args[0].func(args[1:]), method with arguments
        2. args[0].func(), method without arguments
        3. args[1].func(), method without arguments (e.g. (e, x) => x.exp())
        4. func(args), function with arguments
        Nr"   z%(var)s.%(method)s(%(args)s)r   ,  )r   methodr   r   z%(var)s.%(method)s())r   r   r#   z%(func)s(%(args)s))funcr   _imp_c              3  @   K   | ]  }j                  |        y wr(   )
_can_print)r   frg   s     r   r   z2RustCodePrinter._print_Function.<locals>.<genexpr>M  s     0Y1C0Y   )r   __name__r   
isinstancestrr   r   r   	stringifyhasattrr   r   r   _rewriteable_functionsr   allrewrite_print_not_supported)	rg   r   	cond_funcr   stylecondrettarget_frequired_fss	   `        r   _print_FunctionzRustCodePrinter._print_Function  s;    99!5!55,,TYY-?-?@IDE)S) )2 %D$TYY' A:8#55diilC"&GJ499~XYGYtyy}d C_a< C( 
 aZ0#55diilC"&4 C 
 aZ0#55diilC"&4 C 
	 / $ $tyy$ ?2 C 
-  . T7#
4::v(F;;ztzz499566YY4#>#>>$($?$?		@R@R$S!Hkx(S0Y[0Y-Y{{4<<#9:: .Z( ,,T22r   c                    |j                   j                  rV|j                  j                  s@ t        |      t	        |j                         |j                        }| j                  |      S | j                  |      S r(   )r   r*   r   rn   r   r   r   r   s     r   
_print_PowzRustCodePrinter._print_PowR  sZ    99(;(;4:eDII.9D;;t$$##D))r   c                4    t         |   |      }|r|dz   S |S )N_f64)rk   _print_Floatrg   r   r   r   	__class__s       r   r   zRustCodePrinter._print_FloatX  s$    g"4(<Jr   c                4    t         |   |      }|r|dz   S |S )N_i32)rk   _print_Integerr   s       r   r   zRustCodePrinter._print_Integer_  s$    g$T*<Jr   c                d    t        |j                        t        |j                        }}d||fz  S )Nz%d_f64/%d.0)intr   q)rg   r   r   r   s       r   _print_RationalzRustCodePrinter._print_Rationalf  s*    466{CK11v%%r   c                    | j                  |j                        }| j                  |j                        }|j                  }dj	                  |||      S )Nz{} {} {})r   lhsrhsrel_opformat)rg   r   lhs_coderhs_codeops        r   _print_Relationalz!RustCodePrinter._print_Relationalj  sD    ;;txx(;;txx([[  2x88r   c                N   |j                   }t        j                  }t        j                  }t	        t        |j                              D ]  }||j                  |   |z  z  }|||   z  }! | j                  |j                  j                        d| j                  |      dS )N[])r   r   ZeroOnereversedr   rankr   r   r   label)rg   r   dimselemoffsetr   s         r   _print_IndexedzRustCodePrinter._print_Indexedp  s    zzvv%		*+ 	ADLLOF**Dd1gF	  ;;tyy7T9JKKr   c                .    |j                   j                  S r(   )r   r   r   s     r   
_print_IdxzRustCodePrinter._print_Idxz  s    zzr   c                    |j                   S r(   )r   r   s     r   _print_DummyzRustCodePrinter._print_Dummy}  s    yyr   c                     y)NEr/   rg   r   r   s      r   _print_Exp1zRustCodePrinter._print_Exp1  s    r   c                     y)NPIr/   r  s      r   	_print_PizRustCodePrinter._print_Pi  s    r   c                     y)NINFINITYr/   r  s      r   _print_InfinityzRustCodePrinter._print_Infinity  s    r   c                     y)NNEG_INFINITYr/   r  s      r   _print_NegativeInfinityz'RustCodePrinter._print_NegativeInfinity  s    r   c                     y)Nrm   r/   r  s      r   _print_BooleanTruez"RustCodePrinter._print_BooleanTrue  s    r   c                     y)NrP   r/   r  s      r   _print_BooleanFalsez#RustCodePrinter._print_BooleanFalse  s    r   c                4    t        |      j                         S r(   )r   r   r  s      r   _print_boolzRustCodePrinter._print_bool  s    4y  r   c                     y)NNANr/   r  s      r   
_print_NaNzRustCodePrinter._print_NaN  s    r   c                H   |j                   d   j                  dk7  rt        d      g }t        |j                         D ]  \  }\  }}|dk(  r$|j	                  d| j                  |      z         nM|t        |j                         dz
  k(  r|dk(  r|dxx   dz  cc<   n|dxx   d| j                  |      z  z  cc<   | j                  |      }|j	                  |       |j	                  d	        | j                  d
   rdj                  |      S dj                  |      S )Nr   TzAll Piecewise expressions must contain an (expr, True) statement to be used as a default condition. Without one, the generated expression may not evaluate to anything under some condition.r   z	if (%s) {r"   z else {z else if (%s) {r   inline 
)	r   r   
ValueError	enumerater   r   r   	_settingsjoin)rg   r   r   r   eccode0s          r   _print_Piecewisez RustCodePrinter._print_Piecewise  s   99R=%  / 0 0
 "499- 		IAv1Av[4;;q>9:c$))nq((Q$Yb	Y&	b	.Q??	KKNELLLL		 >>(#88E?"99U##r   c                R    ddl m} | j                  |j                  |d            S )Nr   )	PiecewiseF)deep)sympy.functionsr'  r   r   )rg   r   r'  s      r   
_print_ITEzRustCodePrinter._print_ITE  s!    -{{4<<	<>??r   c                r     |j                   dk(  rddj                   fd|D              z  S t        d      )Nr"   z[%s]r   c              3  @   K   | ]  }j                  |        y wr(   )r   )r   arg   s     r   r   z4RustCodePrinter._print_MatrixBase.<locals>.<genexpr>  s     %@dkk!n%@r   zLFull Matrix Support in Rust need Crates (https://crates.io/keywords/matrix).)r   r!  r  )rg   As   ` r   _print_MatrixBasez!RustCodePrinter._print_MatrixBase  s4    66Q;DII%@a%@@@@kllr   c                $    | j                  |      S r(   )r   )rg   r   s     r   _print_SparseRepMatrixz&RustCodePrinter._print_SparseRepMatrix  s    ((--r   c                    |j                   d|j                  |j                  |j                   j                  d   z  z   dS )Nr   r"   r   )parentr   r   r   r   s     r   _print_MatrixElementz$RustCodePrinter._print_MatrixElement  s9    ;;66DFF4;;+<+<Q+?$??A 	Ar   c                L    t         |   |      }|| j                  v rd|z  S |S )Nz(*%s))rk   _print_Symbolr   )rg   r   r   r   s      r   r6  zRustCodePrinter._print_Symbol  s/    w$T*4$$$T>!Kr   c                4   ddl m} |j                  }|j                  }| j                  d   r4|j                  |      s|j                  |      r| j                  ||      S | j                  |      }| j                  |      }| j                  |d|      S )Nr   )IndexedBaser~   z = )	sympy.tensor.indexedr8  r   r   r   has_doprint_loopsr   r   )rg   r   r8  r   r   r   r   s          r   _print_Assignmentz!RustCodePrinter._print_Assignment  s    4hhhh>>*%377;+?$ &&sC00{{3'H{{3'H&&Hh'GHHr   c                l   t        |t              r1| j                  |j                  d            }dj	                  |      S d}d}d}|D cg c]  }|j                  d       }}|D cg c]*  }t        t        t        |j                  |                  , }}|D cg c]*  }t        t        t        |j                  |                  , }}g }	d}
t        |      D ]C  \  }}|dv r|	j                  |       |
||   z  }
|	j                  ||
z  |       |
||   z  }
E |	S c c}w c c}w c c}w )	z0Accepts a string of code or a list of code linesTr   z    ){r   z{
z(
)r   r   z 	r   )r   r  )r   r   r   
splitlinesr!  lstripr   anymapendswith
startswithr  r   )rg   code
code_linestab	inc_token	dec_tokenlineincreasedecreaseprettylevelns               r   r   zRustCodePrinter.indent_code  s:    dC ))$//$*?@J77:&&,		046U#66IMOSS	:;<OO!%( S)<=> ( (   	!GAtz!d#Xa[ EMMCIt45Xa[ E	!  7O(s   D'*/D,/D1)F).r   
__module____qualname____doc__printmethodlanguager   r   r   r   __annotations__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  r  r%  r*  r/  r1  r4  r6  r<  r   __classcell__)r   s   @r   rx   rx      s    HKH(,[-J-J )u	O )~  !# 2"5'B'	%63p*&9L!$6@m.AIr   rx   Nc                8    t        |      j                  | |      S )a  Converts an expr to a string of Rust code

    Parameters
    ==========

    expr : Expr
        A SymPy expression to be converted.
    assign_to : optional
        When given, the argument is used as the name of the variable to which
        the expression is assigned. Can be a string, ``Symbol``,
        ``MatrixSymbol``, or ``Indexed`` type. This is helpful in case of
        line-wrapping, or for expressions that generate multi-line statements.
    precision : integer, optional
        The precision for numbers such as pi [default=15].
    user_functions : dict, optional
        A dictionary where the keys are string representations of either
        ``FunctionClass`` or ``UndefinedFunction`` instances and the values
        are their desired C string representations. Alternatively, the
        dictionary value can be a list of tuples i.e. [(argument_test,
        cfunction_string)].  See below for examples.
    dereference : iterable, optional
        An iterable of symbols that should be dereferenced in the printed code
        expression. These would be values passed by address to the function.
        For example, if ``dereference=[a]``, the resulting code would print
        ``(*a)`` instead of ``a``.
    human : bool, optional
        If True, the result is a single string that may contain some constant
        declarations for the number symbols. If False, the same information is
        returned in a tuple of (symbols_to_declare, not_supported_functions,
        code_text). [default=True].
    contract: bool, optional
        If True, ``Indexed`` instances are assumed to obey tensor contraction
        rules and the corresponding nested loops over indices are generated.
        Setting contract=False will not generate loops, instead the user is
        responsible to provide values for the indices in the code.
        [default=True].

    Examples
    ========

    >>> from sympy import rust_code, symbols, Rational, sin, ceiling, Abs, Function
    >>> x, tau = symbols("x, tau")
    >>> rust_code((2*tau)**Rational(7, 2))
    '8*1.4142135623731*tau.powf(7_f64/2.0)'
    >>> rust_code(sin(x), assign_to="s")
    's = x.sin();'

    Simple custom printing can be defined for certain types by passing a
    dictionary of {"type" : "function"} to the ``user_functions`` kwarg.
    Alternatively, the dictionary value can be a list of tuples i.e.
    [(argument_test, cfunction_string)].

    >>> custom_functions = {
    ...   "ceiling": "CEIL",
    ...   "Abs": [(lambda x: not x.is_integer, "fabs", 4),
    ...           (lambda x: x.is_integer, "ABS", 4)],
    ...   "func": "f"
    ... }
    >>> func = Function('func')
    >>> rust_code(func(Abs(x) + ceiling(x)), user_functions=custom_functions)
    '(fabs(x) + x.CEIL()).f()'

    ``Piecewise`` expressions are converted into conditionals. If an
    ``assign_to`` variable is provided an if statement is created, otherwise
    the ternary operator is used. Note that if the ``Piecewise`` lacks a
    default term, represented by ``(expr, True)`` then an error will be thrown.
    This is to prevent generating an expression that may not evaluate to
    anything.

    >>> from sympy import Piecewise
    >>> expr = Piecewise((x + 1, x > 0), (x, True))
    >>> print(rust_code(expr, tau))
    tau = if (x > 0) {
        x + 1
    } else {
        x
    };

    Support for loops is provided through ``Indexed`` types. With
    ``contract=True`` these expressions will be turned into loops, whereas
    ``contract=False`` will just print the assignment expression that should be
    looped over:

    >>> from sympy import Eq, IndexedBase, Idx
    >>> len_y = 5
    >>> y = IndexedBase('y', shape=(len_y,))
    >>> t = IndexedBase('t', shape=(len_y,))
    >>> Dy = IndexedBase('Dy', shape=(len_y-1,))
    >>> i = Idx('i', len_y-1)
    >>> e=Eq(Dy[i], (y[i+1]-y[i])/(t[i+1]-t[i]))
    >>> rust_code(e.rhs, assign_to=e.lhs, contract=False)
    'Dy[i] = (y[i + 1] - y[i])/(t[i + 1] - t[i]);'

    Matrices are also supported, but a ``MatrixSymbol`` of the same dimensions
    must be provided to ``assign_to``. Note that any expression that can be
    generated normally can also exist inside a Matrix:

    >>> from sympy import Matrix, MatrixSymbol
    >>> mat = Matrix([x**2, Piecewise((x + 1, x > 0), (x, True)), sin(x)])
    >>> A = MatrixSymbol('A', 3, 1)
    >>> print(rust_code(mat, A))
    A = [x.powi(2), if (x > 0) {
        x + 1
    } else {
        x
    }, x.sin()];
    )rx   doprint)r   	assign_tor   s      r   	rust_coderZ    s    Z 8$,,T9==r   c                .    t        t        | fi |       y)z3Prints Rust representation of the given expression.N)printrZ  )r   r   s     r   print_rust_coder]  i  s    	)D
%H
%&r   r(   )rR  
__future__r   typingr   
sympy.corer   r   r   r   sympy.core.numbersr
   sympy.printing.codeprinterr   r   r   rx   rZ  r]  r/   r   r   <module>rc     s  	B #  1 1 + 2$2 W2 v2 
52 H2  
4gqA5vqA6J4fa@4fa@-vq9161=?!2. 
ua()/20 
412< 
5=2> 
5?2B 
5C2D 
5E2F 
5G2H FI2J FK2L FM2N WO2V FW2X c2X3l[k [|m>`'r   