a
    kh_Q                     @  s  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 deZG dd deZ eefee fdZ!ddddd ddfdd ddfdd ddfdd ddfdd d d!fd"d d#d$fd%d d&d$fgd'd d(dfgd)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8dd9Z"g d:Z#G d;d< d<eZ$G d=d> d>eZ%dS )?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)reduceN)Any)float32float64int32realintegerbool_)SRationalFloatLambda)Exprequal_valued)ceilingfloor)CodePrinter)
PRECEDENCEc                   @  s   e Zd ZdZdd ZdS )float_floorzi
    Same as `sympy.floor`, but mimics the Rust behavior of returning a float rather than an integer
    c                 C  s   dS NF selfr   r   A/var/www/auris/lib/python3.9/site-packages/sympy/printing/rust.py_eval_is_integerE   s    zfloat_floor._eval_is_integerN__name__
__module____qualname____doc__r   r   r   r   r   r   A   s   r   c                   @  s   e Zd ZdZdd ZdS )float_ceilingzk
    Same as `sympy.ceiling`, but mimics the Rust behavior of returning a float rather than an integer
    c                 C  s   dS r   r   r   r   r   r   r   L   s    zfloat_ceiling._eval_is_integerNr   r   r   r   r   r"   H   s   r"   )r   r   r   ceilabsc                 C  s
   t |dS )Nr   baseexpr   r   r   <lambda>f       r)   Zrecip   c                 C  s
   t |dS )Ng      ?r   r&   r   r   r   r)   g   r*   sqrtc                 C  s
   t |dS )Ng      r   r&   r   r   r   r)   h   r*   zsqrt().recipc                 C  s   |t ddkS )N      )r   r&   r   r   r   r)   i   r*   Zcbrtc                 C  s
   t | dS )Nr+   r   r&   r   r   r   r)   j   r*   Zexp2r.   c                 C  s   |j S N
is_integerr&   r   r   r   r)   k   r*   Zpowir-   c                 C  s   |j  S r/   r0   r&   r   r   r   r)   l   r*   Zpowfc                 C  s   dS )NTr   )r(   r   r   r   r)   m   r*   r(   lnmaxminsincostanasinacosatanatan2sinhcoshtanhasinhacoshatanh)r   r"   ZAbsPowr(   logZMaxZMinr5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   r,   )4ZabstractasasyncawaitZbecomeZboxbreakconstcontinueZcrateZdoZdynelseenumexternfalsefinalfnforgenifimplinZletZloopmacromatchmodmoveZmutoverrideZprivZpubrefreturnZSelfr   ZstaticstructsuperZtraittruetrytypeZtypeofunsafeZunsizedZuseZvirtualwherewhileyieldc                      sH   e Zd ZdZdd fddZedd Zedd	 ZdddZ  Z	S )TypeCastz9
    The type casting operator of the Rust language.
    None)r[   c                   s@   t    |jo|tu| _|j| _| jr<t| dtd d  d S )N
precedenceZFunc
   )r]   __init__r1   r	   explicitZ_assumptionssetattrr   )r   exprtype_	__class__r   r   ri      s
    
zTypeCast.__init__c                 C  s
   | j d S )Nr   argsr   r   r   r   rl     s    zTypeCast.exprc                 C  s
   | j d S )Nr-   rp   r   r   r   r   rm     s    zTypeCast.type_Nc                 C  s   | j d j|dS )Nr   )order)rq   sort_key)r   rr   r   r   r   rs     s    zTypeCast.sort_key)N)
r   r   r    r!   ri   propertyrl   rm   rs   __classcell__r   r   rn   r   re      s   

re   c                      s  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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d  Z fd!d"Zdc fd$d%	Zd&d' Zd(d) Z dd fd+d,	Z!de fd-d.	Z"d/d0 Z#d1d2 Z$d3d4 Z%d5d6 Z&d7d8 Z'dfd9d:Z(dgd;d<Z)dhd=d>Z*did?d@Z+djdAdBZ,dkdCdDZ-dldEdFZ.dmdGdHZ/dIdJ Z0dKdL Z1dMdN Z2dOdP Z3dQdR Z4 fdSdTZ5dUdV Z6dWdX Z7dYdZ Z8d[d\ Z9d]d^ Z:d_d` Z;dadb Z<  Z=S )nRustCodePrinterz>A printer to convert SymPy expressions to strings of Rust codeZ
_rust_codeZRustZi32Zf32Zf64bool   T)Z	precisionuser_functionscontractdereferencezdict[str, Any]_default_settingsc                 C  sT   t | | tt| _|di }| j| t|dg | _tt| _t	| _	d S )Nry   r{   )
r   ri   dictknown_functionsgetupdateset_dereferencereserved_wordsfunction_overrides)r   settingsZ	userfuncsr   r   r   ri   (  s    

zRustCodePrinter.__init__c                 C  s   |d S )N   r   )r   pr   r   r   _rate_index_position1  s    z$RustCodePrinter._rate_index_positionc                 C  s   d| S )Nz%s;r   )r   Z
codestringr   r   r   _get_statement4  s    zRustCodePrinter._get_statementc                 C  s   d| S )Nz// %sr   )r   textr   r   r   _get_comment7  s    zRustCodePrinter._get_commentc                 C  s   | j | jt  }d|||f S )Nzconst %s: %s = %s;)type_mappingstype_aliasesr   )r   namevaluerm   r   r   r   _declare_number_const:  s    z%RustCodePrinter._declare_number_constc                 C  s
   |  |S r/   )indent_code)r   linesr   r   r   _format_code>  s    zRustCodePrinter._format_codec                   s    |j \}  fddt|D S )Nc                 3  s$   | ]}t  D ]}||fV  qqd S r/   )range).0ijcolsr   r   	<genexpr>C  r*   z;RustCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)shaper   )r   matrowsr   r   r   _traverse_matrix_indicesA  s    
z(RustCodePrinter._traverse_matrix_indicesc              
   C  sX   g }g }d}|D ]>}| || || |j| |jd d  | d q||fS )Nz#for %(var)s in %(start)s..%(end)s {r-   )varstartend})append_printlowerupper)r   indicesZ
open_linesZclose_linesZ	loopstartr   r   r   r   _get_loop_opening_endingE  s    

z(RustCodePrinter._get_loop_opening_endingc                 C  sB   t |jdkr d| | d S |jr4| j|ddS | |S d S )Nr-   ()T)_type)lenrq   r   	is_numberr   rl   r   r   r   _print_caller_varR  s
    z!RustCodePrinter._print_caller_varc                 C  sH  |j j| jv r| j|j j }d}d}t|tr6|}n|D ]\}}}||j r: qTq:|durD|dkrd| |jd |t|jdkr| |jdd dndd }n`|dkrd	| |jd |d
 }n<|dkrd	| |jd |d
 }nd|| |jdd }|S n6t	|dr:t|j
tr:| |j
|j S | |S d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   methodrq   r+   z%(var)s.%(method)s())r   r   r.   z%(func)s(%(args)s))funcrq   _imp_)r   r   r~   
isinstancestrrq   r   r   Z	stringifyhasattrr   r   r   _print_not_supported)r   rl   Z	cond_funcr   stylecondretr   r   r   _print_Function]  sD    


&


zRustCodePrinter._print_Functionc                   s@   t dd |jD }|r4ttj fdd|jD }t |S )Nc                 s  s   | ]}|j o|j V  qd S r/   Zis_realr1   r   argr   r   r   r     r*   z-RustCodePrinter._print_Mul.<locals>.<genexpr>c                 3  s$   | ]}|d kr  |n|V  qdS )r%   N_cast_to_floatr   r   r   r   r     r*   )anyrq   r   operatormulr]   
_print_Mul)r   rl   contains_floatsrn   r   r   r     s    zRustCodePrinter._print_MulNc                   sB   t dd |jD }|r4ttj fdd|jD }t ||S )Nc                 s  s   | ]}|j o|j V  qd S r/   r   r   r   r   r   r     r*   z-RustCodePrinter._print_Add.<locals>.<genexpr>c                 3  s   | ]}  |V  qd S r/   r   r   r   r   r   r     r*   )r   rq   r   r   addr]   
_print_Add)r   rl   rr   r   rn   r   r   r     s    zRustCodePrinter._print_Addc                 C  s:   |j jr0|jjs0t|t|j |j}| |S | |S r/   )r'   r1   r(   r`   r   r   r   r   r   r   r   
_print_Pow  s    
zRustCodePrinter._print_Powc                 C  s8   |j s| |jS | |jd| j| j|j    S d S )Nz as %s)rj   r   rl   r   r   rm   r   r   r   r   _print_TypeCast  s    zRustCodePrinter._print_TypeCastFc                   s0   t  |}|r(|d| j| jt    S |S d S Nz_%s)r]   _print_Floatr   r   r   r   rl   r   r   rn   r   r   r     s    zRustCodePrinter._print_Floatc                   s0   t  |}|r(|d| j| jt    S |S d S r   )r]   _print_Integerr   r   r	   r   rn   r   r   r     s    zRustCodePrinter._print_Integerc                 C  s4   t |jt |j }}| j| jt  }d|||f S )Nz
%d_%s/%d.0)intr   qr   r   r   )r   rl   r   r   Zfloat_suffixr   r   r   _print_Rational  s    zRustCodePrinter._print_Rationalc                 C  sn   |j jr|jjr |jjr:|j js:| |j }| |j}n|j }|j}| |}| |}|j}d|||S )Nz{} {} {})lhsr1   rhsr   r   Zrel_opformat)r   rl   r   r   lhs_coderhs_codeopr   r   r   _print_Relational  s     

z!RustCodePrinter._print_Relationalc                 C  s`   |j }tj}tj}tt|jD ]"}||j| | 7 }||| 9 }q d| |j	j
| |f S )N%s[%s])r   r   ZZeroZOnereversedr   Zrankr   r   r'   label)r   rl   dimselemoffsetr   r   r   r   _print_Indexed  s    zRustCodePrinter._print_Indexedc                 C  s   |j jS r/   )r   r   r   r   r   r   
_print_Idx  s    zRustCodePrinter._print_Idxc                 C  s   |j S r/   )r   r   r   r   r   _print_Dummy  s    zRustCodePrinter._print_Dummyc                 C  s   dS )NEr   r   rl   r   r   r   r   _print_Exp1  s    zRustCodePrinter._print_Exp1c                 C  s   dS )NPIr   r   r   r   r   	_print_Pi  s    zRustCodePrinter._print_Pic                 C  s   dS )NINFINITYr   r   r   r   r   _print_Infinity  s    zRustCodePrinter._print_Infinityc                 C  s   dS )NZNEG_INFINITYr   r   r   r   r   _print_NegativeInfinity  s    z'RustCodePrinter._print_NegativeInfinityc                 C  s   dS )Nr^   r   r   r   r   r   _print_BooleanTrue  s    z"RustCodePrinter._print_BooleanTruec                 C  s   dS )NrM   r   r   r   r   r   _print_BooleanFalse  s    z#RustCodePrinter._print_BooleanFalsec                 C  s   t | S r/   )r   r   r   r   r   r   _print_bool  s    zRustCodePrinter._print_boolc                 C  s   dS )NZNANr   r   r   r   r   
_print_NaN  s    zRustCodePrinter._print_NaNc                 C  s   |j d jdkrtdg }t|j D ]\}\}}|dkrP|d| |  nF|t|j d kr||dkr||d  d7  < n|d  d| | 7  < | |}|| |d	 q&| jd
 rd|S 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 
)	rq   r   
ValueError	enumerater   r   r   	_settingsjoin)r   rl   r   r   ecZcode0r   r   r   _print_Piecewise  s    



z RustCodePrinter._print_Piecewisec                 C  s    ddl m} | |j|ddS )Nr   )	PiecewiseF)deep)Zsympy.functionsr   r   rewrite)r   rl   r   r   r   r   
_print_ITE  s    zRustCodePrinter._print_ITEc                   s2   |j dkr&dd fdd|D  S tdd S )Nr-   z[%s]r   c                 3  s   | ]}  |V  qd S r/   )r   )r   ar   r   r   r     r*   z4RustCodePrinter._print_MatrixBase.<locals>.<genexpr>zLFull Matrix Support in Rust need Crates (https://crates.io/keywords/matrix).)r   r   r   )r   Ar   r   r   _print_MatrixBase  s    
z!RustCodePrinter._print_MatrixBasec                 C  s
   |  |S r/   )r   )r   r   r   r   r   _print_SparseRepMatrix  s    z&RustCodePrinter._print_SparseRepMatrixc                 C  s"   d|j |j|j|j jd   f S )Nr   r-   )parentr   r   r   r   r   r   r   _print_MatrixElement  s    z$RustCodePrinter._print_MatrixElementc                   s&   t  |}|| jv rd| S |S d S )Nz(*%s))r]   _print_Symbolr   )r   rl   r   rn   r   r   r    s    
zRustCodePrinter._print_Symbolc                 C  sl   ddl m} |j}|j}| jd rB||s6||rB| ||S | |}| |}| d||f S d S )Nr   )IndexedBaserz   z%s = %s)	Zsympy.tensor.indexedr  r   r   r   ZhasZ_doprint_loopsr   r   )r   rl   r  r   r   r   r   r   r   r   _print_Assignment'  s    

z!RustCodePrinter._print_Assignmentc                 C  s   |  |jd }d||f S )Nr   z/(if (%s == 0.0) { 0.0 } else { (%s).signum() }))r   rq   )r   rl   r   r   r   r   _print_sign5  s    zRustCodePrinter._print_signc                 C  s"   |j st|tS |jrt|S |S r/   )r   re   r   r1   r   r   r   r   r   r   9  s
    
zRustCodePrinter._cast_to_floatc                 C  s$   || 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   getattrr   )r   r   r   r   r   
_can_print@  s    zRustCodePrinter._can_printc                 C  sB   t  }t|tr>|jr"||j |jD ]}|| |}q(|S r/   )	r   r   r   Zis_Functionr   r   rq   union_collect_functions)r   rl   Z	functionsr   r   r   r   r	  I  s    

z"RustCodePrinter._collect_functionsc                   s^   t |ts|S  |} fdd j D }|D ]$}||jd\}}|r4||}q4|S )Nc                   s>   i | ]6\}\}}  |rt fd d|D r|||fqS )c                 3  s   | ]}  |V  qd S r/   )r  )r   fr   r   r   r   [  r*   zFRustCodePrinter._rewrite_known_functions.<locals>.<dictcomp>.<genexpr>)r  all)r   r   target_fZrequired_fsr   r   r   
<dictcomp>W  s   

z<RustCodePrinter._rewrite_known_functions.<locals>.<dictcomp>)NN)r   r   r	  Z_rewriteable_functionsitemsr   r   r   )r   rl   Zexpression_functionsZrewriteable_functionsr   r  _r   r   r   _rewrite_known_functionsR  s    


z(RustCodePrinter._rewrite_known_functionsc           
        s   t |tr$| |d}d|S d}dd dd |D }fdd|D } fd	d|D }g }d
}t|D ]J\}}	|	dv r||	 qr||| 8 }|d|| |	f  ||| 7 }qr|S )z0Accepts a string of code or a list of code linesTr   z    ){r   z{
z(
)r   r   c                 S  s   g | ]}| d qS )z 	)lstripr   liner   r   r   
<listcomp>n  r*   z/RustCodePrinter.indent_code.<locals>.<listcomp>c                   s    g | ]}t tt|j qS r   )r   r   mapendswithr  )	inc_tokenr   r   r  p  r*   c                   s    g | ]}t tt|j qS r   )r   r   r  
startswithr  )	dec_tokenr   r   r  q  s   r   )r   r   z%s%s)r   r   r   
splitlinesr   r   r   )
r   codeZ
code_linestabZincreaseZdecreaseprettylevelnr  r   )r  r  r   r   c  s*    



zRustCodePrinter.indent_code)N)F)F)F)F)F)F)F)F)F)F)>r   r   r    r!   Zprintmethodlanguager	   r   r   r   r   r   r
   r   r}   r   r|   r   __annotations__ri   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   r   r   r   r  r  r  r  r   r  r	  r  r   ru   r   r   rn   r   rv     sv   

	3








			rv   )&r!   
__future__r   	functoolsr   r   typingr   Zsympy.codegen.astr   r   r   r   r	   r
   Z
sympy.corer   r   r   r   Zsympy.core.exprr   Zsympy.core.numbersr   Z#sympy.functions.elementary.integersr   r   Zsympy.printing.codeprinterr   Zsympy.printing.precedencer   r   r"   r   r~   r   re   rv   r   r   r   r   <module>   sb   ! 	l6