
    gR                    P   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d9S )=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     O/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/printing/rust.py<lambda>r   I   s    |C44     recip   c                "    t          |d          S )Ng      ?r	   r   s     r   r   r   J   s    |C55 r   sqrtc                "    t          |d          S )Ng      r	   r   s     r   r   r   K   s    |C66 r   zsqrt().recipc                *    |t          dd          k    S )N      )r   r   s     r   r   r   L   s    shq!nn4 r   cbrtc                "    t          | d          S )Nr   r	   r   s     r   r   r   M   s    |D!4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                    dS )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            	      R    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                D   t          j        | |           t          t                    | _        |                    di           }| j                            |           t          |                    dg                     | _        t          t                    | _        d S )Nr}   r   )	r   __init__dictknown_functionsgetupdateset_dereferencereserved_words)rg   settings	userfuncss      r   r   zRustCodePrinter.__init__   s    T8,,,#O44LL!1266	##I...]B ? ?@@!.1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     (,eee44r   c                ,    |                      |          S r(   )indent_code)rg   liness     r   _format_codezRustCodePrinter._format_code   s    &&&r   c                N    |j         \  }fdt          |          D             S )Nc              3  D   K   | ]}t                    D ]}||fV  	d S r(   )range).0ijcolss      r   	<genexpr>z;RustCodePrinter._traverse_matrix_indices.<locals>.<genexpr>   s:      AA1U4[[AAAAAAAAAAr   )shaper   )rg   matrowsr   s      @r   _traverse_matrix_indicesz(RustCodePrinter._traverse_matrix_indices   s.    Y
dAAAAdAAAAr   c           
        g }g }d}|D ]y}|                     ||                     |          |                     |j                  |                     |j        dz             dz             |                     d           z||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~~QW--{{17Q;//+1 +1 1 2 2 2 s####;&&r   c                    t          |j                  dk    rd|                     |          z   dz   S |j        r|                     |d          S |                     |          S )Nr"   ()T)_type)lenargsr   	is_numberrg   exprs     r   _print_caller_varz!RustCodePrinter._print_caller_var  se    ty>>A T***S00^ 	%;;t4;000;;t$$$r   c                d    |j         j         j        v r2 j        |j         j                 }d}d}t          |t                    r|}n|D ]\  }}} ||j         r n||dk    rcd                     |j        d                   |t          |j                  dk    r#                     |j        dd         d          nddz  }n{|dk    r'd	                     |j        d                   |d
z  }nN|dk    r'd	                     |j        d                   |d
z  }n!d|                     |j        d          dz  }|S dS t          |d          r<t          |j
        t                    r"                      |j
        |j                   S |j         j         j        v rv j        |j         j                 \  }}                     |          rCt           fd|D                       r*                     |                    |                    S dS dS                      |          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  B   K   | ]}                     |          V  d S r(   )
_can_print)r   frg   s     r   r   z2RustCodePrinter._print_Function.<locals>.<genexpr>M  s/      0Y0Y1C1C0Y0Y0Y0Y0Y0Yr   )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    9!555,TY-?@IDE)S))  )2  %D$tTY' A::8#55dilCC"&GJ49~~XYGYGYty}d C C C_a< < CC
 aZZ0#55dilCC"&4 4 CC aZZ0#55dilCC"&4 4 CC
 / $ $ty$ ? ?2 2 C 
-  . T7## 		3
4:v(F(F 		3;;ztz495666Y4#>>>$($?	@R$S!Hkx(( ;S0Y0Y0Y0Y[0Y0Y0Y-Y-Y ;{{4<<#9#9:::; ; ; ; ,,T222r   c                    |j         j        rQ|j        j        sE t          |          t	          |j                   |j                  }|                     |          S |                     |          S r(   )r   r*   r   rn   r   r   r   r   s     r   
_print_PowzRustCodePrinter._print_PowR  sd    9 	%(; 	%4::eDI..99D;;t$$$##D)))r   Fc                X    t                                          |          }|r|dz   S |S )N_f64)rk   _print_Floatrg   r   r   r   	__class__s       r   r   zRustCodePrinter._print_FloatX  s1    gg""4(( 	<Jr   c                X    t                                          |          }|r|dz   S |S )N_i32)rk   _print_Integerr   s       r   r   zRustCodePrinter._print_Integer_  s1    gg$$T** 	<Jr   c                `    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*    46{{CKK11v%%r   c                    |                      |j                  }|                      |j                  }|j        }d                    |||          S )Nz{} {} {})r   lhsrhsrel_opformat)rg   r   lhs_coderhs_codeops        r   _print_Relationalz!RustCodePrinter._print_Relationalj  sG    ;;tx((;;tx(([  2x888r   c                4   |j         }t          j        }t          j        }t	          t          |j                            D ] }||j        |         |z  z  }|||         z  }!|                     |j	        j
                  d|                     |          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    zv%	**++ 	 	ADLOF**Dd1gFF;;ty7777T9J9J9J9JKKr   c                    |j         j        S r(   )r   r   r   s     r   
_print_IdxzRustCodePrinter._print_Idxz  s    zr   c                    |j         S r(   )r   r   s     r   _print_DummyzRustCodePrinter._print_Dummy}  s
    yr   c                    dS )NEr/   rg   r   r   s      r   _print_Exp1zRustCodePrinter._print_Exp1  s    sr   c                    dS )NPIr/   r  s      r   	_print_PizRustCodePrinter._print_Pi  s    tr   c                    dS )NINFINITYr/   r  s      r   _print_InfinityzRustCodePrinter._print_Infinity  s    zr   c                    dS )NNEG_INFINITYr/   r  s      r   _print_NegativeInfinityz'RustCodePrinter._print_NegativeInfinity  s    ~r   c                    dS )Nrm   r/   r  s      r   _print_BooleanTruez"RustCodePrinter._print_BooleanTrue  s    vr   c                    dS )NrP   r/   r  s      r   _print_BooleanFalsez#RustCodePrinter._print_BooleanFalse  s    wr   c                D    t          |                                          S r(   )r   r   r  s      r   _print_boolzRustCodePrinter._print_bool  s    4yy   r   c                    dS )NNANr/   r  s      r   
_print_NaNzRustCodePrinter._print_NaN  s    ur   c                   |j         d         j        dk    rt          d          g }t          |j                   D ]\  }\  }}|dk    r,|                    d|                     |          z             nX|t          |j                   dz
  k    r|dk    r|dxx         dz  cc<   n&|dxx         d|                     |          z  z  cc<   |                     |          }|                    |           |                    d	           | j        d
         rd                    |          S d                    |          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  sI   9R=%%  / 0 0 0
 "49-- 		 		IAv1Avv[4;;q>>9::::c$)nnq(((Q$YYb			Y&				b			.Q??			KKNNELLLL>(# 	$88E??"99U###r   c                b    ddl m} |                     |                    |d                    S )Nr   )	PiecewiseF)deep)sympy.functionsr&  r   r   )rg   r   r&  s      r   
_print_ITEzRustCodePrinter._print_ITE  s6    ------{{4<<	<>>???r   c                     |j         dk    r$dd                     fd|D                       z  S t          d          )Nr"   z[%s]r   c              3  B   K   | ]}                     |          V  d S r(   )r   )r   arg   s     r   r   z4RustCodePrinter._print_MatrixBase.<locals>.<genexpr>  s-      %@%@dkk!nn%@%@%@%@%@%@r   zLFull Matrix Support in Rust need Crates (https://crates.io/keywords/matrix).)r   r   r  )rg   As   ` r   _print_MatrixBasez!RustCodePrinter._print_MatrixBase  sI    6Q;;DII%@%@%@%@a%@%@%@@@@@klllr   c                ,    |                      |          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  s8    ;;;6DF4;+<Q+?$????A 	Ar   c                f    t                                          |          }|| j        v rd|z  S |S )Nz(*%s))rk   _print_Symbolr   )rg   r   r   r   s      r   r5  zRustCodePrinter._print_Symbol  s7    ww$$T**4$$$T>!Kr   c                L   ddl m} |j        }|j        }| j        d         r@|                    |          s|                    |          r|                     ||          S |                     |          }|                     |          }|                     |d|          S )Nr   )IndexedBaser~   z = )	sympy.tensor.indexedr7  r   r   r  has_doprint_loopsr   r   )rg   r   r7  r   r   r   r   s          r   _print_Assignmentz!RustCodePrinter._print_Assignment  s    444444hh>*% 	I377;+?+? 	I$$	I &&sC000{{3''H{{3''H&&HHHhh'GHHHr   c                  
 t          |t                    r=|                     |                    d                    }d                    |          S d}dd
d |D             }fd|D             }
fd|D             }g }d	}t          |          D ]Q\  }}	|	d
v r|                    |	           |||         z  }|                    ||z  |	           |||         z  }R|S )z0Accepts a string of code or a list of code linesTr   z    ){r   z{
z(
)r   r   c                8    g | ]}|                     d           S )z 	)lstrip)r   lines     r   
<listcomp>z/RustCodePrinter.indent_code.<locals>.<listcomp>  s$    666U##666r   c           
     n    g | ]1}t          t          t          |j                                      2S r/   )r   anymapendswith)r   r@  	inc_tokens     r   rA  z/RustCodePrinter.indent_code.<locals>.<listcomp>  s5    OOOSS	::;;<<OOOr   c           
     n    g | ]1}t          t          t          |j                                      2S r/   )r   rC  rD  
startswith)r   r@  	dec_tokens     r   rA  z/RustCodePrinter.indent_code.<locals>.<listcomp>  sE     ( ( ( S)<<==>> ( ( (r   r   )r   r  )r   r   r   
splitlinesr   r  r   )rg   code
code_linestabincreasedecreaseprettylevelnr@  rI  rF  s             @@r   r   zRustCodePrinter.indent_code  s3    dC   	'))$//$*?*?@@J77:&&&,		66666OOOOOOO( ( ( (!%( ( (   	! 	!GAtz!!d###Xa[ EMMCIItt4555Xa[ EEr   )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.  r0  r3  r5  r;  r   __classcell__)r   s   @r   rx   rx      s        HHKH(,[-J ) )suu	O O ) )     !# 2 2 2 2  " " "  5 5 5' ' 'B B B' ' '	% 	% 	%63 63 63p* * *          & & &9 9 9L L L                      ! ! ! !   $ $ $6@ @ @m m m. . .A A A    I I I      r   rx   Nc                H    t          |                              | |          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_coder]    s#    Z 8$$,,T9===r   c                :    t          t          | fi |           dS )z3Prints Rust representation of the given expression.N)printr]  )r   r   s     r   print_rust_coder`  i  s&    	)D
%
%H
%
%&&&&&r   r(   )rU  
__future__r   typingr   
sympy.corer   r   r   r   sympy.core.numbersr
   sympy.printing.codeprinterr   r   r   rx   r]  r`  r/   r   r   <module>rf     sj  	 	B # " " " " "       1 1 1 1 1 1 1 1 1 1 1 1 + + + + + + 2 2 2 2 2 2$2 W2 v2 
52 H2  
44gqA55vqA66J44fa@44fa@--vq91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 2 2X3 3 3l[ [ [ [ [k [ [ [|m> m> m> m>`' ' ' ' 'r   