
~9\c        4   @  s  d  Z  d d l m Z m Z d d l m Z m Z m Z m Z m	 Z	 d d l
 m Z m Z d d l m Z m Z d d l m Z i* d d 6d	 d 6d
 d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d   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+ 6d,   d- d f g d- 6d. d/ 6d/ d 6d0 d 6d1 d 6d2 d 6d3 d 6d4 d5 6d6 d7 6d8 d 6d9 d9 6d: d: 6d; d; 6d< d< 6d= d= 6d> d> 6d? d? 6d@ d 6dA d 6dB d 6dC dC 6dD dD 6dE dE 6dF dF 6dG dG 6dH dH 6Z dI dJ dK dL dM dN dO dP dQ dR dS dT dU dV dW dX dY dZ d[ d\ d] d^ d_ d` da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz d{ d| g4 Z d} e f d~     YZ e d  Z d   Z d S(   s  
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.

i(   t   print_functiont   division(   t   St   numberst   Rationalt   Floatt   Lambda(   t   string_typest   range(   t   CodePrintert
   Assignment(   t
   precedencet   is_nant    t   is_infinitet	   is_finitet	   is_normalt   classifyt   floort   ceilt   ceilingt   roundt   trunct   fractt   abst   Abst   signumt   signt   is_sign_positivet   is_sign_negativet   mul_addc         C  s   | t  j k S(   N(   R   t   One(   t   baset   exp(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   <lambda>I   R   t   recipi   c         C  s   | t  j k S(   N(   R   t   Half(   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   J   R   t   sqrtc         C  s   | t  j k S(   N(   R   R$   (   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   K   R   s   sqrt().recipc         C  s   | t  d d  k S(   Ni   i   (   R   (   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   L   R   t   cbrtc         C  s   |  t  j d k S(   Ni   (   R   R   (   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   M   R   t   exp2i   c         C  s   | j  S(   N(   t
   is_integer(   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   N   R   t   powii   c         C  s   | j  S(   N(   R(   (   R    R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   O   R   t   powft   Powc         C  s   t  S(   N(   t   True(   R!   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR"   P   R   R!   t   lnt   logt   log2t   log10t
   to_degreest
   to_radianst   maxt   Maxt   mint   Mint   hypott   sint   cost   tant   asint   acost   atant   atan2t   sin_cost   exp_m1t   ln_1pt   sinht   cosht   tanht   asinht   acosht   atanht   abstractt   alignoft   ast   becomet   boxt   breakt   constt   continuet   cratet   dot   elset   enumt   externt   falset   finalt   fnt   fort   ift   implt   int   lett   loopt   macrot   matcht   modt   movet   mutt   offsetoft   overridet   privt   proct   pubt   puret   reft   returnt   Selft   selft   sizeoft   statict   structt   supert   traitt   truet   typet   typeoft   unsafet   unsizedt   uset   virtualt   wheret   whilet   yieldt   RustCodePrinterc           B  s  e  Z d  Z d Z d Z i
 d1 d 6d d 6d d 6i  d 6e d	 6e d
 6e   d 6e d 6d d 6e d 6Z	 i  d  Z
 d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z e d  Z e d  Z d   Z d   Z d   Z d    Z e d!  Z e d"  Z e d#  Z e d$  Z e d%  Z e d&  Z  e d'  Z! e d(  Z" d)   Z# d*   Z$ d+   Z% d,   Z& d-   Z' e& Z% Z' Z( Z) Z* Z+ d.   Z, d/   Z- d0   Z. RS(2   s?   A printer to convert python expressions to strings of Rust codet
   _rust_codet   Rustt   ordert   autot	   full_preci   t	   precisiont   user_functionst   humant   contractt   dereferencet   error_on_reservedt   _t   reserved_word_suffixt   inlinec         C  so   t  j |  |  t t  |  _ | j d i   } |  j j |  t | j d g    |  _ t t  |  _ d  S(   NR   R   (	   R	   t   __init__t   dictt   known_functionst   gett   updatet   sett   _dereferencet   reserved_words(   Rl   t   settingst	   userfuncs(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR      s    c         C  s   | d S(   Ni   (    (   Rl   t   p(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _rate_index_position   s    c         C  s   d | S(   Ns   %s;(    (   Rl   t
   codestring(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _get_statement   s    c         C  s   d | S(   Ns   // %s(    (   Rl   t   text(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _get_comment   s    c         C  s   d | | f S(   Ns   const %s: f64 = %s;(    (   Rl   t   namet   value(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _declare_number_const   s    c         C  s   |  j  |  S(   N(   t   indent_code(   Rl   t   lines(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _format_code   s    c           s)   | j  \ }     f d   t |  D S(   Nc         3  s.   |  ]$ } t     D] } | | f Vq q d  S(   N(   R   (   t   .0t   it   j(   t   cols(    s2   lib/python2.7/site-packages/sympy/printing/rust.pys	   <genexpr>  s    (   t   shapeR   (   Rl   t   matt   rows(    (   R   s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _traverse_matrix_indices  s    c         C  s   g  } g  } d } xf | D]^ } | j  | i |  j |  d 6|  j | j  d 6|  j | j d  d 6 | j  d  q W| | f S(   Ns#   for %(var)s in %(start)s..%(end)s {t   vart   starti   t   endt   }(   t   appendt   _printt   lowert   upper(   Rl   t   indicest
   open_linest   close_linest	   loopstartR   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _get_loop_opening_ending  s    c         C  sW   t  | j  d k r* d |  j |  d S| j rF |  j | d t S|  j |  Sd  S(   Ni   t   (t   )t   _type(   t   lent   argsR   t	   is_numberR,   (   Rl   t   expr(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_caller_var  s
    	c         C  s  | j  j |  j k r|  j | j  j } d } d } t | t  rL | } n- x* | D]" \ } } } | | j   rS PqS qS W| d k	 r| d k r d i |  j | j d  d 6| d 6t | j  d k r |  j	 | j d d  n d d 6} n | d	 k r(d
 i |  j | j d  d 6| d 6} n^ | d k r_d
 i |  j | j d  d 6| d 6} n' d i | d 6|  j	 | j d  d 6} | SnG t
 | d  rt | j t  r|  j | j | j    S|  j |  Sd S(   s<  
        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
        i   s   %(var)s.%(method)s(%(args)s)i    R   t   methods   , R   R   i   s   %(var)s.%(method)s()i   s   %(func)s(%(args)s)t   funct   _imp_N(   R   t   __name__R   t   Nonet
   isinstanceR   R   R   R   t	   stringifyt   hasattrR   R   R   t   _print_not_supported(   Rl   R   t	   cond_funcR   t   stylet   condt   ret(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Function  s<    	<!c         C  sT   | j  j rG | j j rG t |  t | j   | j  } |  j |  S|  j |  S(   N(   R    R(   R!   Rs   R   R   R   (   Rl   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt
   _print_PowR  s    !c         C  s.   t  t |   j |  } | r& | d S| Sd  S(   Nt   _f64(   Rp   R|   t   _print_Float(   Rl   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR   X  s    c         C  s.   t  t |   j |  } | r& | d S| Sd  S(   Nt   _i32(   Rp   R|   t   _print_Integer(   Rl   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR   _  s    c         C  s-   t  | j  t  | j  } } d | | f S(   Ns   %d_f64/%d.0(   t   intR   t   q(   Rl   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Rationalf  s    c         C  s   | j  } t j } t j } x@ t t | j   D]) } | | j | | 7} | | | 9} q1 Wd |  j | j	 j
  |  j |  f S(   Ns   %s[%s](   R   R   t   ZeroR   t   reversedR   t   rankR   R   R    t   label(   Rl   R   t   dimst   elemt   offsetR   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Indexedj  s    			c         C  s
   | j  j S(   N(   R   R   (   Rl   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt
   _print_Idxt  s    c         C  s   | j  S(   N(   R   (   Rl   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Dummyw  s    c         C  s   d S(   Nt   E(    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Exp1z  s    c         C  s   d S(   Nt   PI(    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt	   _print_Pi}  s    c         C  s   d S(   Nt   INFINITY(    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Infinity  s    c         C  s   d S(   Nt   NEG_INFINITY(    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_NegativeInfinity  s    c         C  s   d S(   NRr   (    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_BooleanTrue  s    c         C  s   d S(   NRU   (    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_BooleanFalse  s    c         C  s   t  |  j   S(   N(   t   strR   (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_bool  s    c         C  s   d S(   Nt   NAN(    (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt
   _print_NaN  s    c         C  s#  | j  d j t k r% t d   n  g  } x t | j   D] \ } \ } } | d k rv | j d |  j |   nU | t | j   d k r | t k r | d c d 7<n | d c d |  j |  7<|  j |  } | j |  | j d  q; W|  j d	 rd
 j	 |  Sd j	 |  Sd  S(   Nis   All 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.i    s	   if (%s) {i   s    else {s    else if (%s) {R   R   t    s   
(
   R   R   R,   t
   ValueErrort	   enumerateR   R   R   t	   _settingst   join(   Rl   R   R   R   t   et   ct   code0(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Piecewise  s    "%c         C  sM   d d l  m } | | j d | j d f | j d t f  } |  j |  S(   Ni(   t	   Piecewisei   i    i   (   t   sympy.functionsR   R   R,   R   (   Rl   R   R   t
   _piecewise(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt
   _print_ITE  s    0c         C  s)   d | j  | j | j | j  j d f S(   Ns   %s[%s]i   (   t   parentR   R   R   (   Rl   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Matrix  s    	c           s@   | j  d k r0 d d j   f d   | D  St d   d  S(   Ni   s   [%s]s   , c         3  s   |  ] }   j  |  Vq d  S(   N(   R   (   R   t   a(   Rl   (    s2   lib/python2.7/site-packages/sympy/printing/rust.pys	   <genexpr>  s    sL   Full Matrix Support in Rust need Crates (https://crates.io/keywords/matrix).(   R   R   R   (   Rl   t   A(    (   Rl   s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_MatrixBase  s    !c         C  s)   d | j  | j | j | j  j d f S(   Ns   %s[%s]i   (   R   R   R   R   (   Rl   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_MatrixElement  s    	c         C  s7   t  t |   j |  } | |  j k r/ d | S| Sd  S(   Ns   (*%s)(   Rp   R|   t   _print_SymbolR   (   Rl   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR     s    c         C  s   d d l  m } | j } | j } |  j d r] | j |  sM | j |  r] |  j | |  S|  j |  } |  j |  } |  j d | | f  Sd  S(   Ni(   t   IndexedBaseR   s   %s = %s(	   t   sympy.tensor.indexedR   t   lhst   rhsR   t   hast   _doprint_loopsR   R   (   Rl   R   R   R  R  t   lhs_codet   rhs_code(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   _print_Assignment  s    		c         C  sY  t  | t  r4 |  j | j t   } d j |  Sd } d } d } g  | D] } | j d	  ^ qM } g  | D]$ } t t t	 | j
 |    ^ qo } g  | D]$ } t t t	 | j |    ^ q } g  }	 d
 }
 x| t |  D]n \ } } | d k s| d k r|	 j |  q n  |
 | | 8}
 |	 j d | |
 | f  |
 | | 7}
 q W|	 S(   s0   Accepts a string of code or a list of code linesR   s       t   {R   s   {
s   (
R   R   s    	i    s   
s   %s%s(   R	  R   s   {
s   (
(   R   R   (   R   R   R   t
   splitlinesR,   R   t   lstripR   t   anyt   mapt   endswitht
   startswithR   R   (   Rl   t   codet
   code_linest   tabt	   inc_tokent	   dec_tokent   linet   increaset   decreaset   prettyt   levelt   n(    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR     s(    "1.N(/   R   t
   __module__t   __doc__t   printmethodt   languageR   R,   R   t   Falset   _default_settingsR   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   t   _print_DenseMatrixt   _print_MutableDenseMatrixt   _print_ImmutableMatrixt   _print_ImmutableDenseMatrixR   R  R   (    (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyR|      s`   

									3			
										c         K  s   t  |  j |  |  S(   s  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()];
    (   R|   t   doprint(   R   t	   assign_toR   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt	   rust_code  s    mc         K  s   t  t |  |   d S(   s3   Prints Rust representation of the given expression.N(   t   printR'  (   R   R   (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   print_rust_codeo  s    N(   R  t
   __future__R    R   t
   sympy.coreR   R   R   R   R   t   sympy.core.compatibilityR   R   t   sympy.printing.codeprinterR	   R
   t   sympy.printing.precedenceR   R   R   R|   R   R'  R)  (    (    (    s2   lib/python2.7/site-packages/sympy/printing/rust.pyt   <module>
   s   (
;	 &p