
    wgI                        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e      Z% G d de      Z&d Z' G d de      Z( G d de      Z) G d de      Z* G d de      Z+ G d d e      Z, G d! d"e      Z- G d# d$e      Z. G d% d&e      Z/ e/       Z0d' Z1 e1d(      Z2dQd*d)d)d+d,Z3d- Z4d. Z5dRd/Z6dRd0Z7dQd1Z8dRd2Z9dRd3Z:dQd4Z; G d5 d6e      Z< G d7 d8e      Z= G d9 d:e      Z> G d; d<e>      Z? G d= d>e>      Z@ G d? d@e>      ZA G dA dBe>      ZB G dC dDe>      ZC G dE dFe?      ZD G dG dHe      ZE G dI dJeE      ZF G dK dLeE      ZG G dM dNee      ZH G dO dPee      ZIy))Sz
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                   .    e Zd ZdZdxZZeZ ed       Z	y)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                     t        |  S Nr   r!   s    Y/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/codegen/fnodes.py<lambda>zProgram.<lambda>3       	40@     N)
__name__
__module____qualname____doc__	__slots___fieldsr   _construct_namestaticmethod_construct_body r)   r&   r   r   !   s#     +*IO"#@AOr)   r   c                        e Zd ZdZdxZZeZeZy)
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_originalr3   r)   r&   r5   r5   6   s     0/I r)   r5   c                 H    t        | d      r| j                  S t        |       S )Nr    )hasattrr    r   args    r&   _namer>   J   s    sFxxc{r)   c                   V    e Zd ZdZdxZZeedZ ee	      Z
 ed       Z ed       Zy)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)rB   rC   c           	      h    t        | D cg c]  }t        |t              r|nt        |  c} S c c}w r#   )r   
isinstancer5   argsr=   s     r&   r'   zuse.<lambda>c   sA    %  C  :DwzCQ[A\#blnqbr:r  :D  3E   :Ds   !/c           	      n    t        | D cg c]  }t        |t              r|n
t        |      ! c} S c c}w r#   )r   rE   r5   r>   rF   s     r&   r'   zuse.<lambda>d   s0    vz7{orz#z?Z`efi`j8j7{0| 7{s   $2N)r*   r+   r,   r-   r.   r/   r   defaultsr1   r>   _construct_namespace_construct_rename_construct_onlyr3   r)   r&   r@   r@   P   sE     :9I-H'.$  &E  F"#|}Or)   r@   c                   P    e Zd ZdZdxZZd e       iZeZ	e
d        Z ed       Zy)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definitionsrO   c                 p    |D cg c]  }t        |t              rt        |      n|! }}t        | S c c}w r#   )rE   strr   r   )clsrG   r=   s      r&   _construct_declarationszModule._construct_declarations}   s8    EIJcJsC0Cc9JJ$ Ks   $3c                     t        |  S r#   r$   r<   s    r&   r'   zModule.<lambda>   s
    io r)   N)r*   r+   r,   r-   r.   r/   r   rI   r   r0   classmethodrT   r1   _construct_definitionsr3   r)   r&   rN   rN   g   sE    " BAI(HO    **EFr)   rN   c                   X    e Zd ZdZdZeej                  z   ZeZ e	d       Z
ed        Zy)
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                 B    t        t        t        j                  |        S r#   )r   mapr   deduced)paramss    r&   r'   zSubroutine.<lambda>   s    s8CSCSU[?\8] r)   c                 6    t        |t              r|S t        | S r#   )rE   r   )rS   itrs     r&   r2   zSubroutine._construct_body   s    c9%Jc?"r)   N)r*   r+   r,   r-   r.   r   r/   r   r0   r1   _construct_parametersrV   r2   r3   r)   r&   rY   rY      s?    $ /I$,,&GO()]^# #r)   rY   c                   8    e Zd ZdZdxZZ ee      Z ee	      Z
y)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/   r1   r>   r0   r
   _construct_subroutine_argsr3   r)   r&   rc   rc      s(    
 65I"5)O!-i!8r)   rc   c                       e Zd ZdZdxZZ ed      edZ e	d       Z
 e	e      Z e	e      Z e	e      Z e	e      Z e	d       Zy)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   )rk   rl   c                     t        |  S r#   r$   r%   s    r&   r'   zDo.<lambda>   r(   r)   c                     | rt         S t        S r#   r   r<   s    r&   r'   zDo.<lambda>   s    ST e r)   N)r*   r+   r,   r-   r.   r/   r   r   rI   r1   r2   r   _construct_counter_construct_first_construct_last_construct_step_construct_concurrentr3   r)   r&   rg   rg      sc    4 UTI
%8H"#@AO%g.#G,"7+O"7+O()KLr)   rg   c                   (    e Zd ZdZdxZZ ee      Zy)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/   r1   r
   _construct_elementsr3   r)   r&   rv   rv      s     ('I&y1r)   rv   c                   |    e Zd ZdZdxZZd ed      iZ ee	      Z
 ee	      Z ee	      Z ee	      Z ee	      Zy)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]'

    )exprrh   ri   rj   rk   rk   rm   N)r*   r+   r,   r-   r.   r/   r   rI   r1   r   _construct_exprrp   rq   rr   rs   r3   r)   r&   rz   rz      sV     GFI
#H"7+O%g.#G,"7+O"7+Or)   rz   c                       e Zd ZdZd Zd Zy)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                     t        |      dk(  r.|\  }}t        j                  | t        |      t        |            S t        |      dk(  st        |      dk(  r|d   dv rt        j                  |       S t	        d      )N   r   rm   ):Nz5Expected 0 or 2 args (or one argument == None or ':'))lenr   __new__r   
ValueError)rS   rG   lowhighs       r&   r   zExtent.__new__  sl    t9>IC==gclGDMBBY!^D	Q47k3I==%%TUUr)   c                 x    t        | j                        dk(  rydj                  d | j                  D              S )Nr   r   c              3   2   K   | ]  }t        |        y wr#   )rR   ).0r=   s     r&   	<genexpr>z#Extent._sympystr.<locals>.<genexpr>$  s     6SC6s   )r   rG   join)selfprinters     r&   	_sympystrzExtent._sympystr!  s.    tyy>Qxx6DII666r)   N)r*   r+   r,   r-   r   r   r3   r)   r&   r~   r~     s    $V7r)   r~   c                     t        |       dkD  rt        d      g }| D ]  }t        |t              r|j	                  |       %t        |t
              r:|dk(  r|j	                  t                      T|j	                  t        |             ot        |      r|j	                  t        |        |j	                  t        |              t        |       dk(  rt        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 arraysr   r   zNeed at least one dimension	dimension)
r   r   rE   r~   appendrR   r   r   r   r   )rG   rZ   r=   s      r&   r   r   )  s     4y1}KLLJ ,c6"c"S!cz!!&(+!!&+.c]fcl+gcl+, 4yA~677[*--r)   *Nr3   )attrsvaluetypec                v   t        |t              r/t        |j                        dk7  rt	        dt        |      z        t        | }t        |      |gz   }|9|t        t        t        fvrt        t        t        d|   }|j                  |       |t        j                  | ||      S t        | |||      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: %s)inoutinout)r   r   )rE   r   rR   r    r   r   listr   r   r   r   r   r]   )symboldimintentr   r   r   s         r&   arrayr   N  s    : #y!sxx=K'NQTUXQYYZZoK3%E)Z>>%j<PQWXFV|e5AAE??r)   c                 N    t        | t              rt        |       S t        |       S r#   )rE   rR   r   r   r<   s    r&   
_printabler   {  s    $S#.6#;@GCL@r)   c                 .    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   s    r&   r   r     s     j&7%899r)   c                 ~    t        dt        |       g|rt        |      gng z   |rt        |      gz         S g z         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   kinds      r&   r   r     sX    ( 	E	!*S/	r	+#*T
		-  *,	- r)   c                 ~    t        dt        |       g|rt        |      gng z   |rt        |      gz         S g z         S )Nuboundr   r   s      r&   r   r     sV    	E	!*S/	r	+#*T
		-  *,	- r)   c                 \    t        dt        |       g|rt        |      gz         S g z         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   s     r&   r   r     sE    & 	F	#*T
		-  *,	- r)   c                 ~    t        dt        |       g|rt        |      gng z   |rt        |      gz         S g z         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   s      r&   r   r     sX    ( 	E	!*S/	r	+#*T
		-  *,	- r)   c                     t        dt        |       t        |      g|rt        |      gng z   |rt        |      gz         S g z         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orders       r&   r   r     s_     	F	Z./!*S/	r	+ #*U
		-  *,	- r)   c                 >    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    s    r&   r   r     s!    6 Xt~>>2>>r)   c                   @    e Zd ZdZdxZZdeiZ ee	      Z
 ee      Zy)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   rI   r1   r
   _construct_labelsr   r|   r3   r)   r&   r   r     s1     -,I~H$Y/"7+Or)   r   c                   0    e Zd ZdZdxZZdeiZ ee	      Z
y)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   r1   r   _construct_return_valuer3   r)   r&   r   r   ,  s(    ( ,+I%H*73r)   r   c                       e Zd ZdZd Zy)	FFunctionM   c           	         | j                   j                  }|j                  d   | j                  k  rt	        d|| j                  fz        dj                  |dj                  t        |j                  | j                                    S )Nstandardz%s requires Fortran %d or newerz{}({})z, )
	__class__r*   	_settings_required_standardNotImplementedErrorformatr   r\   _printrG   )r   r   r    s      r&   _fcodezFFunction._fcodeI  sy    ~~&&Z(4+B+BB%&G'+T-D-D&E'F G GtTYYs7>>499/M%NOOr)   N)r*   r+   r,   r   r   r3   r)   r&   r   r   F  s    Pr)   r   c                       e Zd ZdZy)F95Function_   N)r*   r+   r,   r   r3   r)   r&   r   r   Q  s    r)   r   c                       e Zd ZdZdZy)isignz/ Fortran sign intrinsic for integer arguments. r   Nr*   r+   r,   r-   nargsr3   r)   r&   r   r   U  s
    9Er)   r   c                       e Zd ZdZdZy)dsignz8 Fortran sign intrinsic for double precision arguments. r   Nr   r3   r)   r&   r   r   Z  s
    BEr)   r   c                       e Zd ZdZdZy)cmplxz& Fortran complex conversion function. r   Nr   r3   r)   r&   r   r   _  s
    0Er)   r   c                       e Zd ZdZdZy)r   z Fortran kind function. rm   Nr   r3   r)   r&   r   r   d  
    "Er)   r   c                       e Zd ZdZdZy)mergez Fortran merge function    Nr   r3   r)   r&   r   r   i  r   r)   r   c                       e Zd ZdZdZd Zy)_literalNc                     dj                  | j                        | z  j                  d      \  }}|j                  d      j	                  d      }|d   |dd  j                  d      }}|dk(  rdn|}|xs d| j                  z   |z   |xs dz   S )	Nz%.{}ee0.r   rm   + )r   	_decimalssplitstriprstriplstrip_token)r   r   rG   kwargsmantissasgnd_exex_sgnex_nums           r&   r   z_literal._fcoder  s    $^^DNN;dBII#N'>>#&--c2 WQR[%7%7%<}&C4;;.76=SIIr)   )r*   r+   r,   r   r   r   r3   r)   r&   r   r   n  s    FIJr)   r   c                       e Zd ZdZdZdZy)
literal_spz' Fortran single precision real literal r   	   Nr*   r+   r,   r-   r   r   r3   r)   r&   r   r   z  s    1FIr)   r   c                       e Zd ZdZdZdZy)
literal_dpz' Fortran double precision real literal d   Nr   r3   r)   r&   r   r     s    1FIr)   r   c                   >    e Zd ZdxZZeedZ ee      Z	 ee      Z
y)sum_r   r   maskr   r   Nr*   r+   r,   r.   r/   r   rI   r1   r   _construct_array_construct_dimr3   r)   r&   r   r     +    22IT*H#G,!'*Nr)   r   c                   >    e Zd ZdxZZeedZ ee      Z	 ee      Z
y)product_r   r   Nr   r3   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   r5   r>   r@   rN   rY   rc   rg   rv   rz   r~   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   r3   r)   r&   <module>r     s     # '   ( - ! & # . k"	k"	|$
(&Be B*! !(~% ~.GU G<# #>9U 9""M "MJ2u 2&,E ,07U 7B  .F ~+@Rt$ +@ZA: 848$?:,5 ,&4E 44P P) I 
I 
I 
9 
K 
	Ju 	J  +5$ ++ud +r)   