
    Xh)                        d 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	 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 edk    rdgZedk    r>ddlZej                            d          ^ZZZ ee           ee          fdk     rdZndZd Zd Z d Z!e eddg           G d de	e                                  Z"e"xZ#Z$dS )z.Implementation of :class:`FiniteField` class.     N)GROUND_TYPES)doctest_depends_on)
int_valued)Field)ModularIntegerFactory)SimpleDomain)gf_zassenhausgf_irred_p_rabin)CoercionFailed)public)SymPyIntegerflintFiniteField.)r      c                      t           j                     t          j        t          j        	  d            n# t
          $ r Y dS w xY w fd} fd}||fS )Nr   )NNc                 h    	  |           S # t           $ r   |                     cY S w xY wN	TypeError)xindexmodnmods    q/var/www/tools.fuzzalab.pt/emblema-extractor/venv/lib/python3.11/site-packages/sympy/polys/domains/finitefield.pyctxz&_modular_int_factory_nmod.<locals>.ctx/   sS    	'43<< 	' 	' 	'4a#&&&&&	's    11c                      |           S r    )csr   	nmod_polys    r   poly_ctxz+_modular_int_factory_nmod.<locals>.poly_ctx5   s    yS!!!    )operatorr   r   r   r    OverflowError)r   r   r!   r   r   r    s   `  @@@r   _modular_int_factory_nmodr%   "   s    NE
%**C:DIQ   zz' ' ' ' ' ' '" " " " " " =s   A 
AAc                     t           j        t          j        |           t          j        |           t          j        fd}fd}||fS )Nc                 d    	  |           S # t           $ r   |                     cY S w xY wr   r   )r   fctxr   s    r   r   z*_modular_int_factory_fmpz_mod.<locals>.ctxA   sL    	"477N 	" 	" 	"4a>>!!!	"s   
 //c                      |           S r   r   )r   	fctx_polyfmpz_mod_polys    r   r!   z/_modular_int_factory_fmpz_mod.<locals>.poly_ctxH   s    }R+++r"   )r#   r   r   fmpz_mod_ctxfmpz_mod_poly_ctxr+   )r   r   r!   r(   r*   r+   r   s      @@@@r   _modular_int_factory_fmpz_modr.   ;   s}    NEc""D',,I'M" " " " " ", , , , , , =r"   c                 8   	 |                     |           } n # t          $ r t          d| z            w xY wd\  }}}t          <|                                 r(d}t          |           \  }}|t          |           \  }}|t          | |||          }d }|||fS )Nz"modulus must be an integer, got %s)NNFT)convertr   
ValueErrorr   is_primer%   r.   r   )r   dom	symmetricselfr   r!   is_flints          r   _modular_int_factoryr7   N   s    Ekk# E E E=CDDDE 0C8 S\\^^ 2#66X;9#>>MC
{ $Ci>>(""s    5pythongmpy)modulesc                      e Zd ZdZdZdZdxZZdZdZ	dZ
dZdZd!dZed             Zed             Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd 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$d"dZ%d Z&d Z'd  Z(dS )#r   a	  Finite field of prime order :ref:`GF(p)`

    A :ref:`GF(p)` domain represents a `finite field`_ `\mathbb{F}_p` of prime
    order as :py:class:`~.Domain` in the domain system (see
    :ref:`polys-domainsintro`).

    A :py:class:`~.Poly` created from an expression with integer
    coefficients will have the domain :ref:`ZZ`. However, if the ``modulus=p``
    option is given then the domain will be a finite field instead.

    >>> from sympy import Poly, Symbol
    >>> x = Symbol('x')
    >>> p = Poly(x**2 + 1)
    >>> p
    Poly(x**2 + 1, x, domain='ZZ')
    >>> p.domain
    ZZ
    >>> p2 = Poly(x**2 + 1, modulus=2)
    >>> p2
    Poly(x**2 + 1, x, modulus=2)
    >>> p2.domain
    GF(2)

    It is possible to factorise a polynomial over :ref:`GF(p)` using the
    modulus argument to :py:func:`~.factor` or by specifying the domain
    explicitly. The domain can also be given as a string.

    >>> from sympy import factor, GF
    >>> factor(x**2 + 1)
    x**2 + 1
    >>> factor(x**2 + 1, modulus=2)
    (x + 1)**2
    >>> factor(x**2 + 1, domain=GF(2))
    (x + 1)**2
    >>> factor(x**2 + 1, domain='GF(2)')
    (x + 1)**2

    It is also possible to use :ref:`GF(p)` with the :py:func:`~.cancel`
    and :py:func:`~.gcd` functions.

    >>> from sympy import cancel, gcd
    >>> cancel((x**2 + 1)/(x + 1))
    (x**2 + 1)/(x + 1)
    >>> cancel((x**2 + 1)/(x + 1), domain=GF(2))
    x + 1
    >>> gcd(x**2 + 1, x + 1)
    1
    >>> gcd(x**2 + 1, x + 1, domain=GF(2))
    x + 1

    When using the domain directly :ref:`GF(p)` can be used as a constructor
    to create instances which then support the operations ``+,-,*,**,/``

    >>> from sympy import GF
    >>> K = GF(5)
    >>> K
    GF(5)
    >>> x = K(3)
    >>> y = K(2)
    >>> x
    3 mod 5
    >>> y
    2 mod 5
    >>> x * y
    1 mod 5
    >>> x / y
    4 mod 5

    Notes
    =====

    It is also possible to create a :ref:`GF(p)` domain of **non-prime**
    order but the resulting ring is **not** a field: it is just the ring of
    the integers modulo ``n``.

    >>> K = GF(9)
    >>> z = K(3)
    >>> z
    3 mod 9
    >>> z**2
    0 mod 9

    It would be good to have a proper implementation of prime power fields
    (``GF(p**n)``) but these are not yet implemented in SymPY.

    .. _finite field: https://en.wikipedia.org/wiki/Finite_field
    FFTFNc                 `   ddl m} |}|dk    rt          d|z            t          ||||           \  }}}|| _        || _        || _        |                     d          | _        |                     d          | _        || _	        || _
        || _        t          | j                  | _        d S )Nr   )ZZz*modulus must be a positive integer, got %s   )sympy.polys.domainsr>   r1   r7   dtype	_poly_ctx	_is_flintzerooner3   r   symtype_tp)r5   r   r4   r>   r3   r   r!   r6   s           r   __init__zFiniteField.__init__   s    ******!88ICOPPP"6sCD"Q"QXx
!!JJqMM	::a==	??r"   c                     | j         S r   )rH   r5   s    r   tpzFiniteField.tp   	    xr"   c                 f    t          | dd           }|ddlm}  || j                  x| _        }|S )N	_is_fieldr   )isprime)getattrsympy.ntheory.primetestrP   r   rO   )r5   is_fieldrP   s      r   is_FieldzFiniteField.is_Field   sH    4d33777777(/(9(99DNXr"   c                     d| j         z  S )NzGF(%s)r   rK   s    r   __str__zFiniteField.__str__   s    $(""r"   c                 Z    t          | j        j        | j        | j        | j        f          S r   )hash	__class____name__rA   r   r3   rK   s    r   __hash__zFiniteField.__hash__   s$    T^,dj$(DHMNNNr"   c                 l    t          |t                    o| j        |j        k    o| j        |j        k    S )z0Returns ``True`` if two domains are equivalent. )
isinstancer   r   r3   )r5   others     r   __eq__zFiniteField.__eq__   s6    %-- <H	!<&*h%)&;	<r"   c                     | j         S )z*Return the characteristic of this domain. rV   rK   s    r   characteristiczFiniteField.characteristic   rM   r"   c                     | S )z*Returns a field associated with ``self``. r   rK   s    r   	get_fieldzFiniteField.get_field  s    r"   c                 F    t          |                     |                    S )z!Convert ``a`` to a SymPy object. )r   to_intr5   as     r   to_sympyzFiniteField.to_sympy  s    DKKNN+++r"   c                 :   |j         r:|                     | j                            t          |                              S t	          |          r:|                     | j                            t          |                              S t          d|z            )z0Convert SymPy's Integer to SymPy's ``Integer``. zexpected an integer, got %s)
is_IntegerrA   r3   intr   r   rg   s     r   
from_sympyzFiniteField.from_sympy
  s|    < 	D::dhnnSVV44555]] 	D::dhnnSVV44555 !>!BCCCr"   c                 b    t          |          }| j        r|| j        dz  k    r
|| j        z  }|S )z,Convert ``val`` to a Python ``int`` object.    )rl   rF   r   )r5   rh   avals      r   rf   zFiniteField.to_int  s8    1vv8 	tx1},,DHDr"   c                      t          |          S )z#Returns True if ``a`` is positive. )boolrg   s     r   is_positivezFiniteField.is_positive  s    Awwr"   c                     dS )z'Returns True if ``a`` is non-negative. Tr   rg   s     r   is_nonnegativezFiniteField.is_nonnegative  s    tr"   c                     dS )z#Returns True if ``a`` is negative. Fr   rg   s     r   is_negativezFiniteField.is_negative"  s    ur"   c                     | S )z'Returns True if ``a`` is non-positive. r   rg   s     r   is_nonpositivezFiniteField.is_nonpositive&  s	    ur"   c                     |                      | j                            t          |          |j                            S z.Convert ``ModularInteger(int)`` to ``dtype``. )rA   r3   from_ZZrl   K1rh   K0s      r   from_FFzFiniteField.from_FF*  s,    xxs1vvrv66777r"   c                     |                      | j                            t          |          |j                            S r{   )rA   r3   from_ZZ_pythonrl   r}   s      r   from_FF_pythonzFiniteField.from_FF_python.  s.    xx--c!ffbf==>>>r"   c                 ^    |                      | j                            ||                    S z'Convert Python's ``int`` to ``dtype``. rA   r3   r   r}   s      r   r|   zFiniteField.from_ZZ2  &    xx--a44555r"   c                 ^    |                      | j                            ||                    S r   r   r}   s      r   r   zFiniteField.from_ZZ_python6  r   r"   c                 P    |j         dk    r|                     |j                  S dS z,Convert Python's ``Fraction`` to ``dtype``. r?   Ndenominatorr   	numeratorr}   s      r   from_QQzFiniteField.from_QQ:  -    =A$$Q[111 r"   c                 P    |j         dk    r|                     |j                  S dS r   r   r}   s      r   from_QQ_pythonzFiniteField.from_QQ_python?  r   r"   c                 r    |                      | j                            |j        |j                            S )z.Convert ``ModularInteger(mpz)`` to ``dtype``. )rA   r3   from_ZZ_gmpyvalr}   s      r   from_FF_gmpyzFiniteField.from_FF_gmpyD  s*    xx++AE26::;;;r"   c                 ^    |                      | j                            ||                    S )z%Convert GMPY's ``mpz`` to ``dtype``. )rA   r3   r   r}   s      r   r   zFiniteField.from_ZZ_gmpyH  s&    xx++Ar22333r"   c                 P    |j         dk    r|                     |j                  S dS )z%Convert GMPY's ``mpq`` to ``dtype``. r?   N)r   r   r   r}   s      r   from_QQ_gmpyzFiniteField.from_QQ_gmpyL  s+    =A??1;/// r"   c                     |                     |          \  }}|dk    r-|                     | j                            |                    S dS )z'Convert mpmath's ``mpf`` to ``dtype``. r?   N)to_rationalrA   r3   )r~   rh   r   pqs        r   from_RealFieldzFiniteField.from_RealFieldQ  sE    ~~a  16688BFLLOO,,, 6r"   c                 n    d | j         | j        | fD             }t          || j        | j                   S )z7Returns True if ``a`` is a quadratic residue modulo p. c                 ,    g | ]}t          |          S r   rl   .0r   s     r   
<listcomp>z)FiniteField.is_square.<locals>.<listcomp>[      :::1A:::r"   )rE   rD   r
   r   r3   )r5   rh   polys      r   	is_squarezFiniteField.is_squareX  s=     ;:49qb 9:::#D$(DH====r"   c                 $   | j         dk    s|dk    r|S d | j        | j        | fD             }t          || j         | j                  D ]F}t          |          dk    r1|d         | j         dz  k    r|                     |d                   c S GdS )zSquare root modulo p of ``a`` if it is a quadratic residue.

        Explanation
        ===========
        Always returns the square root that is no larger than ``p // 2``.
        ro   r   c                 ,    g | ]}t          |          S r   r   r   s     r   r   z&FiniteField.exsqrt.<locals>.<listcomp>i  r   r"   r?   N)r   rE   rD   r	   r3   lenrA   )r5   rh   r   factors       r   exsqrtzFiniteField.exsqrt^  s     8q==AFFH::49qb 9:::#D$(DH== 	- 	-F6{{aF1IQ$>$>zz&),,,,,tr"   )Tr   ))r[   
__module____qualname____doc__repaliasis_FiniteFieldis_FFis_Numericalhas_assoc_Ringhas_assoc_Fieldr3   r   rI   propertyrL   rT   rW   r\   r`   rb   rd   ri   rm   rf   rs   ru   rw   ry   r   r   r|   r   r   r   r   r   r   r   r   r   r   r"   r   r   r   l   s5       V Vp CE!!NULNO
C
C# # # #(   X   X# # #O O O< < <
    , , ,D D D          8 8 8 8? ? ? ?6 6 6 66 6 6 62 2 2 2
2 2 2 2
< < < <4 4 4 40 0 0 0
- - -> > >    r"   )%r   r#   sympy.external.gmpyr   sympy.utilities.decoratorr   sympy.core.numbersr   sympy.polys.domains.fieldr   "sympy.polys.domains.modularintegerr    sympy.polys.domains.simpledomainr   sympy.polys.galoistoolsr	   r
   sympy.polys.polyerrorsr   sympy.utilitiesr   sympy.polys.domains.groundtypesr   __doctest_skip__r   __version__split_major_minor_rl   r%   r.   r7   r   r<   GFr   r"   r   <module>r      s   4 4  , , , , , , 8 8 8 8 8 8 ) ) ) ) ) ) + + + + + + D D D D D D 9 9 9 9 9 9 C C C C C C C C 1 1 1 1 1 1 " " " " " " 8 8 8 8 8 8 7% 7LLL *0055FFQFSS[[!F**E  2  &# # #< Xv.///    %   0/ D  RRRr"   