B
    [                 @   sr   d Z ddlmZmZ ddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ eG dd	 d	ee
Zi Zd
d ZdS )z1Implementation of :class:`ModularInteger` class.     )print_functiondivisionN)PicklableWithSlots)CoercionFailed)DomainElement)publicc               @   s.  e Zd ZdZd\ZZZZdgZdd Z	dd Z
dd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zedd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' ZeZeZd(d) Zd*d+ Zd,d- Z d.d/ Z!d0d1 Z"d2d3 Z#d4d5 Z$d6d7 Z%d8d9 Z&d:d; Z'd<d= Z(e(Z)ed>d? Z*d@dA Z+dBS )CModularIntegerz(A class representing a modular integer. )NNNNvalc             C   s   | j S )N)_parent)self r   Alib/python3.7/site-packages/sympy/polys/domains/modularinteger.pyparent   s    zModularInteger.parentc             C   s4   t || jr|j| j | _n| j|| j | _d S )N)
isinstance	__class__r	   moddomconvert)r   r	   r   r   r   __init__   s    zModularInteger.__init__c             C   s   t | j| jfS )N)hashr	   r   )r   r   r   r   __hash__   s    zModularInteger.__hash__c             C   s   d| j j| jf S )Nz%s(%s))r   __name__r	   )r   r   r   r   __repr__!   s    zModularInteger.__repr__c             C   s   d| j | jf S )Nz	%s mod %s)r	   r   )r   r   r   r   __str__$   s    zModularInteger.__str__c             C   s   t |  S )N)intto_int)r   r   r   r   __int__'   s    zModularInteger.__int__c             C   s4   | j r*| j| jd kr| jS | j| j S n| jS d S )N   )symr	   r   )r   r   r   r   r   *   s
    zModularInteger.to_intc             C   s   | S )Nr   )r   r   r   r   __pos__3   s    zModularInteger.__pos__c             C   s   |  | j S )N)r   r	   )r   r   r   r   __neg__6   s    zModularInteger.__neg__c             C   s6   t || r|jS y| j|S  tk
r0   d S X d S )N)r   r	   r   r   r   )clsotherr   r   r   _get_val9   s    
zModularInteger._get_valc             C   s*   |  |}|d k	r"| | j| S tS d S )N)r#   r   r	   NotImplemented)r   r"   r	   r   r   r   __add__C   s    
zModularInteger.__add__c             C   s
   |  |S )N)r%   )r   r"   r   r   r   __radd__K   s    zModularInteger.__radd__c             C   s*   |  |}|d k	r"| | j| S tS d S )N)r#   r   r	   r$   )r   r"   r	   r   r   r   __sub__N   s    
zModularInteger.__sub__c             C   s   |   |S )N)r%   )r   r"   r   r   r   __rsub__V   s    zModularInteger.__rsub__c             C   s*   |  |}|d k	r"| | j| S tS d S )N)r#   r   r	   r$   )r   r"   r	   r   r   r   __mul__Y   s    
zModularInteger.__mul__c             C   s
   |  |S )N)r)   )r   r"   r   r   r   __rmul__a   s    zModularInteger.__rmul__c             C   s0   |  |}|d k	r(| | j| | S tS d S )N)r#   r   r	   _invertr$   )r   r"   r	   r   r   r   __div__d   s    
zModularInteger.__div__c             C   s   |   |S )N)invertr)   )r   r"   r   r   r   __rdiv__l   s    zModularInteger.__rdiv__c             C   s*   |  |}|d k	r"| | j| S tS d S )N)r#   r   r	   r$   )r   r"   r	   r   r   r   __mod__r   s    
zModularInteger.__mod__c             C   s*   |  |}|d k	r"| || j S tS d S )N)r#   r   r	   r$   )r   r"   r	   r   r   r   __rmod__z   s    
zModularInteger.__rmod__c             C   sL   |s|  | jjS |dk r.|  j|  }}n| j}|  t|t|| jS )Nr   )r   r   Zoner-   r	   powr   r   )r   Zexpr	   r   r   r   __pow__   s    zModularInteger.__pow__c             C   s,   |  |}|d k	r$|| j|| j S tS d S )N)r#   r	   r   r$   )r   r"   opr	   r   r   r   _compare   s    
zModularInteger._comparec             C   s   |  |tjS )N)r4   operatoreq)r   r"   r   r   r   __eq__   s    zModularInteger.__eq__c             C   s   |  |tjS )N)r4   r5   ne)r   r"   r   r   r   __ne__   s    zModularInteger.__ne__c             C   s   |  |tjS )N)r4   r5   lt)r   r"   r   r   r   __lt__   s    zModularInteger.__lt__c             C   s   |  |tjS )N)r4   r5   le)r   r"   r   r   r   __le__   s    zModularInteger.__le__c             C   s   |  |tjS )N)r4   r5   gt)r   r"   r   r   r   __gt__   s    zModularInteger.__gt__c             C   s   |  |tjS )N)r4   r5   ge)r   r"   r   r   r   __ge__   s    zModularInteger.__ge__c             C   s
   t | jS )N)boolr	   )r   r   r   r   __nonzero__   s    zModularInteger.__nonzero__c             C   s   | j || jS )N)r   r-   r   )r!   valuer   r   r   r+      s    zModularInteger._invertc             C   s   |  | | jS )N)r   r+   r	   )r   r   r   r   r-      s    zModularInteger.invertN),r   
__module____qualname____doc__r   r   r   r
   	__slots__r   r   r   r   r   r   r   r   r    classmethodr#   r%   r&   r'   r(   r)   r*   r,   r.   __truediv____rtruediv__r/   r0   r2   r4   r7   r9   r;   r=   r?   rA   rC   __bool__r+   r-   r   r   r   r   r      sJ   	
r   c                s   y  W n tk
r&   d}Y nX d}|r8dk rDtd  f}yt| }W nP tk
r   G  fdddt}rd |_n
d |_|t|< Y nX |S )	z1Create custom class for specific integer modulus.FT   z*modulus must be a positive integer, got %sc                   s    e Zd Z   ZZZZdS )z"ModularIntegerFactory.<locals>.clsN)r   rE   rF   r   r   r   r
   r   )_dom_mod_symr   r   r   r!      s   r!   zSymmetricModularIntegerMod%szModularIntegerMod%s)r   r   
ValueError_modular_integer_cacheKeyErrorr   r   )rO   rN   rP   r   okkeyr!   r   )rN   rO   rP   r   r   ModularIntegerFactory   s"    


rV   )rG   Z
__future__r   r   r5   Zsympy.polys.polyutilsr   Zsympy.polys.polyerrorsr   Z!sympy.polys.domains.domainelementr   Zsympy.utilitiesr   r   rR   rV   r   r   r   r   <module>   s   
 &