o
    8Va#                     @   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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-d. Z d/d0 Z!d1S )2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   =/usr/lib/python3/dist-packages/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
   t | jS r   )boolr   r   r   r   r   __bool__      
zExtensionElement.__bool__c                 C   s   | S r   r   r   r   r   r   __pos__"      zExtensionElement.__pos__c                 C   s   t | j | jS r   )ExtElemr   r   r   r   r   r   __neg__%      zExtensionElement.__neg__c                 C   sJ   t |tr|j| jkr|jS d S z
| j|}|jW S  ty$   Y d S w r   )
isinstancer   r   r   convertr   r   gr   r   r   _get_rep(   s   
zExtensionElement._get_repc                 C   s(   |  |}|d urt| j| | jS tS r   r!   r   r   r   NotImplementedr   r    r   r   r   r   __add__5      
zExtensionElement.__add__c                 C   s(   |  |}|d urt| j| | jS tS r   r"   r$   r   r   r   __sub__>   r&   zExtensionElement.__sub__c                 C   s(   |  |}|d urt|| j | jS tS r   r"   r$   r   r   r   __rsub__E   r&   zExtensionElement.__rsub__c                 C   s0   |  |}|d urt| j| | jj | jS tS r   )r!   r   r   r   modr#   r$   r   r   r   __mul__L   s   
zExtensionElement.__mul__c                 C   sV   | st d| jjrdS | jjr| jj| jjd rdS d|  d| j d}t|)z5Raise if division is not implemented for this divisorzZero divisorTr   zCan not invert z in z7. Only division by invertible constants is implemented.)r   r   is_Fieldr   	is_grounddomainis_unitNotImplementedError)r   msgr   r   r   	_divcheckU   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.

        )
r1   r   r+   r   invertr)   ringexquooner   )r   ZinvrepRr   r   r   inversef   s   
zExtensionElement.inversec                 C   sV   |  |}|d u rtS t|| j}z	| }W | | S  ty*   t|  d| w )Nz / )r!   r#   r   r   r7   r   ZeroDivisionError)r   r    r   Zginvr   r   r   __truediv__z   s   

zExtensionElement.__truediv__c                 C   s.   z| j |}W ||  S  ty   t Y S w r   r   r   r   r#   r   r   r   r   __rtruediv__      zExtensionElement.__rtruediv__c                 C   sV   |  |}|d u rtS t|| j}z	|  W | jjS  ty*   t|  d| w )Nz % )r!   r#   r   r   r1   r   r8   zeror$   r   r   r   __mod__   s   

zExtensionElement.__mod__c                 C   s.   z| j |}W ||  S  ty   t Y S w r   r:   r   r   r   r   __rmod__   r<   zExtensionElement.__rmod__c                 C   s   t |ts	td|dk r#z
|  | } }W n ty"   tdw | j}| jj}| jj	j}|dkrK|d r=|| | }|| | }|d }|dks3t
|| jS )Nzexponent of type 'int' expectedr   znegative powers are not defined   )r   int	TypeErrorr7   r/   
ValueErrorr   r   r)   r5   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 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__   r   zExtensionElement.__ne__c                 C   s   t | j| jfS r   )hashr   r   r   r   r   r   __hash__   r   zExtensionElement.__hash__c                 C   s   ddl m} || jS )Nr   )sstr)Zsympy.printing.strrM   r   )r   rM   r   r   r   __str__      
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%   __radd__r'   r(   r*   __rmul__r1   r7   r9   __floordiv__r;   __rfloordiv__r>   r?   rH   rI   rJ   rL   rN   __repr__propertyr,   rQ   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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p-|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_univariaterB   ZmonicZdegreeZrankmodulusr   r)   r-   r3   Zold_poly_ringZgensr   r=   r5   symbolssymbol	generatortuplerangeZbasisr+   )r   r)   Zdomr   rb   r   r     s   
 z!MonogenicFiniteExtension.__init__c                 C   s   | j |}t|| j | S r   r3   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   FiniteExtensionre   )r   otherr   r   r   rI   %  s   
zMonogenicFiniteExtension.__eq__c                 C   s   t | jj| jfS r   )rK   	__class__rR   re   r   r   r   r   rL   *  s   z!MonogenicFiniteExtension.__hash__c                 C   s   d| j | j f S )Nz%s/(%s))r3   re   Zas_exprrr   r   r   r   rN   -  s   z MonogenicFiniteExtension.__str__Nc                 C      | j ||}t|| j | S r   rk   r   r   baser   r   r   r   r   2     z MonogenicFiniteExtension.convertc                 C   rs   r   rk   rt   r   r   r   convert_from6  rv   z%MonogenicFiniteExtension.convert_fromc                 C   s   | j |jS r   )r3   to_sympyr   r   r   r   r   r   rx   :  s   z!MonogenicFiniteExtension.to_sympyc                 C   s
   |  |S r   r_   ry   r   r   r   
from_sympy=  r   z#MonogenicFiniteExtension.from_sympyc                 C   s   | j |}| |S r   )re   
set_domainrq   )r   Kr)   r   r   r   r{   @  rO   z#MonogenicFiniteExtension.set_domainc                 G   s(   | j |v r	td| jj| }| |S )Nz+Can not drop generator from FiniteExtension)rg   r   r-   dropr{   )r   rf   r|   r   r   r   r}   D  s   

zMonogenicFiniteExtension.dropc                 C   s   |  ||S r   )r4   )r   r   r    r   r   r   quoJ  s   zMonogenicFiniteExtension.quoc                 C   s"   | j |j|j}t|| j | S r   )r3   r4   r   r   r)   )r   r   r    r   r   r   r   r4   M  s   zMonogenicFiniteExtension.exquoc                 C   s   dS rn   r   r   ar   r   r   is_negativeQ  r   z$MonogenicFiniteExtension.is_negativec                 C   s(   | j rt|S |jr| j| S d S r   )r+   r   r,   r-   r.   rQ   r   r   r   r   r.   T  s
   z MonogenicFiniteExtension.is_unitr   )rR   rS   rT   rU   Zis_FiniteExtensionr	   Zdtyper   rm   rI   rL   rN   r[   r   rw   rx   rz   r{   r}   r~   r4   r   r.   r   r   r   r   r]      s(    (
r]   N)rU   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   r]   ro   r   r   r   r   <module>   s     K 