a
    kh                      @   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 |rd|jd }| dkrN|jd S ||  jr`|S n6t | r| jd }| dkr| jd  S ||  jr|S nt |tr4g g f }\}}|jD ]}	|t |	 |	 q|rtfdd|D rt| tdd |D   }
|
S nft |trg g f }\}}|jD ]}	|t |	 |	 qV|r6tfd	d|D r6td
d |jD r6jr6fdd|D }g }g }|D ].}t |r||jd  n
|| qt| }t| }tdd |D  }|| }
||
 S j	rt
jurtdd |jD rfdd|jD }tdd |D rt
jS t||  }ddlm} ddlm} z4|| t ds fdd|fD \}W n |y    t
j Y n0 | }}|jrvg }|jD ]<}|}||krN|| n
|| q|t|jkrt| }nr| \}} \}d}|jr|js|| }t|dr҈ |9  |t|| 9 }d}|s|| }| | r rdd  |fD \ }||}|d ur2|  S  jr\t dr\| 9 }|ddS  jr jd jrt jd dr jd | }t jdd    ||f||fkd S )Nc           	      S   s  |j rtd| tju s6|tju s6| jdu s6|jdu r<tjS | tju sb| || fv sb| jrh|dkrhtjS |jr| jr|| | S |dkr| jrtjS | j	rtj
S t| drt| d|}|dur|S | | }|jrtjS zt|}W n ty   Y n80 t|tr*| ||  }|| dk dkr&||7 }|S |jr>tt }}n|jrRtt }}ndS d	| }| | }td
D ]8}||| s dS |||r| |   S ||7 }qnd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.9/site-packages/sympy/core/mod.pynumber_eval9   sV    (&
zMod.eval.<locals>.number_evalr   r   c                 3   s   | ]}|j d   kV  qdS r   Nargs.0innerr%   r*   r+   	<genexpr>       zMod.eval.<locals>.<genexpr>c                 S   s   g | ]}|j d  qS r   r.   r1   ir*   r*   r+   
<listcomp>   r5   zMod.eval.<locals>.<listcomp>c                 3   s   | ]}|j d   kV  qdS r-   r.   r0   r3   r*   r+   r4      r5   c                 s   s   | ]}|j V  qd S Nr   r1   tr*   r*   r+   r4      r5   c                    s   g | ]} |qS r*   r*   )r1   x)clsr%   r*   r+   r9      r5   c                 S   s   g | ]}|j d  qS r6   r.   r7   r*   r*   r+   r9      r5   c                 s   s   | ]}|j V  qd S r:   r;   r<   r*   r*   r+   r4      r5   c                    s   g | ]}|j r|  n|qS r*   )
is_Integerr7   r3   r*   r+   r9      r5   c                 s   s   | ]}|t ju V  qd S r:   )r   r   )r1   Ziqr*   r*   r+   r4      r5   )PolynomialError)gcdc                    s   g | ]}t |  d d dqS )F)clearfractionr   r7   )Gr*   r+   r9      s   FTc                 S   s   g | ]
}| qS r*   r*   r7   r*   r*   r+   r9      r5   )evaluate)r    r/   Zis_nonnegativeZis_nonpositiver   appendallr	   r   r@   r   r   anyr   Zsympy.polys.polyerrorsrA   Zsympy.polys.polytoolsrB   r
   Zis_AddcountlistZas_coeff_MulZis_Rationalr   Zcould_extract_minus_signZis_FloatZis_MulZ
_from_args)r?   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_mod1rA   rB   ZpwasZqwasr/   r8   acpZcqokr'   r*   )rE   r?   r%   r+   eval7   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   s   | j d jrdS d S Nr   T)r/   r!   rT   r*   r*   r+   _eval_is_nonnegative   s    zMod._eval_is_nonnegativec                 C   s   | j d jrdS d S rV   )r/   r"   rW   r*   r*   r+   _eval_is_nonpositive   s    zMod._eval_is_nonpositivec                 K   s    ddl m} |||||   S )Nr   floor)#sympy.functions.elementary.integersr[   )rT   rP   bkwargsr[   r*   r*   r+   _eval_rewrite_as_floor   s    zMod._eval_rewrite_as_floorc                 C   s"   ddl m} | |j|||dS Nr   rZ   )logxcdir)r\   r[   rewrite_eval_as_leading_term)rT   r>   ra   rb   r[   r*   r*   r+   rd      s    zMod._eval_as_leading_termr   c                 C   s$   ddl m} | |j||||dS r`   )r\   r[   rc   _eval_nseries)rT   r>   nra   rb   r[   r*   r*   r+   re     s    zMod._eval_nseriesN)r   )__name__
__module____qualname____doc__r   kindclassmethodrS   rU   rX   rY   r_   rd   re   r*   r*   r*   r+   r      s   (
 6r   N)addr   Z	exprtoolsr   functionr   rk   r   Zlogicr   r   mulr	   Znumbersr
   Z
relationalr   r   r   r   Z	singletonr   r   r*   r*   r*   r+   <module>   s   