
    wg'                     0    d Z ddlmZ  G d d      ZddZy)z3Tools for manipulation of expressions using paths.     )Basicc                   F    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
dd
Zd Zy	)EPatha3  
    Manipulate expressions using paths.

    EPath grammar in EBNF notation::

        literal   ::= /[A-Za-z_][A-Za-z_0-9]*/
        number    ::= /-?\d+/
        type      ::= literal
        attribute ::= literal "?"
        all       ::= "*"
        slice     ::= "[" number? (":" number? (":" number?)?)? "]"
        range     ::= all | slice
        query     ::= (type | attribute) ("|" (type | attribute))*
        selector  ::= range | query range?
        path      ::= "/" selector ("/" selector)*

    See the docstring of the epath() function.

    )_path_epathc                 
   t        |t              r|S |st        d      |}|d   dk(  r|dd }nt        d      g }|j	                  d      D ]v  }|j                         }|st        d      d}|D ]  }|j                         s|dv r|dz  } n g }g }|rt|d| }	||d }|	j	                  d	      D ]V  }
|
j                         }
|
st        d
      |
j                  d      r|j                  |
dd        F|j                  |
       X d}|dk(  rn|j                  d      r~	 |j                  d      }|d| g }}d|vrt        |      }nM|j	                  dd      D ]0  }|s|j                  d       |j                  t        |             2 t        | }||dz   d }|rt        d      |j                  |||f       y t        j                  |       }||_        ||_        |S # t        $ r t        d      w xY w)zConstruct new EPath. zempty EPathr   /   Nznon-root EPathzempty selector)_|?r   zempty elementr   *[]zexpected ']', got EOL:   ztrailing characters in selector)
isinstancer   
ValueErrorNotImplementedErrorsplitstripisalnumendswithappend
startswithindexintsliceobject__new__r   r   )clspathr   epathselectorr   cattrstypeselementselementspani_spaneltobjs                   ^/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/simplify/epathtools.pyr!   zEPath.__new__   s@   dE"K]++7c>8D%&677

3 =	/H~~'H !122E 99;!"6QJE	 EE#FU+#EF+'~~c2 	.G%mmoG"(99'',WSb\2W-	. D3&&s+B$NN3/ #+1Q-4E%'"5z#(;;sA#6 6C#& $D 1 $CH 5	6  %d|'A/H$%FGGLL%-.{=	/~ nnS!	

9 & B()@AABs   'G--Hc                 N    | j                   j                  d| j                  dS )N())	__class____name__r   )selfs    r0   __repr__zEPath.__repr__t   s    >>22DJJ??    c                     |j                   r|j                         S |j                  r|j                         S |j                  S )z)Sort ``expr.args`` using printing order. )is_Addas_ordered_termsis_Mulas_ordered_factorsargs)r6   exprs     r0   _get_ordered_argszEPath._get_ordered_argsw   s8    ;;((**[[**,,99r8   c                 .    |D ]  }t        ||      r y y)z(Check if ``expr`` has any of ``attrs``. FT)hasattr)r6   r?   r'   attrs       r0   	_hasattrszEPath._hasattrs   s#     	D4&	 r8   c                     |j                   j                         D cg c]  }|j                   }}t        t	        |      j                  |            S c c}w )z'Check if ``expr`` is any of ``types``. )r4   mror5   boolsetintersection)r6   r?   r(   r"   _typess        r0   	_hastypeszEPath._hastypes   sF    +/>>+=+=+?AC3<<AACK,,U344 Bs   Ac                 b    |s|sy|r| j                  ||      ry|r| j                  ||      ryy)z3Apply ``_hasattrs`` and ``_hastypes`` to ``expr``. TF)rD   rK   )r6   r?   r'   r(   s       r0   _hasz
EPath._has   s3    T^^D%0T^^D%0r8   Nc                 h      fd|xs d|xs i cfd}  j                   ||      S )aj  
        Modify parts of an expression selected by a path.

        Examples
        ========

        >>> from sympy.simplify.epathtools import EPath
        >>> from sympy import sin, cos, E
        >>> from sympy.abc import x, y, z, t

        >>> path = EPath("/*/[0]/Symbol")
        >>> expr = [((x, 1), 2), ((3, y), z)]

        >>> path.apply(expr, lambda expr: expr**2)
        [((x**2, 1), 2), ((3, y**2), z)]

        >>> path = EPath("/*/*/Symbol")
        >>> expr = t + sin(x + 1) + cos(x + y + E)

        >>> path.apply(expr, lambda expr: 2*expr)
        t + sin(2*x + 1) + cos(2*x + 2*y + E)

        c                 ,   | s ||      S | d   | dd  } }|\  }}}t        |t              r"|j                  sj                  |      d}}n|S t	        |d      r|d}}n|S t        |      }|5t        |t              r!t        |j                  t        |             }	n|g}	nt        t        |            }	|	D ])  }
	 ||
   }j                  |||      s | ||      ||
<   + |r |j                  | S |j                  |      S # t        $ r Y Yw xY w)Nr   r
   T__iter__F)r   r   is_Atomr@   rB   listr   rangeindiceslen
IndexErrorrM   funcr4   )r#   r?   rW   r%   r'   r(   r+   r>   basicrT   r,   arg_applyr6   s               r0   rZ   zEPath.apply.<locals>._apply   s0   Dz!!%a$qr($%-"uddE*<<&*&<&<T&BDe#T:."&%DKDz#!$."'c$i)@"A#'&#CI.G  :A!"1g yyeU3"(sD"9Q: $499d++>>$// & ! !s   =D	DD c                      | gi S )Nr[   )r?   _args_kwargsrW   s    r0   <lambda>zEPath.apply.<locals>.<lambda>   s    T$::': r8   r   )	r6   r?   rW   r>   kwargs_funcrZ   r]   r^   s	   ` `   @@@r0   applyzEPath.apply   s6    0'	0R V\rw:dkk4//r8   c                 D     g  fd  j                   |       S )a  
        Retrieve parts of an expression selected by a path.

        Examples
        ========

        >>> from sympy.simplify.epathtools import EPath
        >>> from sympy import sin, cos, E
        >>> from sympy.abc import x, y, z, t

        >>> path = EPath("/*/[0]/Symbol")
        >>> expr = [((x, 1), 2), ((3, y), z)]

        >>> path.select(expr)
        [x, y]

        >>> path = EPath("/*/*/Symbol")
        >>> expr = t + sin(x + 1) + cos(x + y + E)

        >>> path.select(expr)
        [x, x, y]

        c                 V   | s	j                  |       y | d   | dd  } }|\  }}}t        |t              r
j                  |      }nt	        |d      r|}ny |t        |t
              r||   }n	 ||   g}|D ]  }
j                  |||      s | |       ! y # t        $ r Y y w xY w)Nr   r
   rP   )r   r   r   r@   rB   r   rV   rM   )r#   r?   r%   r'   r(   r+   r>   rY   _selectresultr6   s           r0   rf   zEPath.select.<locals>._select   s    d#!%a$qr($%-"uddE*11$7DT:.D#!$.#Dz#$(J<D   +CyyeU3c*+  * #"#s   1B 	B('B(r`   )r6   r?   rf   rg   s   ` @@r0   selectzEPath.select   s$    0 	+6 	T"r8   )NN)r5   
__module____qualname____doc__	__slots__r!   r7   r@   rD   rK   rM   rc   rh   r[   r8   r0   r   r      s;    ( $IUn@5
D0L6r8   r   Nc                 n    t        |       }||S ||j                  |      S |j                  ||||      S )a  
    Manipulate parts of an expression selected by a path.

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

    This function allows to manipulate large nested expressions in single
    line of code, utilizing techniques to those applied in XML processing
    standards (e.g. XPath).

    If ``func`` is ``None``, :func:`epath` retrieves elements selected by
    the ``path``. Otherwise it applies ``func`` to each matching element.

    Note that it is more efficient to create an EPath object and use the select
    and apply methods of that object, since this will compile the path string
    only once.  This function should only be used as a convenient shortcut for
    interactive use.

    This is the supported syntax:

    * select all: ``/*``
          Equivalent of ``for arg in args:``.
    * select slice: ``/[0]`` or ``/[1:5]`` or ``/[1:5:2]``
          Supports standard Python's slice syntax.
    * select by type: ``/list`` or ``/list|tuple``
          Emulates ``isinstance()``.
    * select by attribute: ``/__iter__?``
          Emulates ``hasattr()``.

    Parameters
    ==========

    path : str | EPath
        A path as a string or a compiled EPath.
    expr : Basic | iterable
        An expression or a container of expressions.
    func : callable (optional)
        A callable that will be applied to matching parts.
    args : tuple (optional)
        Additional positional arguments to ``func``.
    kwargs : dict (optional)
        Additional keyword arguments to ``func``.

    Examples
    ========

    >>> from sympy.simplify.epathtools import epath
    >>> from sympy import sin, cos, E
    >>> from sympy.abc import x, y, z, t

    >>> path = "/*/[0]/Symbol"
    >>> expr = [((x, 1), 2), ((3, y), z)]

    >>> epath(path, expr)
    [x, y]
    >>> epath(path, expr, lambda expr: expr**2)
    [((x**2, 1), 2), ((3, y**2), z)]

    >>> path = "/*/*/Symbol"
    >>> expr = t + sin(x + 1) + cos(x + y + E)

    >>> epath(path, expr)
    [x, x, y]
    >>> epath(path, expr, lambda expr: 2*expr)
    t + sin(2*x + 1) + cos(2*x + 2*y + E)

    )r   rh   rc   )r#   r?   rW   r>   ra   r   s         r0   r$   r$     sA    H 4[F||}}T""||D$f55r8   )NNNN)rk   
sympy.corer   r   r$   r[   r8   r0   <module>ro      s    9 P PfK6r8   