a
    kº”hÛo  ã                   @  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i 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€„ ZMdd‚„ ZNdƒd„„ ZOd…d†„ ZPd‡dˆ„ ZQd‰dŠ„ ZRd‹dŒ„ ZSddŽ„ ZTdd„ ZUd‘d’„ ZVd“d”„ ZWd•d–„ ZXd—d˜„ ZY‡  ZZS )šÚFCodePrinterzAA printer to convert SymPy expressions to strings of Fortran codeZ_fcodeZFortranzinteger(c_int)zreal*4zreal*8zreal*10z	complex*8z
complex*16z	integer*1z	integer*2z	integer*4z	integer*8ÚlogicalÚiso_c_bindingÚ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
 |¡ h d£}| jd |vr®td| jd  ƒ‚ttƒ| _d S )NÚtype_aliasesÚtype_mappingsrO   >   éB   rM   éÓ  iØ  éZ   é_   rQ   zUnknown Fortran standard: %s)Úmangled_symbolsÚ	used_nameÚdictr   rX   ÚitemsÚpoprY   ÚsuperÚ__init__Úknown_functionsÚgetÚupdateÚ	_settingsÚ
ValueErrorr   ÚsetÚmodule_uses)ÚselfÚsettingsZ	userfuncsZ	standards©Ú	__class__© úD/var/www/auris/lib/python3.9/site-packages/sympy/printing/fortran.pyrd   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 )NrP   rL   z      z     @ zC     )ÚcodeÚcontÚcommentÚfreeÚ z! zUnknown source format: %s)rh   ri   ©rl   rp   rp   rq   Ú_leadŒ   s
    zFCodePrinter._leadc                   s†   | j d dkrv|| jvrj|j}| ¡ | jv r6|d7 }q| j | ¡ ¡ ||jkr\|| j|< nt|ƒ| j|< | | j¡}tƒ  	|¡}|S )NrR   TÚ_)
rh   r^   ÚnameÚlowerr_   Úappendr*   Zxreplacerc   Ú_print_Symbol)rl   Úexprrz   rn   rp   rq   r}   •   s    


zFCodePrinter._print_Symbolc                 C  s
   | d S )Né   rp   )rl   Úprp   rp   rq   Ú_rate_index_position¦   s    z!FCodePrinter._rate_index_positionc                 C  s   |S ©Nrp   )rl   Z
codestringrp   rp   rq   Ú_get_statement©   s    zFCodePrinter._get_statementc                 C  s
   d  |¡S )Nz! {})Úformat)rl   Útextrp   rp   rq   Ú_get_comment¬   s    zFCodePrinter._get_commentc                 C  s   d  ||  |¡¡S )Nzparameter ({} = {}))r„   Ú_print)rl   rz   Úvaluerp   rp   rq   Ú_declare_number_const¯   s    z"FCodePrinter._declare_number_constc                 C  s(   | j  |t| | jd ¡ƒf¡ t|ƒS )NrN   )Z_number_symbolsÚaddr)   Zevalfrh   Ústr©rl   r~   rp   rp   rq   Ú_print_NumberSymbol²   s     z FCodePrinter._print_NumberSymbolc                 C  s   |   |  |¡¡S r‚   )Ú_wrap_fortranÚindent_code)rl   Úlinesrp   rp   rq   Ú_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©Úrowsrp   rq   Ú	<genexpr>½   ó    z8FCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)Úshaper’   )rl   ÚmatÚcolsrp   r–   rq   Ú_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‡   Úlabelr{   Úupperr|   )rl   ÚindicesZ
open_linesZclose_linesr•   ÚvarÚstartÚstoprp   rp   rq   Ú_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‡   )rl   r~   rE   ÚargZnew_exprrp   rp   rq   Ú_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Ú
rQ   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¨   Úcondri   Zhasr   Ú	enumerater|   r‡   ÚlenÚjoinrh   r~   Úlistrb   r„   ÚNotImplementedError)
rl   r~   r   r•   ÚeÚcÚpatternrr   Ztermsr³   rp   rp   rq   Ú_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Œ   rp   rp   rq   Ú_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)
rl   r~   Z	pure_realZpure_imaginaryÚmixedr«   ÚPRECZtermÚtÚsignrp   rp   rq   rÇ     s<    


ýþzFCodePrinter._print_Addc                   sR   | j d ‰ ‡ fdd„|jD ƒ}|j|Ž }t|tƒs<|  |¡S t | |j|Ž ¡S d S )NrN   c                   s   g | ]}t |ˆ ƒ‘qS rp   )r(   )r“   Úa©Úprecrp   rq   Ú
<listcomp>.  r™   z0FCodePrinter._print_Function.<locals>.<listcomp>)rh   r¨   ÚfuncÚ
isinstancer+   r‡   r/   Ú_print_Function)rl   r~   r¨   Z	eval_exprrp   rÍ   rq   rÒ   +  s    



zFCodePrinter._print_Functionc                 C  sB   | j d dv rd}t|ƒ‚n"|j\}}d |  |¡|  |¡¡S d S )NrQ   )rZ   rM   z]Python % operator and SymPy's Mod() function are not supported by Fortran 66 or 77 standards.z      modulo({}, {}))rh   r¸   r¨   r„   r‡   )rl   r~   ÚmsgÚxÚyrp   rp   rq   Ú
_print_Mod5  s
    

zFCodePrinter._print_Modc                 C  s   dS )Nz
cmplx(0,1)rp   rŒ   rp   rp   rq   Ú_print_ImaginaryUnitB  s    z!FCodePrinter._print_ImaginaryUnitc                 C  s   t |ƒS r‚   ©r‹   rŒ   rp   rp   rq   Ú
_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Œ   rp   rp   rq   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 qd|  |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)rl   r~   rÉ   rp   rp   rq   rÜ   R  s    þzFCodePrinter._print_Powc                 C  s"   t |jƒt |jƒ }}d||f S )Nz%d.0d0/%d.0d0)Úintr€   Úq)rl   r~   r€   rÞ   rp   rp   rq   Ú_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)rl   r~   Zprintedr¹   rp   rp   rq   rà   i  s
    
 zFCodePrinter._print_Floatc                 C  sD   |   |j¡}|   |j¡}|j}|| jvr,|n| j| }d |||¡S )Nz{} {} {})r‡   ÚlhsÚrhsZrel_opÚ_relationalsr„   )rl   r~   Úlhs_codeÚrhs_codeÚoprp   rp   rq   Ú_print_Relationalp  s
    zFCodePrinter._print_Relationalc                   s0   ‡ fdd„|j D ƒ}dˆ  |jj¡d |¡f S )Nc                   s   g | ]}ˆ   |¡‘qS rp   ©r‡   )r“   r•   rw   rp   rq   rÏ   x  r™   z/FCodePrinter._print_Indexed.<locals>.<listcomp>ú%s(%s)ú, )r£   r‡   rÛ   r¡   r¶   )rl   r~   Zindsrp   rw   rq   Ú_print_Indexedw  s    zFCodePrinter._print_Indexedc              	   C  s@   |   |j¡}|   |j¡}|  d |   |¡|   |j¡|   |¡¡¡S )Nz{0} = {0} {1} {2})r‡   râ   rã   rƒ   r„   Úbinop)rl   r~   rå   ræ   rp   rp   rq   Ú_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ê   ry   )r‡   ÚarrayÚdimÚmaskro   Ú__name__Úrstrip)rl   ÚsmÚparamsrp   rp   rq   Ú_print_sum_  s    

zFCodePrinter._print_sum_c                 C  s
   |   |¡S r‚   )rö   )rl   Úprodrp   rp   rq   Ú_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ž   Ústeprv   ú, {step}z*do {concurrent}{counter} = {first}, {last}z
{body}
end do
zconcurrent c                   s
   ˆ   | ¡S r‚   ré   ©r«   rw   rp   rq   Ú<lambda>š  r™   z(FCodePrinter._print_Do.<locals>.<lambda>)ÚapplyÚexclude)rú   r|   r„   rù   Úkwargs)rl   ZdoZexclrú   rp   rw   rq   Ú	_print_DoŒ  s    


ÿûúzFCodePrinter._print_Doc                   s:   |j dkrdnd}d| d jf i |j‡ fdd„d¤ŽS )	Nrž   rv   rû   z$({expr}, {counter} = {first}, {last}ú)c                   s
   ˆ   | ¡S r‚   ré   rü   rw   rp   rq   rý      r™   z3FCodePrinter._print_ImpliedDoLoop.<locals>.<lambda>©rþ   )rú   r„   r   )rl   Zidlrú   rp   rw   rq   Ú_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„   )rl   r~   r  r¥   r¦   rú   r  rp   rp   rq   Ú
_print_For£  s    
ýzFCodePrinter._print_Forc                 C  sP   | j  ||¡}| j ||j¡}| j |¡}|rL|D ]\}}| j|  |¡ q2|S r‚   )rX   rf   rY   rz   Útype_modulesrk   rŠ   )rl   Útype_Ztype_strrk   ÚkÚvrp   rp   rq   Ú_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«   rw   rp   rq   r˜   »  r™   z.FCodePrinter._print_Element.<locals>.<genexpr>©ÚsymbolZidxs)r„   r‡   r  r¶   r£   ©rl   Úelemrp   rw   rq   Ú_print_Element¸  s    
þzFCodePrinter._print_Elementc                 C  s   t |ƒS r‚   rØ   )rl   Úextrp   rp   rq   Ú_print_Extent¾  s    zFCodePrinter._print_Extentc              	     sT  |j ‰ˆj}ˆ d¡}‡fdd„tttfD ƒ}| d¡dkrBd}n2| d¡dkrhdg d	¢| d¡  }ntd
ˆ  ƒ‚t	ˆt
ƒr†tdƒ‚ˆ jd dkrdjˆ  ˆj¡tˆjv r²dnd|rÔdd ‡ fdd„|D ƒ¡ nd|tˆjv rædndˆ  ˆj¡d}|d krP|dˆ  |¡ 7 }n:tˆjv s(|r0tdƒ‚d ‡ fdd„ˆjˆjfD ƒ¡}|S )NZ	dimensionc                   s   g | ]}|ˆ j v ‘qS rp   )Úattrs)r“   Úintent)r¤   rp   rq   rÏ   Å  r™   z3FCodePrinter._print_Declaration.<locals>.<listcomp>Tr   rv   rž   z, intent(%s))ÚinÚoutZinoutz!Multiple intents specified for %sz1Pointers are not available by default in Fortran.rQ   r\   z"{t}{vc}{dim}{intent}{alloc} :: {s}z, parameterz, dimension(%s)rë   c                 3  s   | ]}ˆ   |¡V  qd S r‚   ré   r  rw   rp   rq   r˜   Ó  r™   z2FCodePrinter._print_Declaration.<locals>.<genexpr>z, allocatable)rÊ   Zvcrð   r  ZallocÚsz = %sz0F77 init./parameter statem. req. multiple lines.ú c                 3  s   | ]}ˆ   |¡V  qd S r‚   ré   r  rw   rp   rq   r˜   Ý  r™   )Úvariablerˆ   Úattr_paramsr#   r$   r%   ÚcountÚindexri   rÑ   r   r¸   rh   r„   r‡   Útyper	   r  r¶   r   r  )rl   r~   Úvalrð   Zintentsr  Úresultrp   )rl   r¤   rq   Ú_print_DeclarationÁ  s4    


"
ú
 zFCodePrinter._print_Declarationc                 C  s   d|   tdƒ¡ S )Nz(huge(%s) + 1)r   )r‡   r    rŒ   rp   rp   rq   Ú_print_Infinityâ  s    zFCodePrinter._print_Infinityc                   s    dj f i |j‡ fdd„d¤ŽS )Nz$do while ({condition})
{body}
end doc                   s
   ˆ   | ¡S r‚   ré   rü   rw   rp   rq   rý   ç  r™   z+FCodePrinter._print_While.<locals>.<lambda>r  ©r„   r   rŒ   rp   rw   rq   Ú_print_Whileå  s    
ÿzFCodePrinter._print_Whilec                 C  s   dS )Nz.true.rp   rŒ   rp   rp   rq   Ú_print_BooleanTrueé  s    zFCodePrinter._print_BooleanTruec                 C  s   dS )Nz.false.rp   rŒ   rp   rp   rq   Ú_print_BooleanFalseì  s    z FCodePrinter._print_BooleanFalsec                 C  sR   g }|D ]D}|  d¡r8| | jd |dd …  ¡  ¡ q| | jd | ¡ q|S )Nú!rt   rž   rr   )rÅ   r|   rx   Úlstrip)rl   r   r#  Úlinerp   rp   rq   Ú_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   ˆ |  ˆv rˆ | d  ˆvpnˆ |  ˆvr8ˆ | d  ˆv pnˆ |  ˆv rTˆ | d  ˆvpnˆ |  ˆvonˆ | d  ˆv S )Nrž   rp   )Úpos)r,  Úmy_alnumÚmy_whiterp   rq   rý   	  s    ÿþzDFCodePrinter._wrap_fortran.<locals>.split_pos_code.<locals>.<lambda>rž   r   )rµ   )r,  Úendposr.  Úsplit©r/  r0  )r,  rq   Úsplit_pos_code  s    z2FCodePrinter._wrap_fortran.<locals>.split_pos_coderP   ru   z &rv   rt   éH   r  é   r­   Nr   rZ   ú%s%srr   éA   rs   )rj   ÚstringÚdigitsÚascii_lettersrh   rÅ   rx   rµ   Úrfindr+  r|   ró   )rl   r   r4  r#  Ztrailingr,  r.  Zhunkrp   r3  rq   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v 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 linesTrv   rP   ru   c                 S  s   g | ]}|  d ¡‘qS )z 	)r+  ©r“   r,  rp   rp   rq   rÏ   F  r™   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 rp   ©rÝ   Úanyr    rÅ   r=  )Úinc_keywordrp   rq   rÏ   K  s   ÿc                   s    g | ]}t tt|jˆ ƒƒƒ‘qS rp   r@  r=  )Údec_keywordrp   rq   rÏ   M  s   ÿc                 S  s$   g | ]}t tt|jd dgƒƒƒ‘qS )ú&z&
)rÝ   rA  r    Úendswithr=  rp   rp   rq   rÏ   O  s   ÿr   é   )rv   r°   r  r7  é   )
rÑ   r‹   r   Ú
splitlinesr¶   rh   r´   r|   r-  rŽ   )rl   rr   Z
code_linesru   ZincreaseZdecreaseZcontinuationÚlevelZcont_paddingZtabwidthZnew_coder•   r,  Úpaddingrp   )rC  rB  rq   r   ?  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  rw   rp   rq   r˜   t  r™   z+FCodePrinter._print_GoTo.<locals>.<genexpr>)Úlabelsr~   zgo to %s)r~   r„   r¶   rK  r‡   )rl   ÚgotoZlblrp   rw   rq   Ú_print_GoToq  s    
þzFCodePrinter._print_GoToc                   s    dj f i |j‡ fdd„d¤ŽS )Nz"program {name}
{body}
end program
c                   s
   ˆ   | ¡S r‚   ré   rü   rw   rp   rq   rý   €  r™   z-FCodePrinter._print_Program.<locals>.<lambda>r  r&  )rl   Úprogrp   rw   rq   Ú_print_Program{  s    ÿüzFCodePrinter._print_Programc                   s    dj f i |j‡ fdd„d¤ŽS )NzAmodule {name}
{declarations}

contains

{definitions}
end module
c                   s
   ˆ   | ¡S r‚   ré   rü   rw   rp   rq   rý   ‰  r™   z,FCodePrinter._print_Module.<locals>.<lambda>r  r&  )rl   Úmodrp   rw   rq   Ú_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   rQ   r[   rI   zstdint=>input_unitZ
input_unitr   zstdint=>error_unitZ
error_unitÚ*)rz   rh   rk   rŠ   )rl   Ústrmrp   rp   rq   Ú_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}rR  z3write(%(out)s, fmt="{fmt}", advance="no"), {iolist}r  Ú0Ú6rë   c                 3  s   | ]}ˆ   |¡V  qd S r‚   ré   r  rw   rp   rq   r˜   ¢  r™   z,FCodePrinter._print_Print.<locals>.<genexpr>)ÚfmtZiolist)
Úformat_stringr   r   r   rf   Úfiler‡   r„   r¶   Z
print_args)rl   ZpsÚtemplaterW  rp   rw   rq   Ú_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„   Ú_contextrf   r‡   )rl   Úrsr«   rp   rp   rq   Ú_print_Return¤  s
    þzFCodePrinter._print_Returnc                 C  s"   |j \}|rd|  |¡ S dS d S )Nz	return %sÚreturn)r¨   r‡   )rl   Zfrsr«   rp   rp   rq   Ú_print_FortranReturn«  s    z!FCodePrinter._print_FortranReturnc                   s   |  d¡}|d u 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_Crv   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 rp   )r‡   r  r  rw   rp   rq   rÏ   ¿  r™   z&FCodePrinter._head.<locals>.<listcomp>z result(%s)r°   c                 3  s   | ]}ˆ   t|ƒ¡V  qd S r‚   )r‡   r   r  rw   rp   rq   r˜   Â  r™   z%FCodePrinter._head.<locals>.<genexpr>)Úentityrz   Ú	arg_namesr#  ÚbindZarg_declarations)r  rh   rf   r„   r‡   rz   r¶   Ú
parameters)rl   rb  Úfpr   Zbind_C_paramsrd  r\  rp   rw   rq   Ú_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_typerg  )rl   rf  rb  rp   rp   rq   Ú_print_FunctionPrototypeÅ  s
    ÿ
ûz%FCodePrinter._print_FunctionPrototypec                 C  sˆ   t |jv rd}nt|jv r d}nd}d |  |j¡¡}t| |jd0 dj||  ||¡|  |j	¡dW  d   ƒ S 1 sz0    Y  d S )Nz
elemental zpure rv   rh  )r\  z,{prefix}{function_head}
{body}
end function
)Úprefixri  r  )
r!   r  r"   r„   r‡   rj  r2   rz   rg  r  )rl   Úfdrl  rb  rp   rp   rq   Ú_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„   rg  r‡   r  )rl   Úsubrp   rp   rq   Ú_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  rw   rp   rq   r˜   ï  r™   z5FCodePrinter._print_SubroutineCall.<locals>.<genexpr>)rz   r¨   )r„   r‡   rz   r¶   Zsubroutine_args)rl   Zscallrp   rw   rq   Ú_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  rw   rp   rq   r˜   ó  r™   z1FCodePrinter._print_use_rename.<locals>.<genexpr>)Útupler¨   )rl   Úrnmrp   rw   rq   Ú_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 rp   ré   )r“   rs  rw   rp   rq   rÏ   ø  r™   z+FCodePrinter._print_use.<locals>.<listcomp>z, only: c                   s   g | ]}ˆ   |¡‘qS rp   ré   )r“   Znlyrw   rp   rq   rÏ   ú  r™   )r‡   Ú	namespaceÚrenamer¶   Úonly)rl   Zuser#  rp   rw   rq   Ú
_print_useõ  s    
"
"zFCodePrinter._print_usec                 C  s   dS )NÚexitrp   ©rl   ry   rp   rp   rq   Ú_print_BreakTokený  s    zFCodePrinter._print_BreakTokenc                 C  s   dS )NÚcyclerp   rz  rp   rp   rq   Ú_print_ContinueToken   s    z!FCodePrinter._print_ContinueTokenc                   s4   ˆ j d dkrdnd}|d ‡ fdd„|jD ƒ¡ S )NrQ   r[   z[%s]z(/%s/)rë   c                 3  s   | ]}ˆ   |¡V  qd S r‚   ré   r  rw   rp   rq   r˜     r™   z7FCodePrinter._print_ArrayConstructor.<locals>.<genexpr>)rh   r¶   Úelements)rl   ÚacZfmtstrrp   rw   rq   Ú_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  rw   rp   rq   r˜   
  r™   z3FCodePrinter._print_ArrayElement.<locals>.<genexpr>r  )r„   r‡   rz   r¶   r£   r  rp   rw   rq   Ú_print_ArrayElement  s    
þz FCodePrinter._print_ArrayElement)N)[rò   Ú
__module__Ú__qualname__Ú__doc__ZprintmethodÚlanguager   r   r   r   r   r   rX   r   r
   r   r   r   r   r   r   rY   r	  r`   r/   rS   Ú__annotations__Ú
_operatorsrä   rd   Úpropertyrx   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   rM  rO  rQ  rT  r[  r_  ra  rg  rk  rn  rp  rq  rt  rx  r{  r}  r€  r  Ú__classcell__rp   rp   rn   rq   rG   F   sÄ   
ýõÿ
ú
û	ÿ
*'
		!	G2
		
rG   )Er„  Ú
__future__r   Útypingr   Úcollectionsr   Ú	itertoolsr   r9  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   re   rG   rp   rp   rp   rq   Ú<module>   sF   \4ï