U
    ZÊ¹j#p  ã                   @  sŒ  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	Z	ddl
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ dd	l,m-Z-m.Z.m/Z/m0Z0m1Z1 dd
l2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z=m>Z> ddl?m@Z@ ddl:mAZAmBZB ddddddddddddddd d!d"d#œZCG d$d%„ d%e;ƒZDdS )&ar  
Fortran code printer

The FCodePrinter converts single SymPy expressions into single Fortran
expressions, using the functions defined in the Fortran 77 standard where
possible. Some useful pointers to Fortran can be found on wikipedia:

https://en.wikipedia.org/wiki/Fortran

Most of the code below is based on the "Professional Programmer's Guide to
Fortran77" by Clive G. Page:

https://www.star.le.ac.uk/~cgp/prof77.html

Fortran is a case-insensitive language. This might cause trouble because
SymPy is case sensitive. So, fcode adds underscores to variable names when
it is necessary to make them different for Fortran.
é    )Úannotations)ÚAny)Údefaultdict)ÚchainN)Ú
AssignmentÚDeclarationÚPointerÚvalue_constÚfloat32Úfloat64Úfloat80Ú	complex64Ú
complex128Úint8Úint16Úint32Úint64ÚintcÚrealÚintegerÚbool_Úcomplex_ÚnoneÚstderrÚstdout)ÚallocatableÚisignÚdsignÚcmplxÚmergeÚ
literal_dpÚ	elementalÚpureÚ	intent_inÚ
intent_outÚintent_inout)ÚSÚAddÚNÚFloatÚSymbol)ÚFunction)Úequal_valued)ÚEq)ÚRange)ÚCodePrinter)Ú
precedenceÚ
PRECEDENCE)Úprinter_context)ÚfcodeÚprint_fcodeÚsinÚcosÚtanÚasinÚacosÚatanÚatan2ÚsinhÚcoshÚtanhÚlogÚexpÚerfÚabsZconjgÚmaxÚmin)r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   ÚAbsÚ	conjugateZMaxZMinc                      sœ  e Zd ZU dZdZdZeeee	e
eiZedede	dededed	ed
edededediZeddiiZeejfdi dddddœŽZded< ddddddœZddiZd›‡ fd!d"„	Zed#d$„ ƒZ‡ fd%d&„Z d'd(„ Z!d)d*„ Z"d+d,„ Z#d-d.„ Z$d/d0„ Z%d1d2„ Z&d3d4„ Z'd5d6„ Z(d7d8„ Z)d9d:„ Z*d;d<„ Z+d=d>„ Z,d?d@„ Z-dAdB„ Z.dCdD„ Z/dEdF„ Z0dGdH„ Z1dIdJ„ Z2dKdL„ Z3dMdN„ Z4dOdP„ Z5dQdR„ Z6dSdT„ Z7dUdV„ Z8dWdX„ Z9dYdZ„ Z:d[d\„ Z;d]d^„ Z<d_d`„ Z=dadb„ Z>dcdd„ Z?dedf„ Z@dgdh„ ZAdidj„ ZBdkdl„ ZCdmdn„ ZDdodp„ ZEdqdr„ ZFdsdt„ ZGdudv„ ZHdwdx„ ZIdydz„ ZJd{d|„ ZKd}d~„ ZLdd€„ ZMd�d‚„ ZNdƒd„„ ZOd…d†„ ZPd‡dˆ„ ZQd‰dŠ„ ZRd‹dŒ„ ZSd�dŽ„ ZTd�d�„ ZUd‘d’„ ZVd“d”„ ZWd•d–„ ZXd—d˜„ ZYd™dš„ ZZ‡  Z[S )œÚFCodePrinterzAA printer to convert SymPy expressions to strings of Fortran codeZ_fcodeÚFortranzinteger(c_int)zreal*4zreal*8zreal*10z	complex*8z
complex*16z	integer*1z	integer*2z	integer*4z	integer*8ZlogicalÚiso_c_bindingZc_inté   ÚfixedTéM   )Ú	precisionÚuser_functionsÚsource_formatZcontractÚstandardÚname_manglingzdict[str, Any]Ú_default_settingsz.and.z.or.z.neqv.z.eqv.z.not. )ÚandÚorÚxorZ
equivalentÚnotz!=z/=Nc                   sÄ   |si }i | _ g | _tt| j ¡ | di ¡ ¡ ƒƒ| _tt| j ¡ | di ¡ ¡ ƒƒ| _tƒ  	|¡ tt
ƒ| _
| di ¡}| j
 |¡ dddddd	h}| jd
 |kr¶td| jd
  ƒ‚ttƒ| _d S )NÚtype_aliasesÚtype_mappingsrN   éB   rL   éZ   é_   éÓ  iØ  rP   zUnknown Fortran standard: %s)Úmangled_symbolsÚ	used_nameÚdictr   rW   ÚitemsÚpoprX   ÚsuperÚ__init__Úknown_functionsÚgetÚupdateÚ	_settingsÚ
ValueErrorr   ÚsetÚmodule_uses)ÚselfÚsettingsZ	userfuncsZ	standards©Ú	__class__© úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/printing/fortran.pyrc   x   s(    ÿÿ
ÿzFCodePrinter.__init__c                 C  sJ   | j d dkrddddœS | j d dkr4ddd	dœS td
| j d  ƒ‚d S )NrO   rK   z      z     @ zC     )ÚcodeÚcontÚcommentÚfreeÚ z! zUnknown source format: %s)rg   rh   ©rk   ro   ro   rp   Ú_leadŒ   s
    zFCodePrinter._leadc                   s†   | j d dkrv|| jkrj|j}| ¡ | jkr6|d7 }q| j | ¡ ¡ ||jkr\|| j|< nt|ƒ| j|< | | j¡}tƒ  	|¡}|S )NrQ   TÚ_)
rg   r]   ÚnameÚlowerr^   Úappendr*   Zxreplacerb   Ú_print_Symbol)rk   Úexprry   rm   ro   rp   r|   •   s    


zFCodePrinter._print_Symbolc                 C  s
   | d S )Né   ro   )rk   Úpro   ro   rp   Ú_rate_index_position¦   s    z!FCodePrinter._rate_index_positionc                 C  s   |S ©Nro   )rk   Z
codestringro   ro   rp   Ú_get_statement©   s    zFCodePrinter._get_statementc                 C  s
   d  |¡S )Nz! {})Úformat)rk   Útextro   ro   rp   Ú_get_comment¬   s    zFCodePrinter._get_commentc                 C  s   d  ||  |¡¡S )Nzparameter ({} = {}))rƒ   Ú_print)rk   ry   Úvaluero   ro   rp   Ú_declare_number_const¯   s    z"FCodePrinter._declare_number_constc                 C  s(   | j  |t| | jd ¡ƒf¡ t|ƒS )NrM   )Z_number_symbolsÚaddr)   Zevalfrg   Ústr©rk   r}   ro   ro   rp   Ú_print_NumberSymbol²   s     z FCodePrinter._print_NumberSymbolc                 C  s   |   |  |¡¡S r�   )Ú_wrap_fortranÚindent_code)rk   Úlinesro   ro   rp   Ú_format_code¸   s    zFCodePrinter._format_codec                   s    |j \‰ }‡ fdd„t|ƒD ƒS )Nc                 3  s$   | ]}t ˆ ƒD ]}||fV  qqd S r�   )Úrange)Ú.0ÚjÚi©Úrowsro   rp   Ú	<genexpr>½   s     
  z8FCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)Úshaper‘   )rk   ZmatÚcolsro   r•   rp   Ú_traverse_matrix_indices»   s    
z%FCodePrinter._traverse_matrix_indicesc                 C  s^   g }g }|D ]H}t | j|j|jd |jd gƒ\}}}| d|||f ¡ | d¡ q||fS )Né   zdo %s = %s, %súend do)Úmapr†   Úlabelrz   Úupperr{   )rk   ÚindicesZ
open_linesZclose_linesr”   ÚvarÚstartÚstopro   ro   rp   Ú_get_loop_opening_ending¿   s    ÿ
z%FCodePrinter._get_loop_opening_endingc                 C  s    ddl m} |j\}|jr4tdtd|ƒt|dƒƒ}nb|js@|jrrtt	t
dƒt
dƒƒ|||ƒ t||ƒt
dƒƒƒ}n$tt
dƒtt
dƒ|ƒt|t
dƒƒƒ}|  |¡S )Nr   )rE   r›   )Z$sympy.functions.elementary.complexesrE   ÚargsÚ
is_integerr   r   r-   Z
is_complexÚis_infiniter   r    r   r†   )rk   r}   rE   ÚargZnew_exprro   ro   rp   Ú_print_signÊ   s    2$zFCodePrinter._print_signc           
      C  s:  |j d jdkrtdƒ‚g }| t¡rºt|j ƒD ]t\}\}}|dkrZ| d|  |¡ ¡ n:|t|j ƒd kr€|dkr€| d¡ n| d|  |¡ ¡ | |  |¡¡ q0| d	¡ d
 	|¡S | j
d dk�r.d}|  |j d j¡}t|j d d… ƒ}|�r*| ¡ \}}|  |¡}|  |¡}	|j|||	d�}qò|S tdƒ‚d S )NéÿÿÿÿTz¼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.r   zif (%s) thenr›   Úelsezelse if (%s) thenúend ifÚ
rP   r[   zmerge({T}, {F}, {COND}))ÚTÚFZCONDzmUsing Piecewise as an expression using inline operators is not supported in standards earlier than Fortran95.)r¥   Úcondrh   Úhasr   Ú	enumerater{   r†   ÚlenÚjoinrg   r}   Úlistra   rƒ   ÚNotImplementedError)
rk   r}   r�   r”   ÚeÚcÚpatternrq   Ztermsr°   ro   ro   rp   Ú_print_PiecewiseÖ   s0    




zFCodePrinter._print_Piecewisec                 C  s,   d  | j|jtd dd�|jd |jd ¡S )Nz
{}({}, {})ZAtomT)Ústrictr›   )rƒ   ÚparenthesizeÚparentr1   r”   r“   r‹   ro   ro   rp   Ú_print_MatrixElement   s     ÿ ÿz!FCodePrinter._print_MatrixElementc           
      C  s  g }g }g }|j D ]>}|jr.|jr.| |¡ q|jrF|jrF| |¡ q| |¡ q|�r |rÖt|ƒ}t|Ž }|  |¡}| d¡r’d}	|dd … }nd}	t|ƒ|k rªd| }d|  t|Ž ¡|  t	j
 t|Ž  ¡|	|f S d|  t|Ž ¡|  t	j
 t|Ž  ¡f S nt | |¡S d S )Nú-r›   ú+z(%s)zcmplx(%s,%s) %s %szcmplx(%s,%s))r¥   Ú	is_numberZis_realr{   Úis_imaginaryr0   r'   r†   Ú
startswithr&   ÚImaginaryUnitr/   Ú
_print_Add)
rk   r}   Z	pure_realZpure_imaginaryÚmixedr¨   ÚPRECÚtermÚtÚsignro   ro   rp   rÅ     s>    


 ýþzFCodePrinter._print_Addc                   sR   | j d ‰ ‡ fdd„|jD ƒ}|j|Ž }t|tƒs<|  |¡S t | |j|Ž ¡S d S )NrM   c                   s   g | ]}t |ˆ ƒ‘qS ro   )r(   )r’   Úa©Úprecro   rp   Ú
<listcomp>.  s     z0FCodePrinter._print_Function.<locals>.<listcomp>)rg   r¥   ÚfuncÚ
isinstancer+   r†   r/   Ú_print_Function)rk   r}   r¥   Z	eval_exprro   rÌ   rp   rÑ   +  s    



zFCodePrinter._print_Functionc                 C  sB   | j d dkrd}t|ƒ‚n"|j\}}d |  |¡|  |¡¡S d S )NrP   )rY   rL   z]Python % operator and SymPy's Mod() function are not supported by Fortran 66 or 77 standards.z      modulo({}, {}))rg   r¶   r¥   rƒ   r†   )rk   r}   ÚmsgÚxÚyro   ro   rp   Ú
_print_Mod5  s
    

zFCodePrinter._print_Modc                 C  s   dS )Nz
cmplx(0,1)ro   r‹   ro   ro   rp   Ú_print_ImaginaryUnitB  s    z!FCodePrinter._print_ImaginaryUnitc                 C  s   t |ƒS r�   ©rŠ   r‹   ro   ro   rp   Ú
_print_intF  s    zFCodePrinter._print_intc                 C  s2   |j r"|jr"d|  tj | ¡ S t | |¡S d S )Nzcmplx(0,%s))rÁ   rÂ   r†   r&   rÄ   r/   Ú
_print_Mulr‹   ro   ro   rp   rÙ   I  s
    ÿzFCodePrinter._print_Mulc                 C  s”   t |ƒ}t|jdƒr4d|  tdƒ¡|  |j|¡f S t|jdƒr„|jjrr|jjr`d|  |j¡ S d|  |j¡ S q�d|  |j¡ S nt	 
| |¡S d S )Nrª   z%s/%sr›   g      à?zsqrt(%s.0d0)zsqrt(dble(%s))zsqrt(%s))r0   r,   r@   r†   r    r¼   Úbaser¦   Z	is_Numberr/   Ú
_print_Pow)rk   r}   rÇ   ro   ro   rp   rÛ   R  s    þzFCodePrinter._print_Powc                 C  s"   t |jƒt |jƒ }}d||f S )Nz%d.0d0/%d.0d0)Úintr   Úq)rk   r}   r   rÝ   ro   ro   rp   Ú_print_Rationale  s    zFCodePrinter._print_Rationalc                 C  sF   t  | |¡}| d¡}|dkr>d|d |… ||d d … f S d| S )Nr·   rª   z%sd%sr›   z%sd0)r/   Ú_print_FloatÚfind)rk   r}   Zprintedr·   ro   ro   rp   rß   i  s
    
 zFCodePrinter._print_Floatc                 C  sD   |   |j¡}|   |j¡}|j}|| jkr,|n| j| }d |||¡S )Nz{} {} {})r†   ÚlhsÚrhsZrel_opÚ_relationalsrƒ   )rk   r}   Úlhs_codeÚrhs_codeÚopro   ro   rp   Ú_print_Relationalp  s
    zFCodePrinter._print_Relationalc                   s0   ‡ fdd„|j D ƒ}dˆ  |jj¡d |¡f S )Nc                   s   g | ]}ˆ   |¡‘qS ro   ©r†   )r’   r”   rv   ro   rp   rÎ   x  s     z/FCodePrinter._print_Indexed.<locals>.<listcomp>ú%s(%s)ú, )r    r†   rÚ   rž   r´   )rk   r}   Zindsro   rv   rp   Ú_print_Indexedw  s    zFCodePrinter._print_Indexedc                 C  s   |   |j¡S r�   )r†   rž   r‹   ro   ro   rp   Ú
_print_Idx{  s    zFCodePrinter._print_Idxc              	   C  s@   |   |j¡}|   |j¡}|  d |   |¡|   |j¡|   |¡¡¡S )Nz{0} = {0} {1} {2})r†   rá   râ   r‚   rƒ   Zbinop)rk   r}   rä   rå   ro   ro   rp   Ú_print_AugmentedAssignment~  s     
 ÿz'FCodePrinter._print_AugmentedAssignmentc                 C  s^   |   |j¡}|jd kr*|d|   |j¡ 7 }|jd krH|d|   |j¡ 7 }d|jj d¡|f S )Nrê   z, mask=ré   rx   )r†   ÚarrayÚdimÚmaskrn   Ú__name__Úrstrip)rk   ÚsmÚparamsro   ro   rp   Ú_print_sum_„  s    

zFCodePrinter._print_sum_c                 C  s
   |   |¡S r�   )rõ   )rk   Úprodro   ro   rp   Ú_print_product_Œ  s    zFCodePrinter._print_product_c                   s\   dg}|j dkr | d¡ d}nd}d| d jf d|jr>dndi|j‡ fd	d
„|d�—ŽS )NÚ
concurrentr›   Ústepru   ú, {step}z*do {concurrent}{counter} = {first}, {last}z
{body}
end do
zconcurrent c                   s
   ˆ   | ¡S r�   rè   ©r¨   rv   ro   rp   Ú<lambda>�  ó    z(FCodePrinter._print_Do.<locals>.<lambda>)ÚapplyÚexclude)rù   r{   rƒ   rø   Úkwargs)rk   ÚdoZexclrù   ro   rv   rp   Ú	_print_Do�  s    

üûÿzFCodePrinter._print_Doc                   s6   |j dkrdnd}d| d jf |j‡ fdd„d�ŽS )	Nr›   ru   rú   z$({expr}, {counter} = {first}, {last}ú)c                   s
   ˆ   | ¡S r�   rè   rû   rv   ro   rp   rü   £  rý   z3FCodePrinter._print_ImpliedDoLoop.<locals>.<lambda>©rþ   )rù   rƒ   r   )rk   Úidlrù   ro   rv   rp   Ú_print_ImpliedDoLoop   s    ÿz!FCodePrinter._print_ImpliedDoLoopc                 C  sT   |   |j¡}t|jtƒr(|jj\}}}ntdƒ‚|   |j¡}dj|||d ||d�S )Nz*Only iterable currently supported is Rangez3do {target} = {start}, {stop}, {step}
{body}
end dor›   )Útargetr¢   r£   rù   Úbody)	r†   r  rÐ   Úiterabler.   r¥   r¶   r  rƒ   )rk   r}   r  r¢   r£   rù   r  ro   ro   rp   Ú
_print_For¦  s       ýzFCodePrinter._print_Forc                 C  sP   | j  ||¡}| j ||j¡}| j |¡}|rL|D ]\}}| j|  |¡ q2|S r�   )rW   re   rX   ry   Útype_modulesrj   r‰   )rk   Útype_Ztype_strrj   ÚkÚvro   ro   rp   Ú_print_Type²  s    zFCodePrinter._print_Typec                   s,   dj ˆ  |j¡d ‡ fdd„|jD ƒ¡d�S )Nú{symbol}({idxs})rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   ©r’   r¨   rv   ro   rp   r—   ¾  s     z.FCodePrinter._print_Element.<locals>.<genexpr>©ÚsymbolZidxs)rƒ   r†   r  r´   r    ©rk   Úelemro   rv   rp   Ú_print_Element»  s    
þzFCodePrinter._print_Elementc                 C  s   t |ƒS r�   r×   )rk   Úextro   ro   rp   Ú_print_ExtentÁ  s    zFCodePrinter._print_Extentc              	     sV  |j ‰ˆj}ˆ d¡}‡fdd„tttfD ƒ}| d¡dkrBd}n4| d¡dkrjdd	d
dg| d¡  }ntdˆ  ƒ‚t	ˆt
ƒrˆtdƒ‚ˆ jd dk�rdjˆ  ˆj¡tˆjkr´dnd|rÖdd ‡ fdd„|D ƒ¡ nd|tˆjkrèdndˆ  ˆj¡d�}|d k�rR|dˆ  |¡ 7 }n:tˆjk�s*|�r2tdƒ‚d ‡ fdd„ˆjˆjfD ƒ¡}|S )NÚ	dimensionc                   s   g | ]}|ˆ j k‘qS ro   )Úattrs)r’   Úintent)r¡   ro   rp   rÎ   È  s     z3FCodePrinter._print_Declaration.<locals>.<listcomp>Tr   ru   r›   z, intent(%s)ÚinÚoutZinoutz!Multiple intents specified for %sz1Pointers are not available by default in Fortran.rP   rZ   z"{t}{vc}{dim}{intent}{alloc} :: {s}z, parameterz, dimension(%s)rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   Ö  s     z2FCodePrinter._print_Declaration.<locals>.<genexpr>z, allocatable)rÉ   Úvcrï   r  ZallocÚsz = %sz0F77 init./parameter statem. req. multiple lines.ú c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   à  s     )Úvariabler‡   Úattr_paramsr#   r$   r%   ÚcountÚindexrh   rÐ   r   r¶   rg   rƒ   r†   Útyper	   r  r´   r   r  )rk   r}   Úvalrï   Zintentsr  Úresultro   )rk   r¡   rp   Ú_print_DeclarationÄ  s4    


"
ú
 zFCodePrinter._print_Declarationc                 C  s   d|   tdƒ¡ S )Nz(huge(%s) + 1)r   )r†   r    r‹   ro   ro   rp   Ú_print_Infinityå  s    zFCodePrinter._print_Infinityc                   s   dj f |j‡ fdd„d�ŽS )Nz$do while ({condition})
{body}
end doc                   s
   ˆ   | ¡S r�   rè   rû   rv   ro   rp   rü   ê  rý   z+FCodePrinter._print_While.<locals>.<lambda>r  ©rƒ   r   r‹   ro   rv   rp   Ú_print_Whileè  s    

ÿzFCodePrinter._print_Whilec                 C  s   dS )Nz.true.ro   r‹   ro   ro   rp   Ú_print_BooleanTrueì  s    zFCodePrinter._print_BooleanTruec                 C  s   dS )Nz.false.ro   r‹   ro   ro   rp   Ú_print_BooleanFalseï  s    z FCodePrinter._print_BooleanFalsec                 C  sR   g }|D ]D}|  d¡r8| | jd |dd …  ¡  ¡ q| | jd | ¡ q|S )Nú!rs   r›   rq   )rÃ   r{   rw   Úlstrip)rk   r�   r'  Úlinero   ro   rp   Ú_pad_leading_columnsò  s    
"z!FCodePrinter._pad_leading_columnsc                   sà  t dtj tj ƒ‰ t dƒ‰‡ ‡fdd„}g }| jd dkrBd}nd}|D �]Ž}| | jd	 ¡�r t|ƒd
k�r| ddd
¡}|dkrŠd
}|d|… }||d…  	¡ }| 
|¡ |�r| ddd¡}|dksØt|ƒdk rÜd}|d|… }||d…  	¡ }| 
d| jd	 |f ¡ q°n
| 
|¡ qJ| | jd ¡�rÐ||d
ƒ}|d|…  ¡ }||d…  	¡ }|�rj||7 }| 
|¡ |�rÚ||dƒ}|d|…  ¡ }||d…  	¡ }|�r²||7 }| 
d| jd |f ¡ �qtqJ| 
|¡ qJ|S )zøWrap long Fortran lines

           Argument:
             lines  --  a list of lines (without \n character)

           A comment line is split at white space. Code lines are split with a more
           complex rule to give nice results.
        z_+-.z 	()c                   sJ   t ˆ ƒ|krt ˆ ƒS |}‡ ‡‡fdd„}||ƒsF|d8 }|dkr(|S q(|S )Nc                   sp   ˆ |  ˆkrˆ | d  ˆkpnˆ |  ˆkr8ˆ | d  ˆkpnˆ |  ˆkrTˆ | d  ˆkpnˆ |  ˆkonˆ | d  ˆkS )Nr›   ro   )Úpos)r0  Úmy_alnumÚmy_whitero   rp   rü     s    ÿþzDFCodePrinter._wrap_fortran.<locals>.split_pos_code.<locals>.<lambda>r›   r   )r³   )r0  Úendposr2  Úsplit©r3  r4  )r0  rp   Úsplit_pos_code  s    z2FCodePrinter._wrap_fortran.<locals>.split_pos_coderO   rt   z &ru   rs   éH   r   é   rª   Nr   rY   ú%s%srq   éA   rr   )ri   ÚstringÚdigitsÚascii_lettersrg   rÃ   rw   r³   Úrfindr/  r{   rò   )rk   r�   r8  r'  Ztrailingr0  r2  Zhunkro   r7  rp   r�   û  sP    





zFCodePrinter._wrap_fortranc                   s@  t |tƒr$|  | d¡¡}d |¡S | jd dk}dd„ |D ƒ}d‰d‰ ‡fd	d„|D ƒ}‡ fd
d„|D ƒ}dd„ |D ƒ}d}d}d}	g }
t|ƒD ]˜\}}|dkr®|
 |¡ q’||| 8 }|rÐd||	 |  }nd| |	 }d||f }|sü|  |g¡d }|
 |¡ || �rd|	 }nd}||| 7 }q’|�s<|  	|
¡S |
S )z0Accepts a string of code or a list of code linesTru   rO   rt   c                 S  s   g | ]}|  d ¡‘qS )z 	)r/  ©r’   r0  ro   ro   rp   rÎ   I  s     z,FCodePrinter.indent_code.<locals>.<listcomp>)zdo zif(zif zdo
r«   ÚprogramZ	interface)rœ   Zenddor¬   Úendifr«   zend programzend interfacec                   s    g | ]}t tt|jˆ ƒƒƒ‘qS ro   ©rÜ   Úanyr�   rÃ   rA  )Úinc_keywordro   rp   rÎ   N  s   ÿc                   s    g | ]}t tt|jˆ ƒƒƒ‘qS ro   rD  rA  )Údec_keywordro   rp   rÎ   P  s   ÿc                 S  s$   g | ]}t tt|jd dgƒƒƒ‘qS )ú&z&
)rÜ   rE  r�   ÚendswithrA  ro   ro   rp   rÎ   R  s   ÿr   é   )ru   r­   r   r;  é   )
rÐ   rŠ   rŽ   Ú
splitlinesr´   rg   r²   r{   r1  r�   )rk   rq   Z
code_linesrt   ZincreaseZdecreaseZcontinuationÚlevelZcont_paddingZtabwidthZnew_coder”   r0  Úpaddingro   )rG  rF  rp   rŽ   B  sN    


ÿ
ÿÿ




zFCodePrinter.indent_codec                   sL   |j r2djd ‡ fdd„|jD ƒ¡ˆ  |j ¡d�S |j\}dˆ  |¡ S d S )Nzgo to ({labels}), {expr}rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   w  s     z+FCodePrinter._print_GoTo.<locals>.<genexpr>)Úlabelsr}   zgo to %s)r}   rƒ   r´   rO  r†   )rk   ZgotoZlblro   rv   rp   Ú_print_GoTot  s    
þzFCodePrinter._print_GoToc                   s   dj f |j‡ fdd„d�ŽS )Nz"program {name}
{body}
end program
c                   s
   ˆ   | ¡S r�   rè   rû   rv   ro   rp   rü   ƒ  rý   z-FCodePrinter._print_Program.<locals>.<lambda>r  r*  )rk   Úprogro   rv   rp   Ú_print_Program~  s    ýÿzFCodePrinter._print_Programc                   s   dj f |j‡ fdd„d�ŽS )NzAmodule {name}
{declarations}

contains

{definitions}
end module
c                   s
   ˆ   | ¡S r�   rè   rû   rv   ro   rp   rü   Œ  rý   z,FCodePrinter._print_Module.<locals>.<lambda>r  r*  )rk   Úmodro   rv   rp   Ú_print_Module…  s    ûÿzFCodePrinter._print_Modulec                 C  sp   |j dkr,| jd dkr,| jd  d¡ dS |j dkrX| jd dkrX| jd  d¡ d	S |j dkrfd
S |j S d S )Nr   rP   r\   rI   zstdint=>input_unitZ
input_unitr   zstdint=>error_unitZ
error_unitÚ*)ry   rg   rj   r‰   )rk   Ústrmro   ro   rp   Ú_print_StreamŽ  s    
zFCodePrinter._print_Streamc                   sb   |j tkrd}d}n*ddtdtdi |jd¡i }ˆ  |j ¡}|j|d ‡ fdd	„|j	D ƒ¡d
�S )Nzprint {fmt}, {iolist}rU  z3write(%(out)s, fmt="{fmt}", advance="no"), {iolist}r  Ú0Ú6rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   ¥  s     z,FCodePrinter._print_Print.<locals>.<genexpr>)ÚfmtZiolist)
Úformat_stringr   r   r   re   Úfiler†   rƒ   r´   Z
print_args)rk   ZpsÚtemplaterZ  ro   rv   rp   Ú_print_Print›  s    
 ÿ
ÿzFCodePrinter._print_Printc                 C  s&   |j \}dj| j dd¡|  |¡d�S )Nz{result_name} = {arg}Úresult_nameZsympy_result)r_  r¨   )r¥   rƒ   Ú_contextre   r†   )rk   Úrsr¨   ro   ro   rp   Ú_print_Return§  s
    þzFCodePrinter._print_Returnc                 C  s"   |j \}|rd|  |¡ S dS d S )Nz	return %sÚreturn)r¥   r†   )rk   Zfrsr¨   ro   ro   rp   Ú_print_FortranReturn®  s    z!FCodePrinter._print_FortranReturnc                   s�   |  d¡}|d krd}n|r(d|d  nd}ˆ j dd ¡}dj|ˆ  |j¡d ‡ fd	d
„|jD ƒ¡|rnd| nd|d ‡ fdd„|jD ƒ¡d�S )NZbind_Cru   z bind(C, name="%s")r   z bind(C)r_  z<{entity}{name}({arg_names}){result}{bind}
{arg_declarations}rê   c                   s   g | ]}ˆ   |j¡‘qS ro   )r†   r  r  rv   ro   rp   rÎ   Â  s     z&FCodePrinter._head.<locals>.<listcomp>z result(%s)r­   c                 3  s   | ]}ˆ   t|ƒ¡V  qd S r�   )r†   r   r  rv   ro   rp   r—   Å  s     z%FCodePrinter._head.<locals>.<genexpr>)Úentityry   Ú	arg_namesr'  ÚbindZarg_declarations)r"  rg   re   rƒ   r†   ry   r´   Ú
parameters)rk   re  Úfpr   Zbind_C_paramsrg  r_  ro   rv   rp   Ú_headµ  s    

øÿzFCodePrinter._headc                 C  s&   d  |  |j¡¡}dj |  ||¡d�S )Nú{} function z4interface
{function_head}
end function
end interface)Úfunction_head)rƒ   r†   Úreturn_typerj  )rk   ri  re  ro   ro   rp   Ú_print_FunctionPrototypeÈ  s
    
üÿz%FCodePrinter._print_FunctionPrototypec              
   C  s|   t |jkrd}nt|jkr d}nd}d |  |j¡¡}t| |jd��. dj||  ||¡|  |j	¡d�W  5 Q R £ S Q R X d S )Nz
elemental zpure ru   rk  )r_  z,{prefix}{function_head}
{body}
end function
)Úprefixrl  r  )
r!   r  r"   rƒ   r†   rm  r2   ry   rj  r  )rk   Úfdro  re  ro   ro   rp   Ú_print_FunctionDefinitionÑ  s    



úÿz&FCodePrinter._print_FunctionDefinitionc                 C  s   dj |  d|¡|  |j¡d�S )Nz({subroutine_head}
{body}
end subroutine
zsubroutine )Zsubroutine_headr  )rƒ   rj  r†   r  )rk   Úsubro   ro   rp   Ú_print_Subroutineå  s
    

ûÿzFCodePrinter._print_Subroutinec                   s,   dj ˆ  |j¡d ‡ fdd„|jD ƒ¡d�S )Nzcall {name}({args})rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   ò  s     z5FCodePrinter._print_SubroutineCall.<locals>.<genexpr>)ry   r¥   )rƒ   r†   ry   r´   Zsubroutine_args)rk   Zscallro   rv   rp   Ú_print_SubroutineCallï  s    
þz"FCodePrinter._print_SubroutineCallc                   s   dt ‡ fdd„|jD ƒƒ S )Nz%s => %sc                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—   ö  s     z1FCodePrinter._print_use_rename.<locals>.<genexpr>)Útupler¥   )rk   Úrnmro   rv   rp   Ú_print_use_renameõ  s    zFCodePrinter._print_use_renamec                   sl   dˆ   |j¡ }|jd kr<|dd ‡ fdd„|jD ƒ¡ 7 }|jd krh|dd ‡ fdd„|jD ƒ¡ 7 }|S )Nzuse %srê   c                   s   g | ]}ˆ   |¡‘qS ro   rè   )r’   rv  rv   ro   rp   rÎ   û  s     z+FCodePrinter._print_use.<locals>.<listcomp>z, only: c                   s   g | ]}ˆ   |¡‘qS ro   rè   )r’   Znlyrv   ro   rp   rÎ   ý  s     )r†   Ú	namespaceÚrenamer´   Úonly)rk   Zuser'  ro   rv   rp   Ú
_print_useø  s    
"
"zFCodePrinter._print_usec                 C  s   dS )NÚexitro   ©rk   rx   ro   ro   rp   Ú_print_BreakToken   s    zFCodePrinter._print_BreakTokenc                 C  s   dS )NÚcyclero   r}  ro   ro   rp   Ú_print_ContinueToken  s    z!FCodePrinter._print_ContinueTokenc                   s4   ˆ j d dkrdnd}|d ‡ fdd„|jD ƒ¡ S )NrP   r\   z[%s]z(/%s/)rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—     s     z7FCodePrinter._print_ArrayConstructor.<locals>.<genexpr>)rg   r´   Úelements)rk   ÚacZfmtstrro   rv   rp   Ú_print_ArrayConstructor  s    z$FCodePrinter._print_ArrayConstructorc                   s,   dj ˆ  |j¡d ‡ fdd„|jD ƒ¡d�S )Nr  rê   c                 3  s   | ]}ˆ   |¡V  qd S r�   rè   r  rv   ro   rp   r—     s     z3FCodePrinter._print_ArrayElement.<locals>.<genexpr>r  )rƒ   r†   ry   r´   r    r  ro   rv   rp   Ú_print_ArrayElement
  s    
þz FCodePrinter._print_ArrayElement)N)\rñ   Ú
__module__Ú__qualname__Ú__doc__ZprintmethodÚlanguager   r   r   r   r   r   rW   r   r
   r   r   r   r   r   r   rX   r  r_   r/   rR   Ú__annotations__Ú
_operatorsrã   rc   Úpropertyrw   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-  r1  r�   rŽ   rP  rR  rT  rW  r^  rb  rd  rj  rn  rq  rs  rt  rw  r{  r~  r€  rƒ  r„  Ú__classcell__ro   ro   rm   rp   rG   F   sæ   
   ý           õ ÿú
û	 ÿ
*'
		!	G2
		
rG   )Er‡  Ú
__future__r   Útypingr   Úcollectionsr   Ú	itertoolsr   r=  Zsympy.codegen.astr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zsympy.codegen.fnodesr   r   r   r   r   r    r!   r"   r#   r$   r%   Z
sympy.corer&   r'   r(   r)   r*   Zsympy.core.functionr+   Zsympy.core.numbersr,   Zsympy.core.relationalr-   Z
sympy.setsr.   Zsympy.printing.codeprinterr/   Zsympy.printing.precedencer0   r1   Zsympy.printing.printerr2   r3   r4   rd   rG   ro   ro   ro   rp   Ú<module>   sF   \4ï