o
    ohI                     @   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;Z9d]d<d=Z:d\d>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 )^z
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      t |  S Nr   r     r%   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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   _construct_local_construct_originalr%   r%   r%   r&   r2   6   s
    r2   c                 C   s   t | dr| jS t| S )Nr   )hasattrr   r   argr%   r%   r&   _nameJ   s   
r:   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      t dd | D  S )Nc                 S   s"   g | ]}t |tr|nt| qS r%   )
isinstancer2   .0r9   r%   r%   r&   
<listcomp>c      "  use.<lambda>.<locals>.<listcomp>r   argsr%   r%   r&   r'   c       zuse.<lambda>c                 C   r?   )Nc                 S   s"   g | ]}t |tr|nt|qS r%   )r@   r2   r:   rA   r%   r%   r&   rC   d   rD   rE   r   rF   r%   r%   r&   r'   d   rH   N)r)   r*   r+   r,   r-   r.   r   defaultsr0   r:   _construct_namespace_construct_rename_construct_onlyr%   r%   r%   r&   r;   P   s    
r;   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   declarationsdefinitionsrN   c                 C   s   dd |D }t | S )Nc                 S   s"   g | ]}t |trt|n|qS r%   )r@   strr   rA   r%   r%   r&   rC      rD   z2Module._construct_declarations.<locals>.<listcomp>r#   )clsrG   r%   r%   r&   _construct_declarations}   s   zModule._construct_declarationsc                 C   r!   r"   r#   r8   r%   r%   r&   r'      r(   zModule.<lambda>N)r)   r*   r+   r,   r-   r.   r   rI   r   r/   classmethodrR   r0   _construct_definitionsr%   r%   r%   r&   rM   g   s    

rM   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'      s    zSubroutine.<lambda>c                 C   s   t |tr|S t| S r"   )r@   r   )rQ   itrr%   r%   r&   r1      s   
zSubroutine._construct_bodyN)r)   r*   r+   r,   r-   r   r.   r   r/   r0   _construct_parametersrS   r1   r%   r%   r%   r&   rU      s    
rU   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   subroutine_argsN)r)   r*   r+   r,   r-   r.   r0   r:   r/   r	   _construct_subroutine_argsr%   r%   r%   r&   r\      s
    r\   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   )rc   rd   c                 C   r!   r"   r#   r$   r%   r%   r&   r'      r(   zDo.<lambda>c                 C   s   | rt S tS r"   r   r8   r%   r%   r&   r'      s    N)r)   r*   r+   r,   r-   r.   r   r   rI   r0   r1   r   _construct_counter_construct_first_construct_last_construct_step_construct_concurrentr%   r%   r%   r&   r_      s    r_   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.   r0   r	   _construct_elementsr%   r%   r%   r&   rk      s    rk   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]'

    )exprr`   ra   rb   rc   rc   re   N)r)   r*   r+   r,   r-   r.   r   rI   r0   r   _construct_exprrf   rg   rh   ri   r%   r%   r%   r&   rn      s    rn   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   s`   t |dkr|\}}t| t|t|S t |dks't |dkr,|d dv r,t| S td)N   r   re   ):Nz5Expected 0 or 2 args (or one argument == None or ':'))lenr   __new__r   
ValueError)rQ   rG   lowhighr%   r%   r&   ru     s   $
zExtent.__new__c                 C   s(   t | jdkr	dS ddd | jD S )Nr   rs   c                 s   s    | ]}t |V  qd S r"   )rP   rA   r%   r%   r&   	<genexpr>$  s    z#Extent._sympystr.<locals>.<genexpr>)rt   rG   join)selfprinterr%   r%   r&   	_sympystr!  s   zExtent._sympystrN)r)   r*   r+   r,   ru   r}   r%   r%   r%   r&   rq     s    	rq   c                  G   s   t | dkr
tdg }| D ]8}t|tr|| qt|tr3|dkr+|t  q|t| qt|r?|t|  q|t| qt | dkrQt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 arraysrs   r   zNeed at least one dimension	dimension)
rt   rv   r@   rq   appendrP   r   r   r   r   )rG   rV   r9   r%   r%   r&   r   )  s    


r   *Nr%   )attrsvaluetypec                C   s   t |trt|jdkrtdt| nt| }t||g }|dur8|ttt	fvr3ttt	d| }|
| |du rDtj| ||dS t| |||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

    r   z/Got an unexpected Attribute argument as dim: %sN)inoutinout)r   r   )r@   r   rP   r   rv   r   listr   r   r   r   r
   rX   )symboldimintentr   r   r   r%   r%   r&   arrayN  s   

r   c                 C   s   t | tr	t| S t| S r"   )r@   rP   r   r   r8   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   )r   r%   r%   r&   r     s   r   c                 C   8   t dt| g|rt|gng  |rt|g S 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   r   r   kindr%   r%   r&   r        r   c                 C   r   )Nuboundr   r   r%   r%   r&   r     s   r   c                 C   s&   t dt| g|rt|g S 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   r   )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     r   r   c                 C   s>   t dt| t|g|rt|gng  |rt|g S 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S 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'

    )labelsro   ro   N)r)   r*   r+   r,   r-   r.   r   rI   r0   r	   _construct_labelsr   rp   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   rI   r0   r   _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)   	_settings_required_standardNotImplementedErrorformatrz   rW   _printrG   )r{   r|   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                   @      e Zd ZdZdZdS )isignz/ Fortran sign intrinsic for integer arguments. rr   Nr)   r*   r+   r,   nargsr%   r%   r%   r&   r   U      r   c                   @   r   )dsignz8 Fortran sign intrinsic for double precision arguments. rr   Nr   r%   r%   r%   r&   r   Z  r   r   c                   @   r   )cmplxz& Fortran complex conversion function. rr   Nr   r%   r%   r%   r&   r   _  r   r   c                   @   r   )r   z Fortran kind function. re   Nr   r%   r%   r%   r&   r   d  r   r   c                   @   r   )mergez Fortran merge function    Nr   r%   r%   r%   r&   r   i  r   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r)dn|}|p.d| j | |p6d S )	Nz%.{}ee0.r   re   + )r   	_decimalssplitstriprstriplstrip_token)r{   r|   rG   kwargsmantissasgnd_exex_sgn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                   @      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      r   c                   @   r   )
literal_dpz' Fortran double precision real literal d   Nr   r%   r%   r%   r&   r     r   r   c                   @   .   e Zd Zd ZZeedZeeZ	eeZ
dS )sum_r   r   maskr   r   Nr)   r*   r+   r-   r.   r   rI   r0   r   _construct_array_construct_dimr%   r%   r%   r&   r     
    
r   c                   @   r   )product_r   r   Nr   r%   r%   r%   r&   r     r   r   r"   )NN)Jr,   sympy.codegen.astr   r   r   r   r   r   r   r	   r
   sympy.core.basicr   sympy.core.containersr   sympy.core.exprr   sympy.core.functionr   sympy.core.numbersr   r   sympy.core.symbolr   sympy.core.sympifyr   sympy.logicr   r   sympy.utilities.iterablesr   r   r   r   r   r   r   r   r2   r:   r;   rM   rU   r\   r_   rk   rn   rq   assumed_extentr   assumed_sizer   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>   sl    ,%!#-


	


