o
    g                      @   sx   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 G d	d
 d
eZdS )   )Add	gcd_terms)Function)
NumberKind)	fuzzy_and	fuzzy_not)Mul)equal_valued)Sc                   @   sT   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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 t| }tdD ]9}|t|8 }|jr|jr| jr||   S | jr|   S  dS |jr| jr|  S | jr| |   S  dS 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      	_eval_ModN    T)is_zeroZeroDivisionErrorr   NaN	is_finiteZero
is_integer	is_Numberis_evenis_oddOnehasattrgetattrint	TypeError
isinstanceabsrangeis_negativeis_positive)pqrvrd_ r)   E/var/www/visachat/venv/lib/python3.10/site-packages/sympy/core/mod.pynumber_eval8   sb   (&


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.   r1   ir)   r)   r*   
<listcomp>       zMod.eval.<locals>.<listcomp>c                 3   r,   r-   r.   r0   r3   r)   r*   r4      r5   c                 s       | ]}|j V  qd S Nr   r1   tr)   r)   r*   r4          c                    s   g | ]} |qS r)   r)   )r1   x)clsr$   r)   r*   r:      r;   c                 S   r6   r7   r.   r8   r)   r)   r*   r:      r;   c                 s   r<   r=   r>   r?   r)   r)   r*   r4      rA   c                    s   g | ]}|j r|  n|qS r)   )
is_Integerr8   r3   r)   r*   r:      s    c                 s   s    | ]}|t ju V  qd S r=   )r   r   )r1   iqr)   r)   r*   r4      s    )PolynomialError)gcdc                    s   g | ]}t |  d d dqS )F)clearfractionr   r8   )Gr)   r*   r:      s    FTc                 S   s   g | ]}| qS r)   r)   r8   r)   r)   r*   r:      s    )evaluate)r   r/   is_nonnegativeis_nonpositiver   appendallr	   r   rD   r   r   anyr   sympy.polys.polyerrorsrF   sympy.polys.polytoolsrG   r
   is_Addcountlistas_coeff_Mulis_Rationalr   could_extract_minus_signis_Floatis_Mul
_from_args)rC   r#   r$   r+   r%   qinnerboth_l	non_mod_lmod_largnetmodnon_modjprod_modprod_non_mod	prod_mod1rF   rG   pwasqwasr/   r9   acpcqokr&   r)   )rJ   rC   r$   r*   eval6   s   
;





<









(zMod.evalc                 C   s*   | j \}}t|j|jt|jgrdS d S )NT)r/   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)r/   r"   ro   r)   r)   r*   _eval_is_nonnegative      zMod._eval_is_nonnegativec                 C   rq   rr   )r/   r!   rs   r)   r)   r*   _eval_is_nonpositive   ru   zMod._eval_is_nonpositivec                 K   s    ddl m} |||||   S )Nr   floor)#sympy.functions.elementary.integersrx   )ro   rj   bkwargsrx   r)   r)   r*   _eval_rewrite_as_floor   s   zMod._eval_rewrite_as_floorNr   c                 C   s"   ddl m} | |j|||dS Nr   rw   )logxcdir)ry   rx   rewrite_eval_as_leading_term)ro   rB   r~   r   rx   r)   r)   r*   r      s   zMod._eval_as_leading_termc                 C   s$   ddl m} | |j||||dS r}   )ry   rx   r   _eval_nseries)ro   rB   nr~   r   rx   r)   r)   r*   r     s   zMod._eval_nseries)Nr   r7   )__name__
__module____qualname____doc__r   kindclassmethodrn   rp   rt   rv   r|   r   r   r)   r)   r)   r*   r      s    (
 7
r   N)addr   	exprtoolsr   functionr   r   r   logicr   r   mulr	   numbersr
   	singletonr   r   r)   r)   r)   r*   <module>   s    