B
    }[nP                 @   s   d dl mZm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 d dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ G dd deZ G dd de!Z"G dd deZ#dS )    )print_functiondivision)wraps)AddMulPowSsympifyFloat)Basic)Tuple)default_sort_keystring_types)Lambda)_keep_coeff)Symbol)
StrPrinter)
precedence)
Assignmentc               @   s    e Zd ZdZdd Zdd ZdS )requiresz: Decorator for registering requirements on print methods. c             K   s
   || _ d S )N)_req)selfkwargs r   9lib/python3.7/site-packages/sympy/printing/codeprinter.py__init__   s    zrequires.__init__c                s    fdd}t  |S )Nc                s8   x&j  D ]\}}t| || qW  | f||S )N)r   itemsgetattrupdate)Zself_argsr   kv)methodr   r   r   _method_wrapper   s    z*requires.__call__.<locals>._method_wrapper)r   )r   r"   r#   r   )r"   r   r   __call__   s    zrequires.__call__N)__name__
__module____qualname____doc__r   r$   r   r   r   r   r      s   r   c               @   s   e Zd ZdZdS )AssignmentErrorzA
    Raised if an assignment variable for a loop is missing.
    N)r%   r&   r'   r(   r   r   r   r   r)       s   r)   c                   s  e Zd ZdZddddZdddd	d
dddZdV fdd	ZdWddZdXd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d$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Z fd6d7Zd8d9 ZeZd:d; Zd<d= Zd>d? Z d@dA Z!dBdC Z"dDdE Z#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(dPdQ Z)dRdS Z*dTdU Z+e+Z,e+Z-e+Z.e+Z/e+Z0e+Z1e+Z2e+Z3e+Z4e+Z5e+Z6e+Z7e+Z8e+Z9e+Z:e+Z;e+Z<e+Z=e+Z>e+Z?e+Z@e+ZAe+ZBe+ZCe+ZDe+ZEe+ZFe+ZGe+ZHe+ZI  ZJS )YCodePrinterz6
    The base class for code-printing subclasses.
    z&&z||!)andornotNautoF_T)orderZ	full_precerror_on_reservedreserved_word_suffixhumaninlineallow_unknown_functionsc                s(   t t| j|d t| ds$t | _d S )N)settingsreserved_words)superr*   r   hasattrsetr8   )r   r7   )	__class__r   r   r   <   s    
zCodePrinter.__init__c       
         s  ddl m} t|tr8|jr.||f|j }qdt|}n,t|ttdfsdt	d
t jt||rtt||}nt|}t  _t  _ | } jd rLg }t jdkr| d
 j x,t jtdD ]}| t|j qW x.t jtdD ]\}}| || qW || } |}d|}n4 |}t fd	d
 jD }	|	 jd|f} ` `|S )aO  
        Print the expression as code.

        Parameters
        ----------
        expr : Expression
            The expression to be printed.

        assign_to : Symbol, MatrixSymbol, or string (optional)
            If provided, the printed code will set the expression to a
            variable with name ``assign_to``.
        r   )MatrixSymbolNz'{0} cannot assign to object of type {1}r4   zNot supported in {0}:)key
c                s   g | ]\}}|  |fqS r   )_print).0r    r!   )r   r   r   
<listcomp>v   s    z'CodePrinter.doprint.<locals>.<listcomp>)"sympy.matrices.expressions.matexprr=   
isinstancer   Z	is_Matrixshaper   r   type	TypeErrorformatr%   r   r	   r;   _not_supported_number_symbolsr@   
splitlines	_settingslenappend_get_commentZlanguagesortedstr_declare_number_const_format_codejoin)
r   expr	assign_tor=   linesZ
frontlinesnamevalueresultZnum_symsr   )r   r   doprintB   s@    



zCodePrinter.doprintc          	   C   s  | j ddr0ddlm} | ||}||}ng }d |fi}| |\}}d |krjt| t|d   }nt| d}| 	|}	g }
||	kr|

| |d k	r| d|	|f }|
| |

| x|D ]}t|tr| ||}| |\}}x|| D ]}||kr:dd || D dd || D ks:td	q|d krLtd
||r`td|

| |

| d|	t| || f }|
| | |

| |

| qW qW d|
S )NcontractTr   )get_contraction_structurez%s = %sc             S   s   g | ]}t | qS r   )listkeys)rA   fr   r   r   rB      s    z.CodePrinter._doprint_loops.<locals>.<listcomp>c             S   s   g | ]
}d gqS )Nr   )rA   r`   r   r   r   rB      s    z0FIXME: no support for contractions in factor yetz"need assignment variable for loopszZFIXME: lhs present in rhs,                                this is undefined in CodePrinterr?   )rL   getsympy.tensorr]   _get_expression_indices_get_loop_opening_endingr   r[   r   r@   extend_get_statementrN   rD   tuple_sort_optimizedNotImplementedErrorr)   has
ValueErrorrT   )r   rU   rV   r]   indicesZdummiesZopenloopZ	closelooptextZlhs_printedrW   dZ
openloop_dZcloseloop_dZtermr   r   r   _doprint_loops|   sT    












zCodePrinter._doprint_loopsc             C   sP   ddl m} ||\}}||\}}|r0|s0|}||krDtd| | ||S )Nr   )get_indicesz2lhs indices must match non-dummy rhs indices in %s)rb   rp   rk   rh   )r   rU   rV   rp   ZrindsZjunkZlindsr   r   r   rc      s    z#CodePrinter._get_expression_indicesc       	   
      s   ddl m} |sg S i  x|D ]}d |< qW ||}xT|D ]L}xFt|jD ]8\}}y |  | |7  < W qN tk
r   Y qNX qNW q>W t| fdddS )Nr   )Indexedc                s    |  S )Nr   )x)score_tabler   r   <lambda>   s    z-CodePrinter._sort_optimized.<locals>.<lambda>)r>   )sympy.tensor.indexedrq   Zatoms	enumeraterl   _rate_index_positionKeyErrorrP   )	r   rl   rU   rq   iZarraysZarrpZindr   )rs   r   rh      s    


zCodePrinter._sort_optimizedc             C   s   t ddS )zfunction to calculate score based on position among indices

        This method is used to sort loops in an optimized order, see
        CodePrinter._sort_optimized()
        z=This function must be implemented by subclass of CodePrinter.N)ri   )r   rz   r   r   r   rw      s    z CodePrinter._rate_index_positionc             C   s   t ddS )z1Formats a codestring with the proper line ending.z=This function must be implemented by subclass of CodePrinter.N)ri   )r   Z
codestringr   r   r   rf      s    zCodePrinter._get_statementc             C   s   t ddS )z#Formats a text string as a comment.z=This function must be implemented by subclass of CodePrinter.N)ri   )r   rm   r   r   r   rO      s    zCodePrinter._get_commentc             C   s   t ddS )z3Declare a numeric constant at the top of a functionz=This function must be implemented by subclass of CodePrinter.N)ri   )r   rX   rY   r   r   r   rR     s    z!CodePrinter._declare_number_constc             C   s   t ddS )z~Take in a list of lines of code, and format them accordingly.

        This may include indenting, wrapping long lines, etc...z=This function must be implemented by subclass of CodePrinter.N)ri   )r   rW   r   r   r   rS     s    zCodePrinter._format_codec             C   s   t ddS )zOReturns a tuple (open_lines, close_lines) containing lists
        of codelinesz=This function must be implemented by subclass of CodePrinter.N)ri   )r   rl   r   r   r   rd     s    z$CodePrinter._get_loop_opening_endingc             C   s*   |j drd|j  S d|j |jf S d S )NZDummy_r0   z%s_%d)rX   
startswithZdummy_index)r   rU   r   r   r   _print_Dummy  s    
zCodePrinter._print_Dummyc                s   d  fdd|jD S )Nr?   c                s   g | ]}  |qS r   )r@   )rA   ry   )r   r   r   rB     s    z0CodePrinter._print_CodeBlock.<locals>.<listcomp>)rT   r   )r   rU   r   )r   r   _print_CodeBlock  s    zCodePrinter._print_CodeBlockc             C   s   t |S )N)rQ   )r   stringr   r   r   _print_String  s    zCodePrinter._print_Stringc             C   s
   d|j  S )Nz"%s")rm   )r   argr   r   r   _print_QuotedString!  s    zCodePrinter._print_QuotedStringc             C   s   |  t|S )N)rO   rQ   )r   r~   r   r   r   _print_Comment$  s    zCodePrinter._print_Commentc             C   sF  ddl m} ddlm} ddlm} |j}|j}t|j|rg }g }x,|j	D ]"\}	}
|
t||	 |
|
 qLW |t|| }| |S t||rg }xD| |D ]6\}}t|||f |||f }| |}|
| qW d|S | jddr||s||r| ||S | |}| |}| d||f S d S )	Nr   )	Piecewise)r=   )IndexedBaser?   r\   Fz%s = %s)Z$sympy.functions.elementary.piecewiser   rC   r=   ru   r   lhsrhsrD   r   rN   r   zipr@   Z_traverse_matrix_indicesrT   rL   ra   rj   ro   rf   )r   rU   r   r=   r   r   r   ZexpressionsZ
conditionsecZtemprW   ry   jZcode0lhs_coderhs_coder   r   r   _print_Assignment'  s4    





zCodePrinter._print_Assignmentc                s>     |j}  |j} djt fdd||j|g S )Nz{0} {1} {2}c                s
     | S )N)r@   )r   )r   r   r   rt   O  s    z8CodePrinter._print_AugmentedAssignment.<locals>.<lambda>)r@   r   r   rf   rH   mapop)r   rU   r   r   r   )r   r   _print_AugmentedAssignmentK  s
    z&CodePrinter._print_AugmentedAssignmentc                s$   d|j dt fdd|jf S )Nz%s(%s)z, c                s
     | S )N)r@   )r   )r   r   r   rt   U  s    z1CodePrinter._print_FunctionCall.<locals>.<lambda>)rX   rT   r   Zfunction_args)r   rU   r   )r   r   _print_FunctionCallR  s    zCodePrinter._print_FunctionCallc             C   s   |  |jS )N)r@   Zsymbol)r   rU   r   r   r   _print_VariableX  s    zCodePrinter._print_Variablec             C   s   |j \}| | |S )N)r   rf   r@   )r   rU   r   r   r   r   _print_Statement[  s    zCodePrinter._print_Statementc                sL   t t| |}|| jkrD| jd r6d}t|||| jd  S |S d S )Nr2   zVThis expression includes the symbol "{}" which is a reserved keyword in this language.r3   )r9   r*   _print_Symbolr8   rL   rk   rH   )r   rU   rX   msg)r<   r   r   r   _  s    

zCodePrinter._print_Symbolc                sB  |j j jkr̈ j|j j }d }t|tr0|}nx|D ]\}}||j r6P q6W |d k	ry| f fdd|jD  S  tk
r   y| fdd|jD  S  tk
r   d| |jdf S X Y nX nrt|d rt|j	t
 r |j	|j S |jr4 jddr4d |j dt j|jf S  |S d S )	Nc                s   g | ]}  |d qS )r   )parenthesize)rA   item)r   r   r   rB   x  s    z/CodePrinter._print_Function.<locals>.<listcomp>c                s   g | ]}  |d qS )r   )r   )rA   r   )r   r   r   rB   {  s    z%s(%s)z, _imp_r6   F)funcr%   Zknown_functionsrD   rQ   r   rG   Z	stringifyr:   r   r   r@   Zis_FunctionrL   ra   rT   r   _print_not_supported)r   rU   Z	cond_funcr   Zcondr   )r   r   _print_Functionl  s*    

 $zCodePrinter._print_Functionc             C   sT   | j ddr(| t|| j d S | j|t|| j d f t|S d S )Nr5   FZ	precision)rL   ra   r@   r
   ZevalfrJ   addrQ   )r   rU   r   r   r   _print_NumberSymbol  s
    zCodePrinter._print_NumberSymbolc             C   s
   |  |S )N)r   )r   rU   r   r   r   _print_Catalan  s    zCodePrinter._print_Catalanc             C   s
   |  |S )N)r   )r   rU   r   r   r   _print_EulerGamma  s    zCodePrinter._print_EulerGammac             C   s
   |  |S )N)r   )r   rU   r   r   r   _print_GoldenRatio  s    zCodePrinter._print_GoldenRatioc             C   s
   |  |S )N)r   )r   rU   r   r   r   _print_TribonacciConstant  s    z%CodePrinter._print_TribonacciConstantc             C   s
   |  |S )N)r   )r   rU   r   r   r   _print_Exp1  s    zCodePrinter._print_Exp1c             C   s
   |  |S )N)r   )r   rU   r   r   r   	_print_Pi  s    zCodePrinter._print_Pic                s6   t | djd   fddt|jtdD S )Nz %s r,   c             3   s   | ]} | V  qd S )N)r   )rA   a)PRECr   r   r   	<genexpr>  s   z)CodePrinter._print_And.<locals>.<genexpr>)r>   )r   
_operatorsrT   rP   r   r   )r   rU   r   )r   r   r   
_print_And  s    zCodePrinter._print_Andc                s6   t | djd   fddt|jtdD S )Nz %s r-   c             3   s   | ]} | V  qd S )N)r   )rA   r   )r   r   r   r   r     s   z(CodePrinter._print_Or.<locals>.<genexpr>)r>   )r   r   rT   rP   r   r   )r   rU   r   )r   r   r   	_print_Or  s    zCodePrinter._print_Orc                sH   j dd kr|S t| dj d   fdd|jD S )Nxorz %s c             3   s   | ]} | V  qd S )N)r   )rA   r   )r   r   r   r   r     s   z)CodePrinter._print_Xor.<locals>.<genexpr>)r   ra   r   r   rT   r   )r   rU   r   )r   r   r   
_print_Xor  s
    
zCodePrinter._print_Xorc                sH   j dd kr|S t| dj d   fdd|jD S )NZ
equivalentz %s c             3   s   | ]} | V  qd S )N)r   )rA   r   )r   r   r   r   r     s   z0CodePrinter._print_Equivalent.<locals>.<genexpr>)r   ra   r   r   rT   r   )r   rU   r   )r   r   r   _print_Equivalent  s
    
zCodePrinter._print_Equivalentc             C   s$   t |}| jd | |jd | S )Nr.   r   )r   r   r   r   )r   rU   r   r   r   r   
_print_Not  s    zCodePrinter._print_Notc                s  t | | \}}|dk r.t| |}d}nd}g }g }g }jdkrR| }n
t|}x|D ]}	|	jr|	jr|	j	j
r|	j	jr|	j	dkr|t|	j|	j	 dd qt|	jd jdkrt|	jtr||	 |t|	j|	j	  qb||	 qbW |ptjg} fd	d
|D }
 fdd
|D }x:|D ]2}	|	j|kr4d|||	j  |||	j< q4W t|dkr|d|
 S t|dkr|d|
 d |d  S |d|
 dd|  S d S )Nr   - )oldZnoneF)Zevaluate   c                s   g | ]} | qS r   )r   )rA   rr   )precr   r   r   rB     s    z*CodePrinter._print_Mul.<locals>.<listcomp>c                s   g | ]} | qS r   )r   )rA   rr   )r   r   r   r   rB     s    z(%s)*/z/(%s))r   Zas_coeff_Mulr   r1   Zas_ordered_factorsr   Z	make_argsZis_commutativeZis_PowZexpZis_RationalZis_negativerN   r   baserM   r   rD   r   ZOneindexrT   )r   rU   r   r   Zsignr   bZ	pow_parenr   r   Za_strZb_strr   )r   r   r   
_print_Mul  s>    




 

&zCodePrinter._print_Mulc             C   s   | j | | |S )N)rI   r   ZemptyPrinter)r   rU   r   r   r   r     s    z CodePrinter._print_not_supported)N)N)N)Kr%   r&   r'   r(   r   Z_default_settingsr   r[   ro   rc   rh   rw   rf   rO   rR   rS   rd   r|   r}   r   r   r   r   r   r   r   r   r   r   Z_print_Exprr   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_BasicZ_print_ComplexInfinityZ_print_DerivativeZ_print_ExprCondPairZ_print_GeometryEntityZ_print_InfinityZ_print_IntegralZ_print_IntervalZ_print_AccumulationBoundsZ_print_LimitZ_print_MatrixZ_print_ImmutableMatrixZ_print_ImmutableDenseMatrixZ_print_MutableDenseMatrixZ_print_MatrixBaseZ_print_DeferredVectorZ
_print_NaNZ_print_NegativeInfinityZ_print_NormalZ_print_OrderZ
_print_PDFZ_print_RootOfZ_print_RootsOfZ_print_RootSumZ_print_SampleZ_print_SparseMatrixZ_print_UniformZ_print_UnitZ_print_WildZ_print_WildFunction__classcell__r   r   )r<   r   r*   '   s   
:
O	$
3r*   N)$Z
__future__r   r   	functoolsr   Z
sympy.corer   r   r   r   r	   r
   Zsympy.core.basicr   Zsympy.core.containersr   Zsympy.core.compatibilityr   r   Zsympy.core.functionr   Zsympy.core.mulr   Zsympy.core.symbolr   Zsympy.printing.strr   Zsympy.printing.precedencer   Zsympy.codegen.astr   objectr   	Exceptionr)   r*   r   r   r   r   <module>   s    