
    wg4!                    D   d Z ddlmZ g dZddlmZ ddlmZ  G d 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 e	       Z e
       Z e       Z ee      Z ee      Z ee      ZeeeeeedZddZ G d d      Zd Zy)z#Definitions of monomial orderings.     )annotations)lexgrlexgrevlexilexigrlexigrevlex)Symbol)iterablec                  V    e Zd ZU dZdZded<   dZded<   dZd Zd	 Z	d
 Z
d Zd Zd Zy)MonomialOrderz#Base class for monomial orderings. Nz
str | Nonealiaszbool | None	is_globalFc                4    | j                   j                  dz   S )Nz())	__class____name__selfs    Z/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/polys/orderings.py__repr__zMonomialOrder.__repr__   s    ~~&&--    c                    | j                   S N)r   r   s    r   __str__zMonomialOrder.__str__   s    zzr   c                    t         r   )NotImplementedErrorr   monomials     r   __call__zMonomialOrder.__call__   s    !!r   c                4    | j                   |j                   k(  S r   )r   r   others     r   __eq__zMonomialOrder.__eq__   s    ~~00r   c                ,    t        | j                        S r   )hashr   r   s    r   __hash__zMonomialOrder.__hash__   s    DNN##r   c                    | |k(   S r    r!   s     r   __ne__zMonomialOrder.__ne__    s    EM""r   )r   
__module____qualname____doc__r   __annotations__r   
is_defaultr   r   r   r#   r&   r)   r(   r   r   r   r   
   s<    -E:!I{!J."1$#r   r   c                  "    e Zd ZdZdZdZdZd Zy)LexOrderz"Lexicographic order of monomials. r   Tc                    |S r   r(   r   s     r   r   zLexOrder.__call__*   s    r   N)r   r*   r+   r,   r   r   r.   r   r(   r   r   r0   r0   #   s    ,EIJr   r0   c                      e Zd ZdZdZdZd Zy)GradedLexOrderz)Graded lexicographic order of monomials. r   Tc                    t        |      |fS r   )sumr   s     r   r   zGradedLexOrder.__call__3   s    Hx((r   Nr   r*   r+   r,   r   r   r   r(   r   r   r3   r3   -   s    3EI)r   r3   c                      e Zd ZdZdZdZd Zy)ReversedGradedLexOrderz2Reversed graded lexicographic order of monomials. r   Tc           	     h    t        |      t        t        |D cg c]  }|  c}            fS c c}w r   )r5   tuplereversed)r   r   ms      r   r   zReversedGradedLexOrder.__call__<   s+    HuX8.Dar.D%EFGG.Ds   
/Nr6   r(   r   r   r8   r8   6   s    <EIHr   r8   c                  D    e Zd ZdZd Zd Zd Zd Zd Zd Z	e
d        Zy	)
ProductOrderab  
    A product order built from other monomial orders.

    Given (not necessarily total) orders O1, O2, ..., On, their product order
    P is defined as M1 > M2 iff there exists i such that O1(M1) = O2(M2),
    ..., Oi(M1) = Oi(M2), O{i+1}(M1) > O{i+1}(M2).

    Product orders are typically built from monomial orders on different sets
    of variables.

    ProductOrder is constructed by passing a list of pairs
    [(O1, L1), (O2, L2), ...] where Oi are MonomialOrders and Li are callables.
    Upon comparison, the Li are passed the total monomial, and should filter
    out the part of the monomial to pass to Oi.

    Examples
    ========

    We can use a lexicographic order on x_1, x_2 and also on
    y_1, y_2, y_3, and their product on {x_i, y_i} as follows:

    >>> from sympy.polys.orderings import lex, grlex, ProductOrder
    >>> P = ProductOrder(
    ...     (lex, lambda m: m[:2]), # lex order on x_1 and x_2 of monomial
    ...     (grlex, lambda m: m[2:]) # grlex on y_1, y_2, y_3
    ... )
    >>> P((2, 1, 1, 0, 0)) > P((1, 10, 0, 2, 0))
    True

    Here the exponent `2` of `x_1` in the first monomial
    (`x_1^2 x_2 y_1`) is bigger than the exponent `1` of `x_1` in the
    second monomial (`x_1 x_2^10 y_2^2`), so the first monomial is greater
    in the product ordering.

    >>> P((2, 1, 1, 0, 0)) < P((2, 1, 0, 2, 0))
    True

    Here the exponents of `x_1` and `x_2` agree, so the grlex order on
    `y_1, y_2, y_3` is used to decide the ordering. In this case the monomial
    `y_2^2` is ordered larger than `y_1`, since for the grlex order the degree
    of the monomial is most important.
    c                    || _         y r   )args)r   r@   s     r   __init__zProductOrder.__init__k   s	    	r   c                @    t        fd| j                  D              S )Nc              3  @   K   | ]  \  }} | |              y wr   r(   ).0Olamdar   s      r   	<genexpr>z(ProductOrder.__call__.<locals>.<genexpr>o   s     DJQQuX'Ds   )r:   r@   r   s    `r   r   zProductOrder.__call__n   s    D$))DDDr   c                    | j                   D cg c]  }t        |d          }}| j                  j                  dz   dj	                  |      z   dz   S c c}w Nr   (z, ))r@   reprr   r   joinr   xcontentss      r   r   zProductOrder.__repr__q   sN    (,		21D1J22~~&&,tyy/BBSHH 3   Ac                    | j                   D cg c]  }t        |d          }}| j                  j                  dz   dj	                  |      z   dz   S c c}w rI   )r@   strr   r   rM   rN   s      r   r   zProductOrder.__str__u   sN    '+yy1!C!I11~~&&,tyy/BBSHH 2rQ   c                V    t        |t              sy| j                  |j                  k(  S NF)
isinstancer>   r@   r!   s     r   r#   zProductOrder.__eq__y   s"    %.yyEJJ&&r   c                D    t        | j                  | j                  f      S r   )r%   r   r@   r   s    r   r&   zProductOrder.__hash__~   s    T^^TYY/00r   c                x    t        d | j                  D              ryt        d | j                  D              ryy )Nc              3  >   K   | ]  \  }}|j                   d u   yw)TNr   rD   o_s      r   rG   z)ProductOrder.is_global.<locals>.<genexpr>   s     9tq!q{{d"9   Tc              3  >   K   | ]  \  }}|j                   d u   yw)FNrZ   r[   s      r   rG   z)ProductOrder.is_global.<locals>.<genexpr>   s     :1q{{e#:r^   F)allr@   r   s    r   r   zProductOrder.is_global   s/    9tyy99:		::r   N)r   r*   r+   r,   rA   r   r   r   r#   r&   propertyr   r(   r   r   r>   r>   ?   s=    )VEII'
1  r   r>   c                  >    e Zd ZdZd Zd Zd Zed        Zd Z	d Z
y)	InverseOrdera!  
    The "inverse" of another monomial order.

    If O is any monomial order, we can construct another monomial order iO
    such that `A >_{iO} B` if and only if `B >_O A`. This is useful for
    constructing local orders.

    Note that many algorithms only work with *global* orders.

    For example, in the inverse lexicographic order on a single variable `x`,
    high powers of `x` count as small:

    >>> from sympy.polys.orderings import lex, InverseOrder
    >>> ilex = InverseOrder(lex)
    >>> ilex((5,)) < ilex((0,))
    True
    c                    || _         y r   rE   )r   rE   s     r   rA   zInverseOrder.__init__   s	    r   c                2    dt        | j                        z   S )Ni)rS   rE   r   s    r   r   zInverseOrder.__str__   s    S[  r   c                <    fd | j                  |            S )Nc                H    t        |       rt        fd| D              S |  S )Nc              3  .   K   | ]  } |        y wr   r(   )rD   rO   invs     r   rG   z5InverseOrder.__call__.<locals>.inv.<locals>.<genexpr>   s     /SV/s   )r   r:   )lrk   s    r   rk   z"InverseOrder.__call__.<locals>.inv   s"    {/Q///2Ir   re   )r   r   rk   s     @r   r   zInverseOrder.__call__   s    	 466(#$$r   c                h    | j                   j                  du ry| j                   j                  du ryy )NTF)rE   r   r   s    r   r   zInverseOrder.is_global   s/    66t#66u$r   c                X    t        |t              xr |j                  | j                  k(  S r   )rV   rc   rE   r!   s     r   r#   zInverseOrder.__eq__   s!    %.D577dff3DDr   c                D    t        | j                  | j                  f      S r   )r%   r   rE   r   s    r   r&   zInverseOrder.__hash__   s    T^^TVV,--r   N)r   r*   r+   r,   rA   r   r   ra   r   r#   r&   r(   r   r   rc   rc      s5    $!%  E.r   rc   Nc                     t          t         t              rt                t         t              r
	 t             t         d      r fd}|S  S t        d z        # t
        $ r t        d z        w xY w)an  
    Return a function defining admissible order on monomials.

    The result of a call to :func:`monomial_key` is a function which should
    be used as a key to :func:`sorted` built-in function, to provide order
    in a set of monomials of the same length.

    Currently supported monomial orderings are:

    1. lex       - lexicographic order (default)
    2. grlex     - graded lexicographic order
    3. grevlex   - reversed graded lexicographic order
    4. ilex, igrlex, igrevlex - the corresponding inverse orders

    If the ``order`` input argument is not a string but has ``__call__``
    attribute, then it will pass through with an assumption that the
    callable object defines an admissible order on monomials.

    If the ``gens`` input argument contains a list of generators, the
    resulting key function can be used to sort SymPy ``Expr`` objects.

    zEsupported monomial orderings are 'lex', 'grlex' and 'grevlex', got %rr   c                J      | j                    j                               S r   )as_polydegree_list)exprgensorders    r   _orderzmonomial_key.<locals>._order   s"    \T\\40<<>??r   zFmonomial ordering specification must be a string or a callable, got %s)r   rV   r
   rS   _monomial_keyKeyError
ValueErrorhasattr)rv   ru   rw   s   `` r   monomial_keyr|      s    . }% E
%	n!%(E uj!@Madiijj  	ndgllmm	ns   	A& &A>c                  "    e Zd ZdZd Zd Zd Zy)_ItemGetterz/Helper class to return a subsequence of values.c                $    t        |      | _        y r   r:   seq)r   r   s     r   rA   z_ItemGetter.__init__   s    :r   c                @    t        fd| j                  D              S )Nc              3  (   K   | ]	  }|     y wr   r(   )rD   idxr<   s     r   rG   z'_ItemGetter.__call__.<locals>.<genexpr>   s     0QsV0   r   )r   r<   s    `r   r   z_ItemGetter.__call__   s    0txx000r   c                V    t        |t              sy| j                  |j                  k(  S rU   )rV   r~   r   r!   s     r   r#   z_ItemGetter.__eq__   s"    %-xx599$$r   N)r   r*   r+   r,   rA   r   r#   r(   r   r   r~   r~      s    91%r   r~   c                   	 i 	t        |      D ]
  \  }}|	|<    g }| D ]3  }|d   }|dd }	fd}|j                  t        |       ||      f       5 t        | S )ad  
    Build a monomial order on ``gens``.

    ``arg`` should be a tuple of iterables. The first element of each iterable
    should be a string or monomial order (will be passed to monomial_key),
    the others should be subsets of the generators. This function will build
    the corresponding product order.

    For example, build a product of two grlex orders:

    >>> from sympy.polys.orderings import build_product_order
    >>> from sympy.abc import x, y, z, t

    >>> O = build_product_order((("grlex", x, y), ("grlex", z, t)), [x, y, z, t])
    >>> O((1, 2, 3, 4))
    ((3, (1, 2)), (7, (3, 4)))

    r      Nc                ,    t        fd| D              S )Nc              3  (   K   | ]	  }|     y wr   r(   )rD   ggens2idxs     r   rG   z:build_product_order.<locals>.makelambda.<locals>.<genexpr>  s     8qx{8r   )r~   )varr   s    r   
makelambdaz'build_product_order.<locals>.makelambda  s    8C888r   )	enumerateappendr|   r>   )
argru   rg   r   rv   rt   namer   r   r   s
            @r   build_product_orderr      s~    & H$ 1E <Aw12h	9l4(*S/:;< r   )NN)r,   
__future__r   __all__
sympy.corer
   sympy.utilities.iterablesr   r   r0   r3   r8   r>   rc   r   r   r   r   r   r	   rx   r|   r~   r   r(   r   r   <module>r      s    ) "
C  .# #2} )] )H] HH= HT,.= ,.\ j
 
"C	e	  )kV% % r   