U
    9%eI                     @   s  d Z ddlmZmZmZ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 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mZ ddlmZ edZedZ edZ!edZ"edZ#edZ$G dd deZ%G dd deZ&dd Z'G dd deZ(G dd deZ)G dd deZ*G dd deZ+G d d! d!eZ,G d"d# d#eZ-G d$d% d%eZ.G d&d' d'eZ/e/ Z0d(d) Z1e1d*Z2d\d,d+d+d-d.d/Z3d0d1 Z4d2d3 Z5d]d4d5Z6d^d6d7Z7d_d8d9Z8d`d:d;Z9dad<d=Z:dbd>d?Z;G d@dA dAeZ<G dBdC dCeZ=G dDdE dEeZ>G dFdG dGe>Z?G dHdI dIe>Z@G dJdK dKe>ZAG dLdM dMe>ZBG dNdO dOe>ZCG dPdQ dQe?ZDG dRdS dSeZEG dTdU dUeEZFG dVdW dWeEZGG dXdY dYeeZHG dZd[ d[eeZId+S )cz
AST nodes specific to Fortran.

The functions defined in this module allows the user to express functions such as ``dsign``
as a SymPy function for symbolic manipulation.
    )		Attribute	CodeBlockFunctionCallNodenoneStringToken	_mk_TupleVariable)BasicTuple)Expr)Function)FloatInteger)Str)sympifytruefalse)iterablepure	elemental	intent_in
intent_outintent_inoutallocatablec                   @   s(   e Zd ZdZd ZZeZedd Z	dS )Programaf   Represents a 'program' block in Fortran.

    Examples
    ========

    >>> from sympy.codegen.ast import Print
    >>> from sympy.codegen.fnodes import Program
    >>> prog = Program('myprogram', [Print([42])])
    >>> from sympy import fcode
    >>> print(fcode(prog, source_format='free'))
    program myprogram
        print *, 42
    end program

    )namebodyc                 C   s   t |  S Nr   r     r$   S/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/codegen/fnodes.py<lambda>3       zProgram.<lambda>N)
__name__
__module____qualname____doc__	__slots___fieldsr   _construct_namestaticmethod_construct_bodyr$   r$   r$   r%   r   !   s   r   c                   @   s    e Zd ZdZd ZZeZeZdS )
use_renamea   Represents a renaming in a use statement in Fortran.

    Examples
    ========

    >>> from sympy.codegen.fnodes import use_rename, use
    >>> from sympy import fcode
    >>> ren = use_rename("thingy", "convolution2d")
    >>> print(fcode(ren, source_format='free'))
    thingy => convolution2d
    >>> full = use('signallib', only=['snr', ren])
    >>> print(fcode(full, source_format='free'))
    use signallib, only: snr, thingy => convolution2d

    )localoriginalN)	r(   r)   r*   r+   r,   r-   r   Z_construct_localZ_construct_originalr$   r$   r$   r%   r1   6   s   r1   c                 C   s   t | dr| jS t| S d S )Nr   )hasattrr   r   argr$   r$   r%   _nameJ   s    
r7   c                   @   sB   e Zd ZdZd ZZeedZee	Z
edd Zedd ZdS )usea   Represents a use statement in Fortran.

    Examples
    ========

    >>> from sympy.codegen.fnodes import use
    >>> from sympy import fcode
    >>> fcode(use('signallib'), source_format='free')
    'use signallib'
    >>> fcode(use('signallib', [('metric', 'snr')]), source_format='free')
    'use signallib, metric => snr'
    >>> fcode(use('signallib', only=['snr', 'convolution2d']), source_format='free')
    'use signallib, only: snr, convolution2d'

    )	namespacerenameonly)r:   r;   c                 C   s   t dd | D  S )Nc                 S   s"   g | ]}t |tr|nt| qS r$   )
isinstancer1   .0r6   r$   r$   r%   
<listcomp>c   s      use.<lambda>.<locals>.<listcomp>r   argsr$   r$   r%   r&   c   r'   zuse.<lambda>c                 C   s   t dd | D  S )Nc                 S   s"   g | ]}t |tr|nt|qS r$   )r<   r1   r7   r=   r$   r$   r%   r?   d   s     r@   r   rA   r$   r$   r%   r&   d   r'   N)r(   r)   r*   r+   r,   r-   r   defaultsr/   r7   Z_construct_namespaceZ_construct_renameZ_construct_onlyr$   r$   r$   r%   r8   P   s   
r8   c                   @   s>   e Zd ZdZd ZZde iZeZ	e
dd Zedd ZdS )	Modulea\   Represents a module in Fortran.

    Examples
    ========

    >>> from sympy.codegen.fnodes import Module
    >>> from sympy import fcode
    >>> print(fcode(Module('signallib', ['implicit none'], []), source_format='free'))
    module signallib
    implicit none
    <BLANKLINE>
    contains
    <BLANKLINE>
    <BLANKLINE>
    end module

    )r   declarationsZdefinitionsrE   c                 C   s   dd |D }t | S )Nc                 S   s"   g | ]}t |trt|n|qS r$   )r<   strr   r=   r$   r$   r%   r?      s     z2Module._construct_declarations.<locals>.<listcomp>r"   )clsrB   r$   r$   r%   _construct_declarations}   s    zModule._construct_declarationsc                 C   s   t |  S r!   r"   r5   r$   r$   r%   r&      r'   zModule.<lambda>N)r(   r)   r*   r+   r,   r-   r   rC   r   r.   classmethodrH   r/   Z_construct_definitionsr$   r$   r$   r%   rD   g   s   

rD   c                   @   s:   e Zd ZdZdZeej ZeZe	dd Z
edd ZdS )
Subroutinea   Represents a subroutine in Fortran.

    Examples
    ========

    >>> from sympy import fcode, symbols
    >>> from sympy.codegen.ast import Print
    >>> from sympy.codegen.fnodes import Subroutine
    >>> x, y = symbols('x y', real=True)
    >>> sub = Subroutine('mysub', [x, y], [Print([x**2 + y**2, x*y])])
    >>> print(fcode(sub, source_format='free', standard=2003))
    subroutine mysub(x, y)
    real*8 :: x
    real*8 :: y
    print *, x**2 + y**2, x*y
    end subroutine

    )r   
parametersr    c                 C   s   t ttj|  S r!   )r   mapr
   deduced)paramsr$   r$   r%   r&      r'   zSubroutine.<lambda>c                 C   s   t |tr|S t| S d S r!   )r<   r   )rG   itrr$   r$   r%   r0      s    
zSubroutine._construct_bodyN)r(   r)   r*   r+   r,   r   r-   r   r.   r/   Z_construct_parametersrI   r0   r$   r$   r$   r%   rJ      s   
rJ   c                   @   s(   e Zd ZdZd ZZeeZee	Z
dS )SubroutineCallz Represents a call to a subroutine in Fortran.

    Examples
    ========

    >>> from sympy.codegen.fnodes import SubroutineCall
    >>> from sympy import fcode
    >>> fcode(SubroutineCall('mysub', 'x y'.split()))
    '       call mysub(x, y)'

    )r   Zsubroutine_argsN)r(   r)   r*   r+   r,   r-   r/   r7   r.   r	   Z_construct_subroutine_argsr$   r$   r$   r%   rP      s   rP   c                   @   s^   e Zd ZdZd ZZededZe	dd Z
e	eZe	eZe	eZe	eZe	dd ZdS )	Doa   Represents a Do loop in in Fortran.

    Examples
    ========

    >>> from sympy import fcode, symbols
    >>> from sympy.codegen.ast import aug_assign, Print
    >>> from sympy.codegen.fnodes import Do
    >>> i, n = symbols('i n', integer=True)
    >>> r = symbols('r', real=True)
    >>> body = [aug_assign(r, '+', 1/i), Print([i, r])]
    >>> do1 = Do(body, i, 1, n)
    >>> print(fcode(do1, source_format='free'))
    do i = 1, n
        r = r + 1d0/i
        print *, i, r
    end do
    >>> do2 = Do(body, i, 1, n, 2)
    >>> print(fcode(do2, source_format='free'))
    do i = 1, n, 2
        r = r + 1d0/i
        print *, i, r
    end do

    )r    counterfirstlaststep
concurrent   )rU   rV   c                 C   s   t |  S r!   r"   r#   r$   r$   r%   r&      r'   zDo.<lambda>c                 C   s   | rt S tS r!   r   r5   r$   r$   r%   r&      r'   N)r(   r)   r*   r+   r,   r-   r   r   rC   r/   r0   r   _construct_counter_construct_first_construct_last_construct_stepZ_construct_concurrentr$   r$   r$   r%   rQ      s   rQ   c                   @   s    e Zd ZdZd ZZeeZdS )ArrayConstructoraT   Represents an array constructor.

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.fnodes import ArrayConstructor
    >>> ac = ArrayConstructor([1, 2, 3])
    >>> fcode(ac, standard=95, source_format='free')
    '(/1, 2, 3/)'
    >>> fcode(ac, standard=2003, source_format='free')
    '[1, 2, 3]'

    )elementsN)	r(   r)   r*   r+   r,   r-   r/   r	   Z_construct_elementsr$   r$   r$   r%   r\      s   r\   c                   @   sL   e Zd ZdZd ZZdediZee	Z
ee	Zee	Zee	Zee	ZdS )ImpliedDoLoopa   Represents an implied do loop in Fortran.

    Examples
    ========

    >>> from sympy import Symbol, fcode
    >>> from sympy.codegen.fnodes import ImpliedDoLoop, ArrayConstructor
    >>> i = Symbol('i', integer=True)
    >>> idl = ImpliedDoLoop(i**3, i, -3, 3, 2)  # -27, -1, 1, 27
    >>> ac = ArrayConstructor([-28, idl, 28]) # -28, -27, -1, 1, 27, 28
    >>> fcode(ac, standard=2003, source_format='free')
    '[-28, (i**3, i = -3, 3, 2), 28]'

    )exprrR   rS   rT   rU   rU   rW   N)r(   r)   r*   r+   r,   r-   r   rC   r/   r   _construct_exprrX   rY   rZ   r[   r$   r$   r$   r%   r^      s   r^   c                   @   s    e Zd ZdZdd Zdd ZdS )ExtentaC   Represents a dimension extent.

    Examples
    ========

    >>> from sympy.codegen.fnodes import Extent
    >>> e = Extent(-3, 3)  # -3, -2, -1, 0, 1, 2, 3
    >>> from sympy import fcode
    >>> fcode(e, source_format='free')
    '-3:3'
    >>> from sympy.codegen.ast import Variable, real
    >>> from sympy.codegen.fnodes import dimension, intent_out
    >>> dim = dimension(e, e)
    >>> arr = Variable('x', real, attrs=[dim, intent_out])
    >>> fcode(arr.as_Declaration(), source_format='free', standard=2003)
    'real*8, dimension(-3:3, -3:3), intent(out) :: x'

    c                 G   sd   t |dkr*|\}}t| t|t|S t |dksNt |dkrX|d dkrXt| S tdd S )N   r   rW   ):Nz5Expected 0 or 2 args (or one argument == None or ':'))lenr   __new__r   
ValueError)rG   rB   lowhighr$   r$   r%   re     s    $
zExtent.__new__c                 C   s(   t | jdkrdS ddd | jD S )Nr   rc   c                 s   s   | ]}t |V  qd S r!   )rF   r=   r$   r$   r%   	<genexpr>$  s     z#Extent._sympystr.<locals>.<genexpr>)rd   rB   join)selfprinterr$   r$   r%   	_sympystr!  s    zExtent._sympystrN)r(   r)   r*   r+   re   rm   r$   r$   r$   r%   ra     s   	ra   c                  G   s   t | dkrtdg }| D ]p}t|tr6|| qt|trf|dkrV|t  q|t| qt|r~|t|  q|t| qt | dkrtdt	d|S )a   Creates a 'dimension' Attribute with (up to 7) extents.

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.fnodes import dimension, intent_in
    >>> dim = dimension('2', ':')  # 2 rows, runtime determined number of columns
    >>> from sympy.codegen.ast import Variable, integer
    >>> arr = Variable('a', integer, attrs=[dim, intent_in])
    >>> fcode(arr.as_Declaration(), source_format='free', standard=2003)
    'integer*4, dimension(2, :), intent(in) :: a'

       z0Fortran only supports up to 7 dimensional arraysrc   r   zNeed at least one dimension	dimension)
rd   rf   r<   ra   appendrF   r   r   r   r   )rB   rK   r6   r$   r$   r%   ro   )  s     

ro   *Nr$   )attrsvaluetypec                C   s   t |tr*t|jdkr2tdt| nt| }t||g }|dk	rp|ttt	fkrfttt	d| }|
| |dkrtj| ||dS t| |||dS dS )a   Convenience function for creating a Variable instance for a Fortran array.

    Parameters
    ==========

    symbol : symbol
    dim : Attribute or iterable
        If dim is an ``Attribute`` it need to have the name 'dimension'. If it is
        not an ``Attribute``, then it is passed to :func:`dimension` as ``*dim``
    intent : str
        One of: 'in', 'out', 'inout' or None
    \*\*kwargs:
        Keyword arguments for ``Variable`` ('type' & 'value')

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.ast import integer, real
    >>> from sympy.codegen.fnodes import array
    >>> arr = array('a', '*', 'in', type=integer)
    >>> print(fcode(arr.as_Declaration(), source_format='free', standard=2003))
    integer*4, dimension(*), intent(in) :: a
    >>> x = array('x', [3, ':', ':'], intent='out', type=real)
    >>> print(fcode(x.as_Declaration(value=1), source_format='free', standard=2003))
    real*8, dimension(3, :, :), intent(out) :: x = 1

    ro   z/Got an unexpected Attribute argument as dim: %sN)inoutZinout)rs   rr   )r<   r   rF   r   rf   ro   listr   r   r   rp   r
   rM   )symboldimZintentrr   rs   rt   r$   r$   r%   arrayN  s    

rz   c                 C   s   t | trt| S t| S r!   )r<   rF   r   r   r5   r$   r$   r%   
_printable{  s    r{   c                 C   s   t dt| gS )a   Creates an AST node for a function call to Fortran's "allocated(...)"

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.fnodes import allocated
    >>> alloc = allocated('x')
    >>> fcode(alloc, source_format='free')
    'allocated(x)'

    	allocatedr   r{   )rz   r$   r$   r%   r|     s    r|   c                 C   s4   t dt| g|rt|gng  |r,t|gng  S )ap   Creates an AST node for a function call to Fortran's "lbound(...)"

    Parameters
    ==========

    array : Symbol or String
    dim : expr
    kind : expr

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.fnodes import lbound
    >>> lb = lbound('arr', dim=2)
    >>> fcode(lb, source_format='free')
    'lbound(arr, 2)'

    lboundr}   rz   ry   kindr$   r$   r%   r~     s    r~   c                 C   s4   t dt| g|rt|gng  |r,t|gng  S )Nuboundr}   r   r$   r$   r%   r     s    r   c                 C   s"   t dt| g|rt|gng  S )aR   Creates an AST node for a function call to Fortran's "shape(...)"

    Parameters
    ==========

    source : Symbol or String
    kind : expr

    Examples
    ========

    >>> from sympy import fcode
    >>> from sympy.codegen.fnodes import shape
    >>> shp = shape('x')
    >>> fcode(shp, source_format='free')
    'shape(x)'

    shaper}   )sourcer   r$   r$   r%   r     s    r   c                 C   s4   t dt| g|rt|gng  |r,t|gng  S )a   Creates an AST node for a function call to Fortran's "size(...)"

    Examples
    ========

    >>> from sympy import fcode, Symbol
    >>> from sympy.codegen.ast import FunctionDefinition, real, Return
    >>> from sympy.codegen.fnodes import array, sum_, size
    >>> a = Symbol('a', real=True)
    >>> body = [Return((sum_(a**2)/size(a))**.5)]
    >>> arr = array(a, dim=[':'], intent='in')
    >>> fd = FunctionDefinition(real, 'rms', [arr], body)
    >>> print(fcode(fd, source_format='free', standard=2003))
    real*8 function rms(a)
    real*8, dimension(:), intent(in) :: a
    rms = sqrt(sum(a**2)*1d0/size(a))
    end function

    sizer}   r   r$   r$   r%   r     s    r   c                 C   s:   t dt| t|g|r t|gng  |r2t|gng  S )z Creates an AST node for a function call to Fortran's "reshape(...)"

    Parameters
    ==========

    source : Symbol or String
    shape : ArrayExpr

    reshaper}   )r   r   padorderr$   r$   r%   r     s    
r   c                 C   s   t d| rt| gng S )a   Creates an Attribute ``bind_C`` with a name.

    Parameters
    ==========

    name : str

    Examples
    ========

    >>> from sympy import fcode, Symbol
    >>> from sympy.codegen.ast import FunctionDefinition, real, Return
    >>> from sympy.codegen.fnodes import array, sum_, bind_C
    >>> a = Symbol('a', real=True)
    >>> s = Symbol('s', integer=True)
    >>> arr = array(a, dim=[s], intent='in')
    >>> body = [Return((sum_(a**2)/s)**.5)]
    >>> fd = FunctionDefinition(real, 'rms', [arr, s], body, attrs=[bind_C('rms')])
    >>> print(fcode(fd, source_format='free', standard=2003))
    real*8 function rms(a, s) bind(C, name="rms")
    real*8, dimension(s), intent(in) :: a
    integer*4 :: s
    rms = sqrt(sum(a**2)/s)
    end function

    bind_C)r   r   )r   r$   r$   r%   r     s    r   c                   @   s0   e Zd ZdZd ZZdeiZee	Z
eeZdS )GoToa    Represents a goto statement in Fortran

    Examples
    ========

    >>> from sympy.codegen.fnodes import GoTo
    >>> go = GoTo([10, 20, 30], 'i')
    >>> from sympy import fcode
    >>> fcode(go, source_format='free')
    'go to (10, 20, 30), i'

    )labelsr_   r_   N)r(   r)   r*   r+   r,   r-   r   rC   r/   r	   Z_construct_labelsr   r`   r$   r$   r$   r%   r     s
   r   c                   @   s(   e Zd ZdZd ZZdeiZee	Z
dS )FortranReturnaK   AST node explicitly mapped to a fortran "return".

    Explanation
    ===========

    Because a return statement in fortran is different from C, and
    in order to aid reuse of our codegen ASTs the ordinary
    ``.codegen.ast.Return`` is interpreted as assignment to
    the result variable of the function. If one for some reason needs
    to generate a fortran RETURN statement, this node should be used.

    Examples
    ========

    >>> from sympy.codegen.fnodes import FortranReturn
    >>> from sympy import fcode
    >>> fcode(FortranReturn('x'))
    '       return x'

    )return_valuer   N)r(   r)   r*   r+   r,   r-   r   rC   r/   r   Z_construct_return_valuer$   r$   r$   r%   r   ,  s   r   c                   @   s   e Zd ZdZdd ZdS )	FFunctionM   c                 C   sF   | j j}|jd | jk r*td|| jf d|dt|j| j	S )Nstandardz%s requires Fortran %d or newerz{}({})z, )
	__class__r(   Z	_settings_required_standardNotImplementedErrorformatrj   rL   Z_printrB   )rk   rl   r   r$   r$   r%   _fcodeI  s    zFFunction._fcodeN)r(   r)   r*   r   r   r$   r$   r$   r%   r   F  s   r   c                   @   s   e Zd ZdZdS )F95Function_   N)r(   r)   r*   r   r$   r$   r$   r%   r   Q  s   r   c                   @   s   e Zd ZdZdZdS )isignz/ Fortran sign intrinsic for integer arguments. rb   Nr(   r)   r*   r+   nargsr$   r$   r$   r%   r   U  s   r   c                   @   s   e Zd ZdZdZdS )dsignz8 Fortran sign intrinsic for double precision arguments. rb   Nr   r$   r$   r$   r%   r   Z  s   r   c                   @   s   e Zd ZdZdZdS )cmplxz& Fortran complex conversion function. rb   Nr   r$   r$   r$   r%   r   _  s   r   c                   @   s   e Zd ZdZdZdS )r   z Fortran kind function. rW   Nr   r$   r$   r$   r%   r   d  s   r   c                   @   s   e Zd ZdZdZdS )mergez Fortran merge function    Nr   r$   r$   r$   r%   r   i  s   r   c                   @   s   e Zd ZdZdZdd ZdS )_literalNc                 O   sp   d | j|  d\}}|dd}|d |dd  d }}|dkrRdn|}|p\d| j | |pld S )	Nz%.{}ee0.r   rW   + )r   	_decimalssplitstriprstriplstrip_token)rk   rl   rB   kwargsZmantissaZsgnd_exZex_sgnZex_numr$   r$   r%   r   r  s
    z_literal._fcode)r(   r)   r*   r   r   r   r$   r$   r$   r%   r   n  s   r   c                   @   s   e Zd ZdZdZdZdS )
literal_spz' Fortran single precision real literal r   	   Nr(   r)   r*   r+   r   r   r$   r$   r$   r%   r   z  s   r   c                   @   s   e Zd ZdZdZdZdS )
literal_dpz' Fortran double precision real literal d   Nr   r$   r$   r$   r%   r     s   r   c                   @   s.   e Zd Zd ZZeedZeeZ	eeZ
dS )sum_rz   ry   maskry   r   Nr(   r)   r*   r,   r-   r   rC   r/   r   Z_construct_arrayZ_construct_dimr$   r$   r$   r%   r     s   
r   c                   @   s.   e Zd Zd ZZeedZeeZ	eeZ
dS )product_r   r   Nr   r$   r$   r$   r%   r     s   
r   )N)NN)NN)N)NN)NN)N)Jr+   Zsympy.codegen.astr   r   r   r   r   r   r   r	   r
   Zsympy.core.basicr   Zsympy.core.containersr   Zsympy.core.exprr   Zsympy.core.functionr   Zsympy.core.numbersr   r   Zsympy.core.symbolr   Zsympy.core.sympifyr   Zsympy.logicr   r   Zsympy.utilities.iterablesr   r   r   r   r   r   r   r   r1   r7   r8   rD   rJ   rP   rQ   r\   r^   ra   Zassumed_extentro   Zassumed_sizerz   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%   <module>   sj   ,%!#-

	



