
    Ed                         d 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 e
 G d d	ee                      ZexZZd
S )z.Implementation of :class:`FiniteField` class.     )Field)ModularIntegerFactory)SimpleDomain)CoercionFailed)public)SymPyIntegerc                       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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S )FiniteFielda	  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          | _        || _        || _        d S )Nr   )ZZz*modulus must be a positive integer, got %s   )	sympy.polys.domainsr   
ValueErrorr   dtypezeroonedommod)selfr   	symmetricr   r   s        ?lib/python3.11/site-packages/sympy/polys/domains/finitefield.py__init__zFiniteField.__init__r   s    ******!8 	QICOPPP*3YEE
JJqMM	::a==    c                     d| j         z  S )NzGF(%s)r   r   s    r   __str__zFiniteField.__str__   s    $(""r   c                 Z    t          | j        j        | j        | j        | j        f          S N)hash	__class____name__r   r   r   r   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   r   )r   others     r   __eq__zFiniteField.__eq__   s6    %-- <H	!<&*h%)&;	<r   c                     | j         S )z*Return the characteristic of this domain. r   r   s    r   characteristiczFiniteField.characteristic   s	    xr   c                     | S )z*Returns a field associated with ``self``.  r   s    r   	get_fieldzFiniteField.get_field   s    r   c                 :    t          t          |                    S )z!Convert ``a`` to a SymPy object. )r   intr   as     r   to_sympyzFiniteField.to_sympy   s    CFF###r   c                 P   |j         r:|                     | j                            t          |                              S |j        rMt          |          |k    r:|                     | j                            t          |                              S t          d|z            )z0Convert SymPy's Integer to SymPy's ``Integer``. zexpected an integer, got %s)
is_Integerr   r   r/   is_Floatr   r0   s     r   
from_sympyzFiniteField.from_sympy   s    < 	D::dhnnSVV44555Z 	DCFFaK 	D::dhnnSVV44555 !>!BCCCr   c                 r    |                      | j                            |j        |j                            S z.Convert ``ModularInteger(int)`` to ``dtype``. )r   r   from_ZZvalK1r1   K0s      r   from_FFzFiniteField.from_FF   s(    xxqubf55666r   c                 r    |                      | j                            |j        |j                            S r8   )r   r   from_ZZ_pythonr:   r;   s      r   from_FF_pythonzFiniteField.from_FF_python   s*    xx--aeRV<<===r   c                 ^    |                      | j                            ||                    S z'Convert Python's ``int`` to ``dtype``. r   r   r@   r;   s      r   r9   zFiniteField.from_ZZ   &    xx--a44555r   c                 ^    |                      | j                            ||                    S rC   rD   r;   s      r   r@   zFiniteField.from_ZZ_python   rE   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   1    =A 	2$$Q[111	2 	2r   c                 P    |j         dk    r|                     |j                  S dS rH   rI   r;   s      r   from_QQ_pythonzFiniteField.from_QQ_python   rM   r   c                 r    |                      | j                            |j        |j                            S )z.Convert ``ModularInteger(mpz)`` to ``dtype``. )r   r   from_ZZ_gmpyr:   r;   s      r   from_FF_gmpyzFiniteField.from_FF_gmpy   s*    xx++AE26::;;;r   c                 ^    |                      | j                            ||                    S )z%Convert GMPY's ``mpz`` to ``dtype``. )r   r   rQ   r;   s      r   rQ   zFiniteField.from_ZZ_gmpy   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)rJ   rQ   rK   r;   s      r   from_QQ_gmpyzFiniteField.from_QQ_gmpy   s/    =A 	0??1;///	0 	0r   c                     |                     |          \  }}|dk    r-|                     | j                            |                    S dS )z'Convert mpmath's ``mpf`` to ``dtype``. r   N)to_rationalr   r   )r<   r1   r=   pqs        r   from_RealFieldzFiniteField.from_RealField   sK    ~~a  16 	-88BFLLOO,,,	- 	-r   )Tr    )r#   
__module____qualname____doc__repaliasis_FiniteFieldis_FFis_Numericalhas_assoc_Ringhas_assoc_Fieldr   r   r   r   r$   r(   r*   r-   r2   r6   r>   rA   r9   r@   rL   rO   rR   rQ   rU   rZ   r,   r   r   r
   r
      s       V Vp CE!!NULNO
C
C   # # #O O O< < <
    $ $ $D D D7 7 7 7> > > >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
   N)r]   sympy.polys.domains.fieldr   "sympy.polys.domains.modularintegerr    sympy.polys.domains.simpledomainr   sympy.polys.polyerrorsr   sympy.utilitiesr   sympy.polys.domains.groundtypesr   r
   r   GFr,   r   r   <module>rl      s    4 4 , + + + + + D D D D D D 9 9 9 9 9 9 1 1 1 1 1 1 " " " " " " 8 8 8 8 8 8~- ~- ~- ~- ~-% ~- ~- ~-B  RRRr   