o
    GZh                      @   s   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mZmZ d d	lmZ G d
d deZdS )   )Add	gcd_terms)DefinedFunction)
NumberKind)	fuzzy_and	fuzzy_not)Mul)equal_valued)is_leis_ltis_geis_gt)Sc                   @   sR   e Zd ZdZeZedd Zdd Zdd Z	dd	 Z
d
d Zdd ZdddZdS )Modai  Represents a modulo operation on symbolic expressions.

    Parameters
    ==========

    p : Expr
        Dividend.

    q : Expr
        Divisor.

    Notes
    =====

    The convention used is the same as Python's: the remainder always has the
    same sign as the divisor.

    Many objects can be evaluated modulo ``n`` much faster than they can be
    evaluated directly (or at all).  For this, ``evaluate=False`` is
    necessary to prevent eager evaluation:

    >>> from sympy import binomial, factorial, Mod, Pow
    >>> Mod(Pow(2, 10**16, evaluate=False), 97)
    61
    >>> Mod(factorial(10**9, evaluate=False), 10**9 + 9)
    712524808
    >>> Mod(binomial(10**18, 10**12, evaluate=False), (10**5 + 3)**2)
    3744312326

    Examples
    ========

    >>> from sympy.abc import x, y
    >>> x**2 % y
    Mod(x**2, y)
    >>> _.subs({x: 5, y: 6})
    1

    c                    s  dd }||}|d ur|S t |r2|jd }| dkr'|jd S ||  jr0|S nt | rX| jd }| dkrN| jd  S ||  jrW|S nt |trg g f }\}}|jD ]}	|t |	 |	 qh|rtfdd|D rt| tdd |D   }
|
S nt |trEg g f }\}}|jD ]}	|t |	 |	 q|rtfd	d|D rtd
d |jD rjrfdd|D }g }g }|D ]}t |r||jd  q|| qt| }t| }tdd |D  }|| }
||
 S j	r?t
jur?tdd |jD r?fdd|jD }tdd |D r?t
jS t||  }ddlm} ddlm} z|| t dsj fdd|fD \}W n |yx   t
j Y nw |}}|jrg }|jD ]}|}||kr|| q|| q|t|jkrt| }n9| \}} \}d}|jr|js|| }t|dr |9  |t|| 9 }d}|s|| }| | r rdd  |fD \ }||}|d ur|  S  jr't dr'| 9 }|ddS  jrL jd jrLt jd drL jd | }t jdd    ||f||fkd S )Nc           	      S   s  |j rtd| tju s|tju s| jdu s|jdu rtjS | tju s1| || fv s1| jr4|dkr4tjS |jrN| jr>| | S |dkrN| jrHtjS | j	rNtj
S t| dr`t| d|}|dur`|S | | }|jrjtjS zt|}W n	 tyy   Y nw t|tr| ||  }|| dk dkr||7 }|S |jrtt}}n|jrtt}}ndS d	| }| | }td
D ]}||| s dS |||r| |   S ||7 }qdS )zmTry to return p % q if both are numbers or +/-p is known
            to be less than or equal q.
            zModulo by zeroFr      Z	_eval_ModN    T   )is_zeroZeroDivisionErrorr   NaN	is_finiteZero
is_integerZ	is_NumberZis_evenZis_oddOnehasattrgetattrint	TypeError
isinstanceis_positiver   r   is_negativer   r   range)	pqrvrdZcomp1Zcomp2Zls_ r*   =/var/www/auris/lib/python3.10/site-packages/sympy/core/mod.pynumber_eval9   sZ   (&




zMod.eval.<locals>.number_evalr   r   c                 3       | ]
}|j d   kV  qdS r   Nargs.0innerr%   r*   r+   	<genexpr>       zMod.eval.<locals>.<genexpr>c                 S      g | ]}|j d  qS r   r/   r2   ir*   r*   r+   
<listcomp>       zMod.eval.<locals>.<listcomp>c                 3   r-   r.   r/   r1   r4   r*   r+   r5      r6   c                 s       | ]}|j V  qd S Nr   r2   tr*   r*   r+   r5          c                    s   g | ]} |qS r*   r*   )r2   x)clsr%   r*   r+   r;      r<   c                 S   r7   r8   r/   r9   r*   r*   r+   r;      r<   c                 s   r=   r>   r?   r@   r*   r*   r+   r5      rB   c                    s   g | ]}|j r|  n|qS r*   )
is_Integerr9   r4   r*   r+   r;      s    c                 s   s    | ]}|t ju V  qd S r>   )r   r   )r2   Ziqr*   r*   r+   r5      s    )PolynomialError)gcdc                    s   g | ]}t |  d d dqS )F)clearfractionr   r9   )Gr*   r+   r;      s    FTc                 S   s   g | ]}| qS r*   r*   r9   r*   r*   r+   r;      s    )evaluate)r    r0   Zis_nonnegativeZis_nonpositiver   appendallr	   r   rE   r   r   anyr   Zsympy.polys.polyerrorsrF   Zsympy.polys.polytoolsrG   r
   Zis_AddcountlistZas_coeff_MulZis_Rationalr   Zcould_extract_minus_signZis_FloatZis_MulZ
_from_args)rD   r$   r%   r,   r&   ZqinnerZboth_lZ	non_mod_lZmod_largnetmodZnon_modjZprod_modZprod_non_modZ	prod_mod1rF   rG   ZpwasZqwasr0   r:   acpZcqokr'   r*   )rJ   rD   r%   r+   eval7   s   
:





<









(zMod.evalc                 C   s*   | j \}}t|j|jt|jgrdS d S )NT)r0   r   r   r   r   )selfr$   r%   r*   r*   r+   _eval_is_integer   s   
zMod._eval_is_integerc                 C      | j d jrdS d S Nr   T)r0   r!   rY   r*   r*   r+   _eval_is_nonnegative      zMod._eval_is_nonnegativec                 C   r[   r\   )r0   r"   r]   r*   r*   r+   _eval_is_nonpositive   r_   zMod._eval_is_nonpositivec                 K   s    ddl m} |||||   S )Nr   floor)#sympy.functions.elementary.integersrb   )rY   rU   bkwargsrb   r*   r*   r+   _eval_rewrite_as_floor   s   zMod._eval_rewrite_as_floorc                 C   s"   ddl m} | |j|||dS Nr   ra   )logxcdir)rc   rb   rewrite_eval_as_leading_term)rY   rC   rh   ri   rb   r*   r*   r+   rk      s   zMod._eval_as_leading_termr   c                 C   s$   ddl m} | |j||||dS rg   )rc   rb   rj   _eval_nseries)rY   rC   nrh   ri   rb   r*   r*   r+   rl     s   zMod._eval_nseriesNr8   )__name__
__module____qualname____doc__r   kindclassmethodrX   rZ   r^   r`   rf   rk   rl   r*   r*   r*   r+   r      s    (
 6r   N)addr   Z	exprtoolsr   functionr   rr   r   Zlogicr   r   mulr	   numbersr
   Z
relationalr   r   r   r   Z	singletonr   r   r*   r*   r*   r+   <module>   s    