U
    ZÊ¹jò   ã                   @   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 �nèt |tƒ�r4g g f }\}}|jD ]}	|t |	ˆƒ  |	¡ qÔ|�ršt‡fdd„|D ƒƒ�ršt|Ž tdd„ |D ƒŽ  }
ˆ|
ˆƒS �nft |tƒ�ršg 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
| |¡ �qÎt|Ž }t|Ž }tdd„ |D ƒŽ }|| }
|ˆ|
ˆƒ S ˆj	�rŽˆt
jk	�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} 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�rêt|Ž }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�r¨tˆ 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r�tjS | j	rœtj
S t| dƒrÀt| dƒ|ƒ}|dk	rÀ|S | | }|jrÔt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%   úM/var/www/html/bwave/python/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   