U
    L?h                      @   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 k	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k	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 |k
r   t
j Y nX | }}|jrxg }|jD ]<}|}||krP|| 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 k	r4|  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ks6|tjks6| jdks6|jdkr<tjS | tjksb| || fk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k	r|S | | }|jrtjS zt|}W n tk
r   Y n8X t|tr,| ||  }|| dk dkr(||7 }|S t| }tdD ]~}|t|8 }|jr<|jr| jrp||   S | jr|   S n.|jr| jr|  S | jr| |   S  qq<d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absrangeis_negativeis_positive)pqrvrd_ r%   @/var/www/html/venv/lib/python3.8/site-packages/sympy/core/mod.pynumber_eval8   sZ    (&
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>   s     zMod.eval.<locals>.<genexpr>c                 S   s   g | ]}|j d  qS r   r)   r,   ir%   r%   r&   
<listcomp>   s     zMod.eval.<locals>.<listcomp>c                 3   s   | ]}|j d   kV  qdS r(   r)   r+   r.   r%   r&   r/      s     c                 s   s   | ]}|j V  qd S Nr   r,   tr%   r%   r&   r/      s     c                    s   g | ]} |qS r%   r%   )r,   x)clsr    r%   r&   r3      s     c                 S   s   g | ]}|j d  qS r0   r)   r1   r%   r%   r&   r3      s     c                 s   s   | ]}|j V  qd S r4   r5   r6   r%   r%   r&   r/      s     c                    s   g | ]}|j r|  n|qS r%   )
is_Integerr1   r.   r%   r&   r3      s     c                 s   s   | ]}|t jkV  qd S r4   )r   r   )r,   Ziqr%   r%   r&   r/      s     )PolynomialError)gcdc                    s   g | ]}t |  d d dqS )F)clearZfractionr   r1   )Gr%   r&   r3      s   FTc                 S   s   g | ]
}| qS r%   r%   r1   r%   r%   r&   r3      s     )evaluate)r   r*   Zis_nonnegativeZis_nonpositiver   appendallr	   r   r:   r   r   anyr   Zsympy.polys.polyerrorsr;   Zsympy.polys.polytoolsr<   r
   Zis_AddcountlistZas_coeff_MulZis_Rationalr   Zcould_extract_minus_signZis_FloatZis_MulZ
_from_args)r9   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_mod1r;   r<   ZpwasZqwasr*   r2   acpZcqokr"   r%   )r>   r9   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   s   | j d jrdS d S Nr   T)r*   r   rM   r%   r%   r&   _eval_is_nonnegative   s    zMod._eval_is_nonnegativec                 C   s   | j d jrdS d S rO   )r*   r   rP   r%   r%   r&   _eval_is_nonpositive   s    zMod._eval_is_nonpositivec                 K   s    ddl m} |||||   S )Nr   floor)#sympy.functions.elementary.integersrT   )rM   rI   bkwargsrT   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   rS   )logxcdir)rU   rT   rewrite_eval_as_leading_term)rM   r8   rZ   r[   rT   r%   r%   r&   r]      s    zMod._eval_as_leading_termc                 C   s$   ddl m} | |j||||dS rY   )rU   rT   r\   _eval_nseries)rM   r8   nrZ   r[   rT   r%   r%   r&   r^     s    zMod._eval_nseries)Nr   )r   )__name__
__module____qualname____doc__r   kindclassmethodrL   rN   rQ   rR   rX   r]   r^   r%   r%   r%   r&   r      s   (
 7
r   N)addr   Z	exprtoolsr   functionr   rd   r   Zlogicr   r   mulr	   numbersr
   Z	singletonr   r   r%   r%   r%   r&   <module>   s   