a
    RG5dU                     @   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rHt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   Z/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/polys/agca/homomorphisms.py__init__8   s    

zModuleHomomorphism.__init__c                 C   s   | 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   s    

zModuleHomomorphism.kernelc                 C   s   | j du r|  | _ | j S )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\   s    

zModuleHomomorphism.imagec                 C   s   t dS )zCompute the kernel of ``self``.NNotImplementedErrorr   r   r   r   r   r   s    zModuleHomomorphism._kernelc                 C   s   t dS )zCompute the image of ``self``.Nr   r   r   r   r   r   v   s    zModuleHomomorphism._imagec                 C   s   t dS )%Implementation of domain restriction.Nr   r   smr   r   r   _restrict_domainz   s    z#ModuleHomomorphism._restrict_domainc                 C   s   t dS )'Implementation of codomain restriction.Nr   r   r   r   r   _restrict_codomain~   s    z%ModuleHomomorphism._restrict_codomainc                 C   s   t dS )"Implementation of domain quotient.Nr   r   r   r   r   _quotient_domain   s    z#ModuleHomomorphism._quotient_domainc                 C   s   t dS )$Implementation of codomain quotient.Nr   r   r   r   r   _quotient_codomain   s    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r0| 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   s   t dS )zApply ``self`` to ``elem``.Nr   r   elemr   r   r   _apply  s    zModuleHomomorphism._applyc                 C   s   | j | | j|S N)r   convertr.   r   r,   r   r   r   __call__  s    zModuleHomomorphism.__call__c                 C   s   t dS )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.)
        Nr   r   othr   r   r   _compose  s    zModuleHomomorphism._composec                 C   s   t dS )z8Scalar multiplication. ``c`` is guaranteed in self.ring.Nr   r   cr   r   r   _mul_scalar'  s    zModuleHomomorphism._mul_scalarc                 C   s   t dS )zv
        Homomorphism addition.
        ``oth`` is guaranteed to be a homomorphism with same domain/codomain.
        Nr   r2   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   r2   r   r   r   
_check_hom2  s    
zModuleHomomorphism._check_homc                 C   sP   t |tr | j|jkr || S z| | j|W S  tyJ   t	 Y S 0 d S r/   )
r	   r   r   r   r4   r7   r   r0   r   NotImplementedr2   r   r   r   __mul__8  s    
zModuleHomomorphism.__mul__c                 C   s4   z|  d| j| W S  ty.   t Y S 0 d S )N   )r7   r   r0   r   r:   r2   r   r   r   __truediv__C  s    zModuleHomomorphism.__truediv__c                 C   s   |  |r| |S tS r/   )r9   r8   r:   r2   r   r   r   __add__I  s    

zModuleHomomorphism.__add__c                 C   s&   |  |r"| || jdS tS )N)r9   r8   r7   r   r0   r:   r2   r   r   r   __sub__N  s    
zModuleHomomorphism.__sub__c                 C   s   |    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
        )rA   rB   r   r   r   r   is_isomorphism  s    z!ModuleHomomorphism.is_isomorphismc                 C   s   |    S )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 0 d S )NF)r)   r
   r2   r   r   r   __eq__  s    zModuleHomomorphism.__eq__c                 C   s
   | |k S r/   r   r2   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+   r.   r1   r4   r7   r8   r9   r;   __rmul__r=   r>   r@   rA   rB   rC   r)   rD   rE   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r2td|jt|f | jj t| jtt	frT| jj
j t fdd|D | _d S )Nz#Need to provide %s elements, got %sc                 3   s   | ]} |V  qd S r/   r   .0x	converterr   r   	<genexpr>      z.MatrixHomomorphism.__init__.<locals>.<genexpr>)r   r   lenrankr   r   r0   r	   r   r   	containertuplematrix)r   r   r   rW   r   rO   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 r/   r   rN   r   r   r   <lambda>  rR   z2MatrixHomomorphism._sympy_matrix.<locals>.<lambda>c                 S   s   | j S r/   )datarY   r   r   r   rZ     rR   c                    s"   g | ]}fd d |D qS )c                    s   g | ]} j |qS r   )r   to_sympy)rM   yr   r   r   
<listcomp>  rR   z?MatrixHomomorphism._sympy_matrix.<locals>.<listcomp>.<listcomp>r   rL   r6   r   r   r   r^     rR   z4MatrixHomomorphism._sympy_matrix.<locals>.<listcomp>)sympy.matricesrX   r	   r   r   r   rW   T)r   rX   r   r_   r   _sympy_matrix  s
    z MatrixHomomorphism._sympy_matrixc                 C   s   t |  d}d| j| jf }dt| }t|}t|d D ]}||  |7  < qB||d   |7  < t|d d |D ]}||  |7  < q~d|S )N
z : %s -> %s    r<   )reprrb   splitr   r   rS   rangejoin)r   linestsnir   r   r   __repr__  s    zMatrixHomomorphism.__repr__c                 C   s   t || j| jS )r   )SubModuleHomomorphismr   rW   r   r   r   r   r     s    z#MatrixHomomorphism._restrict_domainc                 C   s   |  | j|| jS )r    )	__class__r   rW   r   r   r   r   r!     s    z%MatrixHomomorphism._restrict_codomainc                 C   s   |  | j| | j| jS )r"   rq   r   r   rW   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                    s   g | ]} |qS r   r   rL   rO   r   r   r^     rR   z9MatrixHomomorphism._quotient_codomain.<locals>.<listcomp>)r   r0   r	   r   rU   rq   r   rW   )r   r   Qr   rO   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   )rM   rN   r]   r   r   r   r^     rR   z+MatrixHomomorphism._add.<locals>.<listcomp>)rq   r   r   ziprW   r2   r   r   r   r8     s    zMatrixHomomorphism._addc                    s"   |  | j| j fdd| jD S )Nc                    s   g | ]} | qS r   r   rL   r6   r   r   r^     rR   z2MatrixHomomorphism._mul_scalar.<locals>.<listcomp>rr   r5   r   ru   r   r7     s    zMatrixHomomorphism._mul_scalarc                    s"   |  | j j fdd| jD S )Nc                    s   g | ]} |qS r   r   rL   r3   r   r   r^     rR   z/MatrixHomomorphism._compose.<locals>.<listcomp>rr   r2   r   rv   r   r4     s    zMatrixHomomorphism._composeN)rF   rG   rH   rI   r   rb   ro   r   r!   r#   r%   r8   r7   r4   r   r   r   r   rK     s   	rK   c                   @   s(   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   s,   t | jtr|j}tdd t|| jD S )Nc                 s   s   | ]\}}|| V  qd S r/   r   rM   rN   er   r   r   rQ   /  rR   z0FreeModuleHomomorphism._apply.<locals>.<genexpr>)r	   r   r   r[   sumrt   rW   r,   r   r   r   r.   ,  s    zFreeModuleHomomorphism._applyc                 C   s   | j j| j S r/   )r   	submodulerW   r   r   r   r   r   1  s    zFreeModuleHomomorphism._imagec                 C   s   |    }| jj|j S r/   r   Zsyzygy_moduler   r{   gensr   Zsyzr   r   r   r   4  s    zFreeModuleHomomorphism._kernelNrF   rG   rH   rI   r.   r   r   r   r   r   r   rw     s   rw   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rp   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   s,   t | jtr|j}tdd t|| jD S )Nc                 s   s   | ]\}}|| V  qd S r/   r   rx   r   r   r   rQ   T  rR   z/SubModuleHomomorphism._apply.<locals>.<genexpr>)r	   r   r   r[   rz   rt   rW   r,   r   r   r   r.   Q  s    zSubModuleHomomorphism._applyc                    s    j j fdd jjD  S )Nc                    s   g | ]} |qS r   r   rL   r   r   r   r^   W  rR   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   s   | ]\}}|| V  qd S r/   r   )rM   xigir   r   r   rQ   \  rR   z;SubModuleHomomorphism._kernel.<locals>.<listcomp>.<genexpr>)rz   rt   r   r}   )rM   rl   r   r   r   r^   \  s   z1SubModuleHomomorphism._kernel.<locals>.<listcomp>r|   r~   r   r   r   r   Y  s    
zSubModuleHomomorphism._kernelNr   r   r   r   r   rp   >  s   rp   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rF j j j fddfS t  trl 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 r/   )r0   rY   moduler   r   rZ     rR   z0homomorphism.<locals>.freepres.<locals>.<lambda>c                    s     | jS r/   )r0   r[   rY   r   r   r   rZ     rR   c                    s    j | jS r/   )rU   r0   r[   rY   r   r   r   rZ     rR   c                    s    j | S r/   )rU   r0   rY   r   r   r   rZ     rR   )r	   r   r{   r   basekilled_moduler   rU   r   r   r   r   freepres  s    





zhomomorphism.<locals>.freepresc                    s   g | ]} |qS r   r   rL   ru   r   r   r^     rR   z homomorphism.<locals>.<listcomp>)rw   r'   r(   r+   r*   )r   r   rW   r   ZSFZSSZSQ_ZTFZTSZTQr   ru   r   homomorphism`  s    <r   N)rI   Zsympy.polys.agca.modulesr   r   r   r   r   sympy.polys.polyerrorsr   r   rK   rw   rp   r   r   r   r   r   <module>   s   	   -]%"