U
    me                     @  s   U d Z ddlmZ ddl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ed< dd ZdS )z1Implementation of :class:`ModularInteger` class.     )annotations)AnyN)PicklableWithSlots)CoercionFailed)DomainElement)publicc                   @  s   e Zd ZdZd\ZZZZ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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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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   F/tmp/pip-unpacked-wheel-rdz2gdd2/sympy/polys/domains/modularinteger.pyparent   s    zModularInteger.parentc                 C  s4   t || jr|j| j | _n| j|| j | _d S r
   )
isinstance	__class__r	   moddomconvert)r   r	   r   r   r   __init__   s    zModularInteger.__init__c                 C  s   t | j| jfS r
   )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 r
   )intto_intr   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 r
   r   r   r   r   r   __pos__4   s    zModularInteger.__pos__c                 C  s   |  | j S r
   )r   r	   r   r   r   r   __neg__7   s    zModularInteger.__neg__c                 C  s:   t || r|jS z| j|W S  tk
r4   Y d S X d S r
   )r   r	   r   r   r   )clsotherr   r   r   _get_val:   s    
zModularInteger._get_valc                 C  s*   |  |}|d k	r"| | j| S tS d S r
   r%   r   r	   NotImplementedr   r$   r	   r   r   r   __add__D   s    
zModularInteger.__add__c                 C  s
   |  |S r
   r)   r   r$   r   r   r   __radd__L   s    zModularInteger.__radd__c                 C  s*   |  |}|d k	r"| | j| S tS d S r
   r&   r(   r   r   r   __sub__O   s    
zModularInteger.__sub__c                 C  s   |   |S r
   r*   r+   r   r   r   __rsub__W   s    zModularInteger.__rsub__c                 C  s*   |  |}|d k	r"| | j| S tS d S r
   r&   r(   r   r   r   __mul__Z   s    
zModularInteger.__mul__c                 C  s
   |  |S r
   )r/   r+   r   r   r   __rmul__b   s    zModularInteger.__rmul__c                 C  s0   |  |}|d k	r(| | j| | S tS d S r
   )r%   r   r	   _invertr'   r(   r   r   r   __truediv__e   s    
zModularInteger.__truediv__c                 C  s   |   |S r
   )invertr/   r+   r   r   r   __rtruediv__m   s    zModularInteger.__rtruediv__c                 C  s*   |  |}|d k	r"| | j| S tS d S r
   r&   r(   r   r   r   __mod__p   s    
zModularInteger.__mod__c                 C  s*   |  |}|d k	r"| || j S tS d S r
   r&   r(   r   r   r   __rmod__x   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oner3   r	   powr   r   )r   expr	   r   r   r   __pow__   s    zModularInteger.__pow__c                 C  s,   |  |}|d k	r$|| j|| j S tS d S r
   )r%   r	   r   r'   )r   r$   opr	   r   r   r   _compare   s    
zModularInteger._comparec                 C  s   |  |tjS r
   )r;   operatoreqr+   r   r   r   __eq__   s    zModularInteger.__eq__c                 C  s   |  |tjS r
   )r;   r<   ner+   r   r   r   __ne__   s    zModularInteger.__ne__c                 C  s   |  |tjS r
   )r;   r<   ltr+   r   r   r   __lt__   s    zModularInteger.__lt__c                 C  s   |  |tjS r
   )r;   r<   ler+   r   r   r   __le__   s    zModularInteger.__le__c                 C  s   |  |tjS r
   )r;   r<   gtr+   r   r   r   __gt__   s    zModularInteger.__gt__c                 C  s   |  |tjS r
   )r;   r<   ger+   r   r   r   __ge__   s    zModularInteger.__ge__c                 C  s
   t | jS r
   )boolr	   r   r   r   r   __bool__   s    zModularInteger.__bool__c                 C  s   | j || jS r
   )r   r3   r   )r#   valuer   r   r   r1      s    zModularInteger._invertc                 C  s   |  | | jS r
   )r   r1   r	   r   r   r   r   r3      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/   r0   r2   r4   r5   r6   r9   r;   r>   r@   rB   rD   rF   rH   rJ   r1   r3   r   r   r   r   r      sH   	
	
r   z0dict[tuple[Any, Any, Any], type[ModularInteger]]_modular_integer_cachec                   s   z  W n tk
r&   d}Y nX d}|r8dk rDtd  f}z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   rL   rM   r   r   r    r   r   _dom_mod_symr   r   r   r#      s   r#   zSymmetricModularIntegerMod%szModularIntegerMod%s)r   r   
ValueErrorrQ   KeyErrorr   r   )rU   rT   rV   r   okkeyr#   r   rS   r   ModularIntegerFactory   s"    


r[   )rN   
__future__r   typingr   r<   Zsympy.polys.polyutilsr   Zsympy.polys.polyerrorsr   Z!sympy.polys.domains.domainelementr   Zsympy.utilitiesr   r   rQ   __annotations__r[   r   r   r   r   <module>   s    !