o
    jgU                     @   sv   d Z ddlmZmZmZmZmZ ddlmZ G dd dZ	G dd de	Z
G dd	 d	e
ZG d
d de
Zdd ZdS )a   
Computations with homomorphisms of modules and rings.

This module implements classes for representing homomorphisms of rings and
their modules. Instead of instantiating the classes directly, you should use
the function ``homomorphism(from, to, matrix)`` to create homomorphism objects.
    )Module
FreeModuleQuotientModule	SubModuleSubQuotientModule)CoercionFailedc                   @   s   e 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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eZd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!d<S )=ModuleHomomorphisma"  
    Abstract base class for module homomoprhisms. Do not instantiate.

    Instead, use the ``homomorphism`` function:

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> from sympy.polys.agca import homomorphism

    >>> F = QQ.old_poly_ring(x).free_module(2)
    >>> homomorphism(F, F, [[1, 0], [0, 1]])
    Matrix([
    [1, 0], : QQ[x]**2 -> QQ[x]**2
    [0, 1]])

    Attributes:

    - ring - the ring over which we are considering modules
    - domain - the domain module
    - codomain - the codomain module
    - _ker - cached kernel
    - _img - cached image

    Non-implemented methods:

    - _kernel
    - _image
    - _restrict_domain
    - _restrict_codomain
    - _quotient_domain
    - _quotient_codomain
    - _apply
    - _mul_scalar
    - _compose
    - _add
    c                 C   sl   t |tstd| t |tstd| |j|jkr$td||f || _|| _|j| _d | _d | _d S )NzSource must be a module, got %szTarget must be a module, got %sz8Source and codomain must be over same ring, got %s != %s)	
isinstancer   	TypeErrorring
ValueErrordomaincodomain_ker_img)selfr   r    r   V/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/polys/agca/homomorphisms.py__init__8   s   


zModuleHomomorphism.__init__c                 C      | j du r
|  | _ | j S )a  
        Compute the kernel of ``self``.

        That is, if ``self`` is the homomorphism `\phi: M \to N`, then compute
        `ker(\phi) = \{x \in M | \phi(x) = 0\}`.  This is a submodule of `M`.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> homomorphism(F, F, [[1, 0], [x, 0]]).kernel()
        <[x, -1]>
        N)r   _kernelr   r   r   r   kernelF      

zModuleHomomorphism.kernelc                 C   r   )a  
        Compute the image of ``self``.

        That is, if ``self`` is the homomorphism `\phi: M \to N`, then compute
        `im(\phi) = \{\phi(x) | x \in M \}`.  This is a submodule of `N`.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> homomorphism(F, F, [[1, 0], [x, 0]]).image() == F.submodule([1, 0])
        True
        N)r   _imager   r   r   r   image\   r   zModuleHomomorphism.imagec                 C      t )zCompute the kernel of ``self``.NotImplementedErrorr   r   r   r   r   r      zModuleHomomorphism._kernelc                 C   r   )zCompute the image of ``self``.r   r   r   r   r   r   v   r   zModuleHomomorphism._imagec                 C   r   z%Implementation of domain restriction.r   r   smr   r   r   _restrict_domainz   r   z#ModuleHomomorphism._restrict_domainc                 C   r   z'Implementation of codomain restriction.r   r!   r   r   r   _restrict_codomain~   r   z%ModuleHomomorphism._restrict_codomainc                 C   r   z"Implementation of domain quotient.r   r!   r   r   r   _quotient_domain   r   z#ModuleHomomorphism._quotient_domainc                 C   r   )$Implementation of codomain quotient.r   r!   r   r   r   _quotient_codomain   r   z%ModuleHomomorphism._quotient_codomainc                 C   s6   | j |std| j |f || j kr| S | |S )a?  
        Return ``self``, with the domain restricted to ``sm``.

        Here ``sm`` has to be a submodule of ``self.domain``.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2
        [0, 0]])
        >>> h.restrict_domain(F.submodule([1, 0]))
        Matrix([
        [1, x], : <[1, 0]> -> QQ[x]**2
        [0, 0]])

        This is the same as just composing on the right with the submodule
        inclusion:

        >>> h * F.submodule([1, 0]).inclusion_hom()
        Matrix([
        [1, x], : <[1, 0]> -> QQ[x]**2
        [0, 0]])
        z$sm must be a submodule of %s, got %s)r   is_submoduler   r#   r!   r   r   r   restrict_domain   s    

z"ModuleHomomorphism.restrict_domainc                 C   s:   | |  std|  |f || jkr| S | |S )a  
        Return ``self``, with codomain restricted to to ``sm``.

        Here ``sm`` has to be a submodule of ``self.codomain`` containing the
        image.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2
        [0, 0]])
        >>> h.restrict_codomain(F.submodule([1, 0]))
        Matrix([
        [1, x], : QQ[x]**2 -> <[1, 0]>
        [0, 0]])
        z$the image %s must contain sm, got %s)r*   r   r   r   r%   r!   r   r   r   restrict_codomain   s   


z$ModuleHomomorphism.restrict_codomainc                 C   s8   |   |std|   |f | r| S | |S )am  
        Return ``self`` with domain replaced by ``domain/sm``.

        Here ``sm`` must be a submodule of ``self.kernel()``.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2
        [0, 0]])
        >>> h.quotient_domain(F.submodule([-x, 1]))
        Matrix([
        [1, x], : QQ[x]**2/<[-x, 1]> -> QQ[x]**2
        [0, 0]])
        z!kernel %s must contain sm, got %s)r   r*   r   is_zeror'   r!   r   r   r   quotient_domain   s   

z"ModuleHomomorphism.quotient_domainc                 C   s4   | j |std| j |f | r| S | |S )a:  
        Return ``self`` with codomain replaced by ``codomain/sm``.

        Here ``sm`` must be a submodule of ``self.codomain``.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2
        [0, 0]])
        >>> h.quotient_codomain(F.submodule([1, 1]))
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]>
        [0, 0]])

        This is the same as composing with the quotient map on the left:

        >>> (F/[(1, 1)]).quotient_hom() * h
        Matrix([
        [1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]>
        [0, 0]])
        z-sm must be a submodule of codomain %s, got %s)r   r*   r   r-   r)   r!   r   r   r   quotient_codomain   s   
z$ModuleHomomorphism.quotient_codomainc                 C   r   )zApply ``self`` to ``elem``.r   r   elemr   r   r   _apply  r   zModuleHomomorphism._applyc                 C   s   | j | | j|S N)r   convertr2   r   r0   r   r   r   __call__  s   zModuleHomomorphism.__call__c                 C   r   )a	  
        Compose ``self`` with ``oth``, that is, return the homomorphism
        obtained by first applying then ``self``, then ``oth``.

        (This method is private since in this syntax, it is non-obvious which
        homomorphism is executed first.)
        r   r   othr   r   r   _compose  s   zModuleHomomorphism._composec                 C   r   )z8Scalar multiplication. ``c`` is guaranteed in self.ring.r   r   cr   r   r   _mul_scalar'  r   zModuleHomomorphism._mul_scalarc                 C   r   )zv
        Homomorphism addition.
        ``oth`` is guaranteed to be a homomorphism with same domain/codomain.
        r   r6   r   r   r   _add+  s   zModuleHomomorphism._addc                 C   s&   t |tsdS |j| jko|j| jkS )zEHelper to check that oth is a homomorphism with same domain/codomain.F)r	   r   r   r   r6   r   r   r   
_check_hom2  s   
zModuleHomomorphism._check_homc                 C   sL   t |tr| j|jkr|| S z
| | j|W S  ty%   t	 Y S w r3   )
r	   r   r   r   r8   r;   r   r4   r   NotImplementedr6   r   r   r   __mul__8  s   
zModuleHomomorphism.__mul__c                 C   s0   z|  d| j| W S  ty   t Y S w )N   )r;   r   r4   r   r>   r6   r   r   r   __truediv__C  s
   zModuleHomomorphism.__truediv__c                 C   s   |  |r
| |S tS r3   )r=   r<   r>   r6   r   r   r   __add__I  s   

zModuleHomomorphism.__add__c                 C   s&   |  |r| || jdS tS )N)r=   r<   r;   r   r4   r>   r6   r   r   r   __sub__N  s   
zModuleHomomorphism.__sub__c                 C      |    S )a  
        Return True if ``self`` is injective.

        That is, check if the elements of the domain are mapped to the same
        codomain element.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h.is_injective()
        False
        >>> h.quotient_domain(h.kernel()).is_injective()
        True
        )r   r-   r   r   r   r   is_injectiveS  s   zModuleHomomorphism.is_injectivec                 C   s   |   | jkS )a  
        Return True if ``self`` is surjective.

        That is, check if every element of the codomain has at least one
        preimage.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h.is_surjective()
        False
        >>> h.restrict_codomain(h.image()).is_surjective()
        True
        )r   r   r   r   r   r   is_surjectivej  s   z ModuleHomomorphism.is_surjectivec                 C   s   |   o|  S )a~  
        Return True if ``self`` is an isomorphism.

        That is, check if every element of the codomain has precisely one
        preimage. Equivalently, ``self`` is both injective and surjective.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h = h.restrict_codomain(h.image())
        >>> h.is_isomorphism()
        False
        >>> h.quotient_domain(h.kernel()).is_isomorphism()
        True
        )rF   rG   r   r   r   r   is_isomorphism  s   z!ModuleHomomorphism.is_isomorphismc                 C   rE   )aN  
        Return True if ``self`` is a zero morphism.

        That is, check if every element of the domain is mapped to zero
        under self.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x
        >>> from sympy.polys.agca import homomorphism

        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> h = homomorphism(F, F, [[1, 0], [x, 0]])
        >>> h.is_zero()
        False
        >>> h.restrict_domain(F.submodule()).is_zero()
        True
        >>> h.quotient_codomain(h.image()).is_zero()
        True
        )r   r-   r   r   r   r   r-     s   zModuleHomomorphism.is_zeroc                 C   s$   z| |   W S  ty   Y dS w )NF)r-   r
   r6   r   r   r   __eq__  s
   zModuleHomomorphism.__eq__c                 C   s
   | |k S r3   r   r6   r   r   r   __ne__  s   
zModuleHomomorphism.__ne__N)"__name__
__module____qualname____doc__r   r   r   r   r   r#   r%   r'   r)   r+   r,   r.   r/   r2   r5   r8   r;   r<   r=   r?   __rmul__rA   rB   rD   rF   rG   rH   r-   rI   rJ   r   r   r   r   r      s@    %' &
	r   c                   @   s`   e 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d ZdS )MatrixHomomorphisma  
    Helper class for all homomoprhisms which are expressed via a matrix.

    That is, for such homomorphisms ``domain`` is contained in a module
    generated by finitely many elements `e_1, \ldots, e_n`, so that the
    homomorphism is determined uniquely by its action on the `e_i`. It
    can thus be represented as a vector of elements of the codomain module,
    or potentially a supermodule of the codomain module
    (and hence conventionally as a matrix, if there is a similar interpretation
    for elements of the codomain module).

    Note that this class does *not* assume that the `e_i` freely generate a
    submodule, nor that ``domain`` is even all of this submodule. It exists
    only to unify the interface.

    Do not instantiate.

    Attributes:

    - matrix - the list of images determining the homomorphism.
    NOTE: the elements of matrix belong to either self.codomain or
          self.codomain.container

    Still non-implemented methods:

    - kernel
    - _apply
    c                    sp   t | || t||jkrtd|jt|f | jj t| jtt	fr*| jj
j t fdd|D | _d S )Nz#Need to provide %s elements, got %sc                 3   s    | ]} |V  qd S r3   r   .0x	converterr   r   	<genexpr>  s    z.MatrixHomomorphism.__init__.<locals>.<genexpr>)r   r   lenrankr   r   r4   r	   r   r   	containertuplematrix)r   r   r   r[   r   rT   r   r     s   
zMatrixHomomorphism.__init__c                    sH   ddl m} dd  tjttfrdd  | fddjD jS )z=Helper function which returns a SymPy matrix ``self.matrix``.r   )Matrixc                 S   s   | S r3   r   rS   r   r   r   <lambda>  s    z2MatrixHomomorphism._sympy_matrix.<locals>.<lambda>c                 S   s   | j S r3   )datar]   r   r   r   r^     s    c                    s"   g | ]}fd d |D qS )c                    s   g | ]} j |qS r   )r   to_sympy)rR   yr   r   r   
<listcomp>      z?MatrixHomomorphism._sympy_matrix.<locals>.<listcomp>.<listcomp>r   rQ   r:   r   r   r   rb     s   " z4MatrixHomomorphism._sympy_matrix.<locals>.<listcomp>)sympy.matricesr\   r	   r   r   r   r[   T)r   r\   r   rd   r   _sympy_matrix  s
   z MatrixHomomorphism._sympy_matrixc                 C   s   t |  d}d| j| jf }dt| }t|}t|d D ]
}||  |7  < q!||d   |7  < t|d d |D ]
}||  |7  < q?d|S )N
z : %s -> %s    r@   )reprrg   splitr   r   rW   rangejoin)r   linestsnir   r   r   __repr__  s   
zMatrixHomomorphism.__repr__c                 C   s   t || j| jS r    )SubModuleHomomorphismr   r[   r!   r   r   r   r#     s   z#MatrixHomomorphism._restrict_domainc                 C   s   |  | j|| jS r$   )	__class__r   r[   r!   r   r   r   r%     s   z%MatrixHomomorphism._restrict_codomainc                 C   s   |  | j| | j| jS r&   rv   r   r   r[   r!   r   r   r   r'     s   z#MatrixHomomorphism._quotient_domainc                    sJ   | j | }|j t| j tr|jj | | j| j |  fdd| jD S )r(   c                       g | ]} |qS r   r   rQ   rT   r   r   rb         z9MatrixHomomorphism._quotient_codomain.<locals>.<listcomp>)r   r4   r	   r   rY   rv   r   r[   )r   r"   Qr   rT   r   r)     s   
z%MatrixHomomorphism._quotient_codomainc                 C   s&   |  | j| jdd t| j|jD S )Nc                 S   s   g | ]\}}|| qS r   r   )rR   rS   ra   r   r   r   rb     rc   z+MatrixHomomorphism._add.<locals>.<listcomp>)rv   r   r   zipr[   r6   r   r   r   r<     s   zMatrixHomomorphism._addc                    s"   |  | j| j fdd| jD S )Nc                    s   g | ]} | qS r   r   rQ   r:   r   r   rb     ry   z2MatrixHomomorphism._mul_scalar.<locals>.<listcomp>rw   r9   r   r|   r   r;        "zMatrixHomomorphism._mul_scalarc                    s"   |  | j j fdd| jD S )Nc                    rx   r   r   rQ   r7   r   r   rb     ry   z/MatrixHomomorphism._compose.<locals>.<listcomp>rw   r6   r   r~   r   r8     r}   zMatrixHomomorphism._composeN)rK   rL   rM   rN   r   rg   rt   r#   r%   r'   r)   r<   r;   r8   r   r   r   r   rP     s    	rP   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	FreeModuleHomomorphisma  
    Concrete class for homomorphisms with domain a free module or a quotient
    thereof.

    Do not instantiate; the constructor does not check that your data is well
    defined. Use the ``homomorphism`` function instead:

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> from sympy.polys.agca import homomorphism

    >>> F = QQ.old_poly_ring(x).free_module(2)
    >>> homomorphism(F, F, [[1, 0], [0, 1]])
    Matrix([
    [1, 0], : QQ[x]**2 -> QQ[x]**2
    [0, 1]])
    c                 C   ,   t | jtr	|j}tdd t|| jD S )Nc                 s       | ]	\}}|| V  qd S r3   r   rR   rS   er   r   r   rV   /      z0FreeModuleHomomorphism._apply.<locals>.<genexpr>)r	   r   r   r_   sumr{   r[   r0   r   r   r   r2   ,     zFreeModuleHomomorphism._applyc                 C   s   | j j| j S r3   )r   	submoduler[   r   r   r   r   r   1  s   zFreeModuleHomomorphism._imagec                 C   s   |    }| jj|j S r3   r   syzygy_moduler   r   gensr   syzr   r   r   r   4  s   zFreeModuleHomomorphism._kernelNrK   rL   rM   rN   r2   r   r   r   r   r   r   r     
    r   c                   @   r   )	ru   a  
    Concrete class for homomorphism with domain a submodule of a free module
    or a quotient thereof.

    Do not instantiate; the constructor does not check that your data is well
    defined. Use the ``homomorphism`` function instead:

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> from sympy.polys.agca import homomorphism

    >>> M = QQ.old_poly_ring(x).free_module(2)*x
    >>> homomorphism(M, M, [[1, 0], [0, 1]])
    Matrix([
    [1, 0], : <[x, 0], [0, x]> -> <[x, 0], [0, x]>
    [0, 1]])
    c                 C   r   )Nc                 s   r   r3   r   r   r   r   r   rV   T  r   z/SubModuleHomomorphism._apply.<locals>.<genexpr>)r	   r   r   r_   r   r{   r[   r0   r   r   r   r2   Q  r   zSubModuleHomomorphism._applyc                    s    j j fdd jjD  S )Nc                    rx   r   r   rQ   r   r   r   rb   W  ry   z0SubModuleHomomorphism._image.<locals>.<listcomp>)r   r   r   r   r   r   r   r   r   V  s   zSubModuleHomomorphism._imagec                    s(       } jj fdd|jD  S )Nc                    s(   g | ]}t d d t| jjD qS )c                 s   r   r3   r   )rR   xigir   r   r   rV   \  r   z;SubModuleHomomorphism._kernel.<locals>.<listcomp>.<genexpr>)r   r{   r   r   )rR   rq   r   r   r   rb   \  s     z1SubModuleHomomorphism._kernel.<locals>.<listcomp>r   r   r   r   r   r   Y  s   
zSubModuleHomomorphism._kernelNr   r   r   r   r   ru   >  r   ru   c                    sZ   dd }|| \}}}}||\}}	}
 t || fdd|D ||	|
|S )a>  
    Create a homomorphism object.

    This function tries to build a homomorphism from ``domain`` to ``codomain``
    via the matrix ``matrix``.

    Examples
    ========

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> from sympy.polys.agca import homomorphism

    >>> R = QQ.old_poly_ring(x)
    >>> T = R.free_module(2)

    If ``domain`` is a free module generated by `e_1, \ldots, e_n`, then
    ``matrix`` should be an n-element iterable `(b_1, \ldots, b_n)` where
    the `b_i` are elements of ``codomain``. The constructed homomorphism is the
    unique homomorphism sending `e_i` to `b_i`.

    >>> F = R.free_module(2)
    >>> h = homomorphism(F, T, [[1, x], [x**2, 0]])
    >>> h
    Matrix([
    [1, x**2], : QQ[x]**2 -> QQ[x]**2
    [x,    0]])
    >>> h([1, 0])
    [1, x]
    >>> h([0, 1])
    [x**2, 0]
    >>> h([1, 1])
    [x**2 + 1, x]

    If ``domain`` is a submodule of a free module, them ``matrix`` determines
    a homomoprhism from the containing free module to ``codomain``, and the
    homomorphism returned is obtained by restriction to ``domain``.

    >>> S = F.submodule([1, 0], [0, x])
    >>> homomorphism(S, T, [[1, x], [x**2, 0]])
    Matrix([
    [1, x**2], : <[1, 0], [0, x]> -> QQ[x]**2
    [x,    0]])

    If ``domain`` is a (sub)quotient `N/K`, then ``matrix`` determines a
    homomorphism from `N` to ``codomain``. If the kernel contains `K`, this
    homomorphism descends to ``domain`` and is returned; otherwise an exception
    is raised.

    >>> homomorphism(S/[(1, 0)], T, [0, [x**2, 0]])
    Matrix([
    [0, x**2], : <[1, 0] + <[1, 0]>, [0, x] + <[1, 0]>, [1, 0] + <[1, 0]>> -> QQ[x]**2
    [0,    0]])
    >>> homomorphism(S/[(0, x)], T, [0, [x**2, 0]])
    Traceback (most recent call last):
    ...
    ValueError: kernel <[1, 0], [0, 0]> must contain sm, got <[0,x]>

    c                    s   t  tr     fddfS t  tr# j j j fddfS t  tr6 jj j j fddfS  j    fddfS )z
        Return a tuple ``(F, S, Q, c)`` where ``F`` is a free module, ``S`` is a
        submodule of ``F``, and ``Q`` a submodule of ``S``, such that
        ``module = S/Q``, and ``c`` is a conversion function.
        c                    s
     | S r3   )r4   r]   moduler   r   r^     s   
 z0homomorphism.<locals>.freepres.<locals>.<lambda>c                    s     | jS r3   )r4   r_   r]   r   r   r   r^         c                    s    j | jS r3   )rY   r4   r_   r]   r   r   r   r^     s    c                    s    j | S r3   )rY   r4   r]   r   r   r   r^     r   )r	   r   r   r   basekilled_moduler   rY   r   r   r   r   freepres  s   





zhomomorphism.<locals>.freepresc                    rx   r   r   rQ   r|   r   r   rb     ry   z homomorphism.<locals>.<listcomp>)r   r+   r,   r/   r.   )r   r   r[   r   SFSSSQ_TFTSTQr   r|   r   homomorphism`  s   <r   N)rN   sympy.polys.agca.modulesr   r   r   r   r   sympy.polys.polyerrorsr   r   rP   r   ru   r   r   r   r   r   <module>   s    	   -]%"