U
    @f$                     @   sv   d Z ddlmZ ddlmZ ddlmZmZmZ ddl	m
Z
 ddlmZ G dd deeZeZG d	d
 d
eZeZdS )z"Finite extensions of ring domains.    )Domain)DomainElement)CoercionFailedNotInvertibleGeneratorsError)Poly)DefaultPrintingc                   @   s   e Zd Zd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eZdd Zdd Zdd ZeZdd Zdd Zdd ZeZdd  Ze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 d/d0 Z!d1d2 Z"d3S )4ExtensionElementa#  
    Element of a finite extension.

    A class of univariate polynomials modulo the ``modulus``
    of the extension ``ext``. It is represented by the
    unique polynomial ``rep`` of lowest degree. Both
    ``rep`` and the representation ``mod`` of ``modulus``
    are of class DMP.

    repextc                 C   s   || _ || _d S Nr
   )selfr   r    r   ?/tmp/pip-unpacked-wheel-6uje5nh9/sympy/polys/agca/extensions.py__init__   s    zExtensionElement.__init__c                 C   s   | j S r   )r   fr   r   r   parent   s    zExtensionElement.parentc                 C   s   | j | S r   )r   to_sympyr   r   r   r   as_expr   s    zExtensionElement.as_exprc                 C   s
   t | jS r   )boolr   r   r   r   r   __bool__"   s    zExtensionElement.__bool__c                 C   s   | S r   r   r   r   r   r   __pos__%   s    zExtensionElement.__pos__c                 C   s   t | j | jS r   )ExtElemr   r   r   r   r   r   __neg__(   s    zExtensionElement.__neg__c                 C   sR   t |tr"|j| jkr|jS d S n,z| j|}|jW S  tk
rL   Y d S X d S r   )
isinstancer   r   r   convertr   r   gr   r   r   _get_rep+   s    
zExtensionElement._get_repc                 C   s,   |  |}|d k	r$t| j| | jS tS d S r   r    r   r   r   NotImplementedr   r   r   r   r   r   __add__8   s    
zExtensionElement.__add__c                 C   s,   |  |}|d k	r$t| j| | jS tS d S r   r!   r#   r   r   r   __sub__A   s    
zExtensionElement.__sub__c                 C   s,   |  |}|d k	r$t|| j | jS tS d S r   r!   r#   r   r   r   __rsub__H   s    
zExtensionElement.__rsub__c                 C   s4   |  |}|d k	r,t| j| | jj | jS tS d S r   )r    r   r   r   modr"   r#   r   r   r   __mul__O   s    
zExtensionElement.__mul__c                 C   sZ   | st dnH| jjrdS | jjr:| jj| j r:dS d|  d| j d}t|dS )z5Raise if division is not implemented for this divisorzZero divisorTzCan not invert z in z7. Only division by invertible constants is implemented.N)	r   r   is_Fieldr   	is_grounddomainis_unitZLCNotImplementedError)r   msgr   r   r   	_divcheckX   s    
zExtensionElement._divcheckc                 C   sF   |    | jjr"| j| jj}n| jj}||j| j}t	|| jS )zMultiplicative inverse.

        Raises
        ======

        NotInvertible
            If the element is a zero divisor.

        )
r/   r   r)   r   invertr'   ringexquooner   )r   ZinvrepRr   r   r   inversei   s    
zExtensionElement.inversec                 C   s^   |  |}|d krtS t|| j}z| }W n& tk
rT   t|  d| Y nX | | S )Nz / )r    r"   r   r   r5   r   ZeroDivisionError)r   r   r   Zginvr   r   r   __truediv__}   s    
zExtensionElement.__truediv__c                 C   s2   z| j |}W n tk
r(   t Y S X ||  S r   r   r   r   r"   r   r   r   r   __rtruediv__   s
    
zExtensionElement.__rtruediv__c                 C   s^   |  |}|d krtS t|| j}z|  W n& tk
rT   t|  d| Y nX | jjS )Nz % )r    r"   r   r   r/   r   r6   zeror#   r   r   r   __mod__   s    
zExtensionElement.__mod__c                 C   s2   z| j |}W n tk
r(   t Y S X ||  S r   r8   r   r   r   r   __rmod__   s
    
zExtensionElement.__rmod__c                 C   s   t |tstd|dk rLz|  |  } }W n tk
rJ   tdY nX | j}| jj}| jj	j}|dkr|d r|| | }|| | }|d }qdt
|| jS )Nzexponent of type 'int' expectedr   znegative powers are not defined   )r   int	TypeErrorr5   r-   
ValueErrorr   r   r'   r3   r   )r   nbmrr   r   r   __pow__   s     


zExtensionElement.__pow__c                 C   s*   t |tr"| j|jko | j|jkS tS d S r   )r   r   r   r   r"   r   r   r   r   __eq__   s    
zExtensionElement.__eq__c                 C   s
   | |k S r   r   r   r   r   r   __ne__   s    zExtensionElement.__ne__c                 C   s   t | j| jfS r   )hashr   r   r   r   r   r   __hash__   s    zExtensionElement.__hash__c                 C   s   ddl m} ||  S )Nr   )sstr)Zsympy.printing.strrJ   r   )r   rJ   r   r   r   __str__   s    zExtensionElement.__str__c                 C   s   | j jS r   )r   r*   r   r   r   r   r*      s    zExtensionElement.is_groundc                 C   s   | j  \}|S r   )r   Zto_list)r   cr   r   r   	to_ground   s    zExtensionElement.to_groundN)#__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   r    r$   __radd__r%   r&   r(   __rmul__r/   r5   r7   __floordiv__r9   __rfloordiv__r;   r<   rE   rF   rG   rI   rK   __repr__propertyr*   rM   r   r   r   r   r	      s@   

r	   c                   @   s   e Zd ZdZdZeZdd Zdd Zdd Z	d	d
 Z
dd ZeZedd Zdd Zd&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S )'MonogenicFiniteExtensiona  
    Finite extension generated by an integral element.

    The generator is defined by a monic univariate
    polynomial derived from the argument ``mod``.

    A shorter alias is ``FiniteExtension``.

    Examples
    ========

    Quadratic integer ring $\mathbb{Z}[\sqrt2]$:

    >>> from sympy import Symbol, Poly
    >>> from sympy.polys.agca.extensions import FiniteExtension
    >>> x = Symbol('x')
    >>> R = FiniteExtension(Poly(x**2 - 2)); R
    ZZ[x]/(x**2 - 2)
    >>> R.rank
    2
    >>> R(1 + x)*(3 - 2*x)
    x - 1

    Finite field $GF(5^3)$ defined by the primitive
    polynomial $x^3 + x^2 + 2$ (over $\mathbb{Z}_5$).

    >>> F = FiniteExtension(Poly(x**3 + x**2 + 2, modulus=5)); F
    GF(5)[x]/(x**3 + x**2 + 2)
    >>> F.basis
    (1, x, x**2)
    >>> F(x + 3)/(x**2 + 2)
    -2*x**2 + x + 2

    Function field of an elliptic curve:

    >>> t = Symbol('t')
    >>> FiniteExtension(Poly(t**2 - x**3 - x + 1, t, field=True))
    ZZ(x)[t]/(t**2 - x**3 - x + 1)

    Tc                    s   t |tr|jstd|jdd}| _|_|j_	|j
 _
}|j|j _jj_jj_jjd  jjd _ _t fddtjD _j
j_d S )Nz!modulus must be a univariate PolyF)autor   c                 3   s   | ]}  | V  qd S r   r   ).0igenr   r   r   	<genexpr>  s     z4MonogenicFiniteExtension.__init__.<locals>.<genexpr>)r   r   Zis_univariater?   ZmonicZdegreeZrankmodulusr   r'   r+   Zold_poly_ringZgensr1   r   r:   r3   symbolssymbol	generatortuplerangeZbasisr)   )r   r'   domr   r^   r   r     s    
 z!MonogenicFiniteExtension.__init__c                 C   s   | j |}t|| j | S r   r1   r   r   r'   )r   argr   r   r   r   new$  s    zMonogenicFiniteExtension.newc                 C   s   t |tsdS | j|jkS NF)r   FiniteExtensionra   )r   otherr   r   r   rF   (  s    
zMonogenicFiniteExtension.__eq__c                 C   s   t | jj| jfS r   )rH   	__class__rN   ra   r   r   r   r   rI   -  s    z!MonogenicFiniteExtension.__hash__c                 C   s   d| j | j f S )Nz%s/(%s))r1   ra   r   ro   r   r   r   rK   0  s    z MonogenicFiniteExtension.__str__c                 C   s   | j jS r   )r+   has_CharacteristicZeroro   r   r   r   rp   5  s    z/MonogenicFiniteExtension.has_CharacteristicZeroc                 C   s
   | j  S r   )r+   characteristicro   r   r   r   rq   9  s    z'MonogenicFiniteExtension.characteristicNc                 C   s   | j ||}t|| j | S r   rh   r   r   baser   r   r   r   r   <  s    z MonogenicFiniteExtension.convertc                 C   s   | j ||}t|| j | S r   rh   rr   r   r   r   convert_from@  s    z%MonogenicFiniteExtension.convert_fromc                 C   s   | j |jS r   )r1   r   r   r   r   r   r   r   r   D  s    z!MonogenicFiniteExtension.to_sympyc                 C   s
   |  |S r   r[   ru   r   r   r   
from_sympyG  s    z#MonogenicFiniteExtension.from_sympyc                 C   s   | j |}| |S r   )ra   
set_domainrn   )r   Kr'   r   r   r   rw   J  s    z#MonogenicFiniteExtension.set_domainc                 G   s(   | j |krtd| jj| }| |S )Nz+Can not drop generator from FiniteExtension)rc   r   r+   droprw   )r   rb   rx   r   r   r   ry   N  s    
zMonogenicFiniteExtension.dropc                 C   s   |  ||S r   )r2   )r   r   r   r   r   r   quoT  s    zMonogenicFiniteExtension.quoc                 C   s"   | j |j|j}t|| j | S r   )r1   r2   r   r   r'   )r   r   r   r   r   r   r   r2   W  s    zMonogenicFiniteExtension.exquoc                 C   s   dS rk   r   r   ar   r   r   is_negative[  s    z$MonogenicFiniteExtension.is_negativec                 C   s(   | j rt|S |jr$| j| S d S r   )r)   r   r*   r+   r,   rM   r{   r   r   r   r,   ^  s    z MonogenicFiniteExtension.is_unit)N)rN   rO   rP   rQ   Zis_FiniteExtensionr	   Zdtyper   rj   rF   rI   rK   rW   rX   rp   rq   r   rt   r   rv   rw   ry   rz   r2   r}   r,   r   r   r   r   rY      s,   (

rY   N)rQ   Zsympy.polys.domains.domainr   Z!sympy.polys.domains.domainelementr   Zsympy.polys.polyerrorsr   r   r   Zsympy.polys.polytoolsr   Zsympy.printing.defaultsr   r	   r   rY   rl   r   r   r   r   <module>   s    N 
