
    Xh_Q                       d Z ddlmZ ddlmZ ddlZddlmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ  G d de          Z G d de          Z eefee fdZ!i 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/d0d0d1d1d2d2d3d3d4d4d5d5d6d6d7d7d8d8d9d:d;d<dd=Z"g d>Z# G d? d@e          Z$ G dA dBe          Z%dS )Ca  
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)reduceN)Any)float32float64int32realintegerbool_)SRationalFloatLambda)Exprequal_valued)ceilingfloor)CodePrinter)
PRECEDENCEc                      e Zd ZdZd ZdS )float_floorzi
    Same as `sympy.floor`, but mimics the Rust behavior of returning a float rather than an integer
    c                    dS NF selfs    e/var/www/tools.fuzzalab.pt/emblema-extractor/venv/lib/python3.11/site-packages/sympy/printing/rust.py_eval_is_integerzfloat_floor._eval_is_integerE       u    N__name__
__module____qualname____doc__r   r   r!   r   r   r   A   -             r!   r   c                      e Zd ZdZd ZdS )float_ceilingzk
    Same as `sympy.ceiling`, but mimics the Rust behavior of returning a float rather than an integer
    c                    dS r   r   r   s    r   r   zfloat_ceiling._eval_is_integerL   r    r!   Nr"   r   r!   r   r)   r)   H   r'   r!   r)   )r   r   r   ceilAbsabsPowc                "    t          |d          S )Nr   baseexps     r   <lambda>r4   f   s    |C44 r!   recip   c                "    t          |d          S )Ng      ?r   r1   s     r   r4   r4   g   s    |C55 r!   sqrtc                "    t          |d          S )Ng      r   r1   s     r   r4   r4   h   s    |C66 r!   zsqrt().recipc                *    |t          dd          k    S )N      )r   r1   s     r   r4   r4   i   s    shq!nn4 r!   cbrtc                "    t          | d          S )Nr6   r   r1   s     r   r4   r4   j   s    |D!44 r!   exp2r<   c                    |j         S N
is_integerr1   s     r   r4   r4   k   s    s~ r!   powir;   c                    |j          S rA   rB   r1   s     r   r4   r4   l   s    3>1 r!   powfr3   c                    dS )NTr   )r3   s    r   r4   r4   m   s     r!   loglnMaxmaxMinminsincostanasinacosatanatan2sinhcoshtanhasinhacoshatanh)rW   rX   rY   rZ   r8   )4abstractasasyncawaitbecomeboxbreakconstcontinuecratedodynelseenumexternfalsefinalfnforgenifimplinletloopmacromatchmodmovemutoverrideprivpubrefreturnSelfr   staticstructsupertraittruetrytypetypeofunsafeunsizedusevirtualwherewhileyieldc                  X     e Zd ZdZd	 fdZed             Zed             Zd
dZ xZ	S )TypeCastz9
    The type casting operator of the Rust language.
    r}   Nonec                    t                                                       |j        o|t          u| _        |j        | _        | j        r!t          | dt          d         dz              d S d S )N
precedenceFunc
   )r   __init__rC   r
   explicit_assumptionssetattrr   )r   exprtype_	__class__s      r   r   zTypeCast.__init__   sp    @E,@ -= 	AD,
6(:R(?@@@@@	A 	Ar!   c                    | j         d         S )Nr   argsr   s    r   r   zTypeCast.expr      y|r!   c                    | j         d         S )Nr;   r   r   s    r   r   zTypeCast.type_  r   r!   Nc                D    | j         d                             |          S )Nr   )order)r   sort_key)r   r   s     r   r   zTypeCast.sort_key  s    y|$$5$111r!   )r}   r   rA   )
r#   r$   r%   r&   r   propertyr   r   r   __classcell__r   s   @r   r   r      s         A A A A A A   X   X2 2 2 2 2 2 2 2r!   r   c            	          e Zd ZU dZdZdZeeee	iZ
edede	dedi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 fdZd9 f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, Z0d- Z1d. Z2d/ Z3d0 Z4 fd1Z5d2 Z6d3 Z7d4 Z8d5 Z9d6 Z:d7 Z;d8 Z< xZ=S );RustCodePrinterz>A printer to convert SymPy expressions to strings of Rust code
_rust_codeRusti32f32f64bool   T)	precisionuser_functionscontractdereferencezdict[str, Any]_default_settingsc                \   t          j        | |           t          t                    | _        |                    di           }| j                            |           t          |                    dg                     | _        t          t                    | _        t          | _	        d S )Nr   r   )
r   r   dictknown_functionsgetupdateset_dereferencereserved_wordsfunction_overrides)r   settings	userfuncss      r   r   zRustCodePrinter.__init__(  s    T8,,,#O44LL!1266	##I...]B ? ?@@!.11"4r!   c                    |dz  S )N   r   )r   ps     r   _rate_index_positionz$RustCodePrinter._rate_index_position1  s    s
r!   c                    d|z  S )Nz%s;r   )r   
codestrings     r   _get_statementzRustCodePrinter._get_statement4  s    z!!r!   c                    d|z  S )Nz// %sr   )r   texts     r   _get_commentzRustCodePrinter._get_comment7  s    ~r!   c                T    | j         | j        t                            }d|d|d|dS )Nzconst z:  = ;)type_mappingstype_aliasesr	   )r   namevaluer   s       r   _declare_number_constz%RustCodePrinter._declare_number_const:  s2    "4#4T#:;'+ttUUUEEE::r!   c                ,    |                      |          S rA   )indent_code)r   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 rA   )range).0ijcolss      r   	<genexpr>z;RustCodePrinter._traverse_matrix_indices.<locals>.<genexpr>C  s:      AA1U4[[AAAAAAAAAAr!   )shaper   )r   matrowsr   s      @r   _traverse_matrix_indicesz(RustCodePrinter._traverse_matrix_indicesA  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)r   indices
open_linesclose_lines	loopstartr   s         r   _get_loop_opening_endingz(RustCodePrinter._get_loop_opening_endingE  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)lenr   r   	is_numberr   r   s     r   _print_caller_varz!RustCodePrinter._print_caller_varR  se    ty>>A T***S00^ 	%;;t4;000;;t$$$r!   c                P   |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 |                     |          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   r6   z%(var)s.%(method)s())r   r   r<   z%(func)s(%(args)s))funcr   _imp_)r   r#   r   
isinstancestrr   r   r   	stringifyhasattrr   r   r   _print_not_supported)r   r   	cond_funcr   stylecondrets          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,,T222r!   c                     t          d |j        D                       }|r+t          t          j         fd|j        D                       }t                                          |          S )Nc              3  4   K   | ]}|j         o|j         V  d S rA   is_realrC   r   args     r   r   z-RustCodePrinter._print_Mul.<locals>.<genexpr>  .      VVSck@#..@VVVVVVr!   c              3  R   K   | ]!}|d k    r                     |          n|V  "dS )r0   N_cast_to_floatr   r  r   s     r   r   z-RustCodePrinter._print_Mul.<locals>.<genexpr>  s@      'l'l[^C2II(;(;C(@(@(@SV'l'l'l'l'l'lr!   )anyr   r   operatormulr   
_print_Mul)r   r   contains_floatsr   s   `  r   r  zRustCodePrinter._print_Mul  sm    VVDIVVVVV 	n(,'l'l'l'lbfbk'l'l'lmmDww!!$'''r!   Nc                     t          d |j        D                       }|r+t          t          j         fd|j        D                       }t                                          ||          S )Nc              3  4   K   | ]}|j         o|j         V  d S rA   r
  r  s     r   r   z-RustCodePrinter._print_Add.<locals>.<genexpr>  r  r!   c              3  B   K   | ]}                     |          V  d S rA   r  r  s     r   r   z-RustCodePrinter._print_Add.<locals>.<genexpr>  s1      (W(Wc)<)<S)A)A(W(W(W(W(W(Wr!   )r  r   r   r  addr   
_print_Add)r   r   r   r  r   s   `   r   r  zRustCodePrinter._print_Add  sm    VVDIVVVVV 	Y(,(W(W(W(WTY(W(W(WXXDww!!$...r!   c                    |j         j        rQ|j        j        sE t          |          t	          |j                   |j                  }|                     |          S |                     |          S rA   )r2   rC   r3   r   r   r   r  r   s     r   
_print_PowzRustCodePrinter._print_Pow  sd    9 	%(; 	%4::eDI..99D;;t$$$##D)))r!   c                    |j         s|                     |j                  S |                     |j                  d| j        | j        |j                          z  z   S )Nz as %s)r   r   r   r   r   r   r   s     r   _print_TypeCastzRustCodePrinter._print_TypeCast  sS    } 	i;;ty)));;ty))Ht7I$J[\`\fJg7h,hhhr!   Fc                    t                                          |          }|r#|d| j        | j        t                            z  z   S |S Nz_%s)r   _print_Floatr   r   r	   r   r   r   r  r   s       r   r#  zRustCodePrinter._print_Float  sG    gg""4(( 	!3D4Ed4K!LLLLJr!   c                    t                                          |          }|r#|d| j        | j        t                            z  z   S |S r"  )r   _print_Integerr   r   r
   r$  s       r   r&  zRustCodePrinter._print_Integer  sG    gg$$T** 	!3D4Eg4N!OOOOJr!   c                    t          |j                  t          |j                  }}| j        | j        t
                            }d|||fz  S )Nz
%d_%s/%d.0)intr   qr   r   r	   )r   r   r   r)  float_suffixs        r   _print_RationalzRustCodePrinter._print_Rational  sB    46{{CKK1)$*;D*ABq,222r!   c                x   |j         j        r|j        j        r|j        j        rA|j         j        s5|                     |j                   }|                     |j                  }n|j         }|j        }|                     |          }|                     |          }|j        }d                    |||          S )Nz{} {} {})lhsrC   rhsr  r   rel_opformat)r   r   r-  r.  lhs_coderhs_codeops          r   _print_Relationalz!RustCodePrinter._print_Relational  s    H 	(; 	AT 	]a]e]p 	%%dh//C%%dh//CC(C(C;;s##;;s##[  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   r2   label)r   r   dimselemoffsetr   s         r   _print_IndexedzRustCodePrinter._print_Indexed  s    zv%	**++ 	 	ADLOF**Dd1gFF;;ty7777T9J9J9J9JKKr!   c                    |j         j        S rA   )r<  r   r   s     r   
_print_IdxzRustCodePrinter._print_Idx  s    zr!   c                    |j         S rA   )r   r   s     r   _print_DummyzRustCodePrinter._print_Dummy  s
    yr!   c                    dS )NEr   r   r   r   s      r   _print_Exp1zRustCodePrinter._print_Exp1  s    sr!   c                    dS )NPIr   rG  s      r   	_print_PizRustCodePrinter._print_Pi  s    tr!   c                    dS )NINFINITYr   rG  s      r   _print_InfinityzRustCodePrinter._print_Infinity  s    zr!   c                    dS )NNEG_INFINITYr   rG  s      r   _print_NegativeInfinityz'RustCodePrinter._print_NegativeInfinity  s    ~r!   c                    dS )Nr   r   rG  s      r   _print_BooleanTruez"RustCodePrinter._print_BooleanTrue  s    vr!   c                    dS )Nrj   r   rG  s      r   _print_BooleanFalsez#RustCodePrinter._print_BooleanFalse  s    wr!   c                D    t          |                                          S rA   )r   r   rG  s      r   _print_boolzRustCodePrinter._print_bool  s    4yy   r!   c                    dS )NNANr   rG  s      r   
_print_NaNzRustCodePrinter._print_NaN  r    r!   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 )Nr0   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)r   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.functionsrh  r   rewrite)r   r   rh  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 rA   )r   )r   ar   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   rb  r_  )r   As   ` r   _print_MatrixBasez!RustCodePrinter._print_MatrixBase  sI    6Q;;DII%@%@%@%@a%@%@%@@@@@klllr!   c                ,    |                      |          S rA   )r  )r   r   s     r   _print_SparseRepMatrixz&RustCodePrinter._print_SparseRepMatrix  s    ((---r!   c                \    |j         d|j        |j        |j         j        d         z  z   dS )Nr6  r;   r7  )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))r   _print_Symbolr   )r   r   r   r   s      r   rx  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   r   )	sympy.tensor.indexedrz  r-  r.  ra  has_doprint_loopsr   r   )r   r   rz  r-  r.  r1  r2  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    |                      |j        d                   }d|d|dS )Nr   z(if (z == 0.0) { 0.0 } else { (z).signum() }))r   r   )r   r   r  s      r   _print_signzRustCodePrinter._print_sign5  s.    kk$)A,''DGCCMMr!   c                j    |j         st          |t                    S |j        rt	          |          S |S rA   )r   r   r	   rC   r   r   s     r   r  zRustCodePrinter._cast_to_float9  s7    ~ 	D$'''_ 	;;r!   c                n    || j         v p,|t          v p#t          | d                    |          d          S )z Check if function ``name`` is either a known function or has its own
            printing method. Used to check if rewriting is possible.z	_print_{}F)r   r   getattrr0  )r   r   s     r   
_can_printzRustCodePrinter._can_print@  s@     t++{t7I/I{WUY[f[m[mnr[s[suzM{M{{r!   c                    t                      }t          |t                    rS|j        r|                    |j                   |j        D ]*}|                    |                     |                    }+|S rA   )	r   r   r   is_Functionr  r   r   union_collect_functions)r   r   	functionsr  s       r   r  z"RustCodePrinter._collect_functionsI  sw    EE	dD!! 	J )di(((y J J%OOD,C,CC,H,HII		r!   c                    t          |t                    s|S                      |          } fd j                                        D             }|D ]7}|                    |j        d          \  }}|r|                    |          }8|S )Nc                    i | ]=\  }\  }}                     |          t          fd |D                       8|||f>S )c              3  B   K   | ]}                     |          V  d S rA   )r  )r   fr   s     r   r   zFRustCodePrinter._rewrite_known_functions.<locals>.<dictcomp>.<genexpr>[  s/      <<1DOOA&&<<<<<<r!   )r  all)r   r   target_frequired_fsr   s       r   
<dictcomp>z<RustCodePrinter._rewrite_known_functions.<locals>.<dictcomp>W  sr     !
 !
 !
--xx((!
 <<<<<<<<<	!
8[)!
 !
 !
r!   )NN)r   r   r  _rewriteable_functionsitemsr   r#   rk  )r   r   expression_functionsrewriteable_functionsr   r  _s   `      r   _rewrite_known_functionsz(RustCodePrinter._rewrite_known_functionsR  s    $%% 	K#66t<<!
 !
 !
 !
151L1R1R1T1T!
 !
 !
 ) 	. 	.D/33DM<PPKHa .||H--r!   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>n  s$    666U##666r!   c           
     n    g | ]1}t          t          t          |j                                      2S r   )r(  r  mapendswith)r   r  	inc_tokens     r   r  z/RustCodePrinter.indent_code.<locals>.<listcomp>p  s5    OOOSS	::;;<<OOOr!   c           
     n    g | ]1}t          t          t          |j                                      2S r   )r(  r  r  
startswith)r   r  	dec_tokens     r   r  z/RustCodePrinter.indent_code.<locals>.<listcomp>q  sE     ( ( ( S)<<==>> ( ( (r!   r   )r   r^  )r   r   r   
splitlinesrb  r`  r   )r   code
code_linestabincreasedecreaseprettylevelnr  r  r  s             @@r   r   zRustCodePrinter.indent_codec  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!   rA   )F)>r#   r$   r%   r&   printmethodlanguager
   r   r	   r   r   r   r   r   r   r   r   r   __annotations__r   r   r   r   r   r   r   r   r   r  r  r  r  r   r#  r&  r+  r4  r@  rB  rD  rH  rK  rN  rQ  rS  rU  rW  rZ  rf  rl  rq  rs  rv  rx  r~  r  r  r  r  r  r   r   r   s   @r   r   r     s        HHKH 	gL 	uv	M )-[-J ) )suu	O O ) )     !# 5 5 5 5  " " "  ; ; ;' ' 'B B B' ' '	% 	% 	%13 13 13f( ( ( ( (/ / / / / /* * *i i i          3 3 3

9 
9 
9L L L                      ! ! ! !   $ $ $6@ @ @m m m. . .A A A    I I IN N N  | | |    "      r!   r   )&r&   
__future__r   	functoolsr   r  typingr   sympy.codegen.astr   r   r   r	   r
   r   
sympy.corer   r   r   r   sympy.core.exprr   sympy.core.numbersr   #sympy.functions.elementary.integersr   r   sympy.printing.codeprinterr   sympy.printing.precedencer   r   r)   r   r   r   r   r   r   r!   r   <module>r     s  	 	B # " " " " "                             2 1 1 1 1 1 1 1 1 1 1 1             + + + + + + > > > > > > > > 2 2 2 2 2 2 0 0 0 0 0 0"    %       G    [!'  2 72 V2 
5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 FY2Z c2 2 2X3 3 3l2 2 2 2 2t 2 2 20m m m m mk m m m m mr!   