o
    jg                     @   sT  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	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ G dd dZG dd dZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdd Zdd ZG dd de	ZG d d! d!eZG d"d# d#eZG d$d% d%eZ G d&d' d'eZ!d(S ))ao  
Computations with modules over polynomial rings.

This module implements various classes that encapsulate groebner basis
computations for modules. Most of them should not be instantiated by hand.
Instead, use the constructing routines on objects you already have.

For example, to construct a free module over ``QQ[x, y]``, call
``QQ[x, y].free_module(rank)`` instead of the ``FreeModule`` constructor.
In fact ``FreeModule`` is an abstract base class that should not be
instantiated, the ``free_module`` method instead returns the implementing class
``FreeModulePolyRing``.

In general, the abstract base classes implement most functionality in terms of
a few non-implemented methods. The concrete base classes supply only these
non-implemented methods. They may also supply new implementations of the
convenience methods, for example if there are faster algorithms available.
    )copy)reduce)Ideal)Field)ProductOrdermonomial_key)DMP)CoercionFailed)_aresame)iterablec                   @   s   e Zd ZdZdd 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d Zdd Zdd ZeZdd  ZdS )"Modulea  
    Abstract base class for modules.

    Do not instantiate - use ring explicit constructors instead:

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> QQ.old_poly_ring(x).free_module(2)
    QQ[x]**2

    Attributes:

    - dtype - type of elements
    - ring - containing ring

    Non-implemented methods:

    - submodule
    - quotient_module
    - is_zero
    - is_submodule
    - multiply_ideal

    The method convert likely needs to be changed in subclasses.
    c                 C   s
   || _ d S N)ring)selfr    r   P/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/polys/agca/modules.py__init__G      
zModule.__init__Nc                 C   s   t || jst|S )z
        Convert ``elem`` into internal representation of this module.

        If ``M`` is not None, it should be a module containing it.
        )
isinstancedtyper	   r   elemMr   r   r   convertJ   s   zModule.convertc                 G      t )zGenerate a submodule.NotImplementedErrorr   gensr   r   r   	submoduleT      zModule.submodulec                 C   r   )zGenerate a quotient module.r   r   otherr   r   r   quotient_moduleX   r    zModule.quotient_modulec                 C   s   t |ts
| j| }| |S r   )r   r   r   r#   r   er   r   r   __truediv__\   s   


zModule.__truediv__c                 C   s&   z|  | W dS  ty   Y dS w )z5Return True if ``elem`` is an element of this module.TF)r   r	   r   r   r   r   r   containsa   s   
zModule.containsc                 C   
   |  |S r   r(   r'   r   r   r   __contains__i   r   zModule.__contains__c                       t  fdd|D S )aN  
        Returns True if ``other`` is is a subset of ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> F.subset([(1, x), (x, 2)])
        True
        >>> F.subset([(1/x, x), (x, 2)])
        False
        c                 3       | ]}  |V  qd S r   r*   .0xr   r   r   	<genexpr>{       z Module.subset.<locals>.<genexpr>allr!   r   r1   r   subsetl   s   zModule.subsetc                 C   s   |  |o	| | S r   )is_submoduler!   r   r   r   __eq__}      zModule.__eq__c                 C   
   | |k S r   r   r!   r   r   r   __ne__   r   zModule.__ne__c                 C   r   )z*Returns True if ``self`` is a zero module.r   r1   r   r   r   is_zero   r    zModule.is_zeroc                 C   r   )z5Returns True if ``other`` is a submodule of ``self``.r   r!   r   r   r   r7      r    zModule.is_submodulec                 C   r   )z;
        Multiply ``self`` by the ideal ``other``.
        r   r!   r   r   r   multiply_ideal   s   zModule.multiply_idealc              	   C   s@   t |tsz| j|}W n ttfy   t Y S w | |S r   )r   r   r   idealr	   r   NotImplementedr=   r$   r   r   r   __mul__   s   

zModule.__mul__c                 C   r   )z-Return the identity homomorphism on ``self``.r   r1   r   r   r   identity_hom   r    zModule.identity_homr   )__name__
__module____qualname____doc__r   r   r   r#   r&   r(   r+   r6   r8   r;   r<   r7   r=   r@   __rmul__rA   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	e	Z
dd Zdd Zdd Zdd ZeZdd Zdd Zdd ZdS )ModuleElementa  
    Base class for module element wrappers.

    Use this class to wrap primitive data types as module elements. It stores
    a reference to the containing module, and implements all the arithmetic
    operators.

    Attributes:

    - module - containing module
    - data - internal data

    Methods that likely need change in subclasses:

    - add
    - mul
    - div
    - eq
    c                 C   s   || _ || _d S r   )moduledata)r   rH   rI   r   r   r   r      s   
zModuleElement.__init__c                 C   s   || S )zAdd data ``d1`` and ``d2``.r   r   d1d2r   r   r   add      zModuleElement.addc                 C   s   || S )z,Multiply module data ``m`` by coefficient d.r   r   mdr   r   r   mul   rN   zModuleElement.mulc                 C   s   || S )z*Divide module data ``m`` by coefficient d.r   rO   r   r   r   div   rN   zModuleElement.divc                 C   s   ||kS )z4Return true if d1 and d2 represent the same element.r   rJ   r   r   r   eq   rN   zModuleElement.eqc                 C   sZ   t || jr|j| jkr z| j|}W n ty   t Y S w | | j| | j|jS r   )r   	__class__rH   r   r	   r?   rM   rI   r   omr   r   r   __add__   s   zModuleElement.__add__c              	   C   s"   |  | j| | j| jjdS )N)rU   rH   rR   rI   r   r   r1   r   r   r   __neg__   s   zModuleElement.__neg__c                 C   sL   t || jr|j| jkr z| j|}W n ty   t Y S w | | S r   )r   rU   rH   r   r	   r?   rX   rV   r   r   r   __sub__   s   zModuleElement.__sub__c                 C   s   |   |S r   )rX   rV   r   r   r   __rsub__   s   zModuleElement.__rsub__c                 C   R   t || jjjsz	| jj|}W n ty   t Y S w | | j| | j	|S r   )
r   rH   r   r   r   r	   r?   rU   rR   rI   r   or   r   r   r@         zModuleElement.__mul__c                 C   r]   r   )
r   rH   r   r   r   r	   r?   rU   rS   rI   r^   r   r   r   r&      r`   zModuleElement.__truediv__c                 C   sN   t || jr|j| jkrz| j|}W n
 ty   Y dS w | | j|jS NF)r   rU   rH   r   r	   rT   rI   rV   r   r   r   r8      s   zModuleElement.__eq__c                 C   r:   r   r   rV   r   r   r   r;      r   zModuleElement.__ne__N)rB   rC   rD   rE   r   rM   rR   rS   rT   rX   __radd__rZ   r[   r\   r@   rF   r&   r8   r;   r   r   r   r   rG      s"    rG   c                   @   @   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S )FreeModuleElementz1Element of a free module. Data stored as a tuple.c                 C   s   t dd t||D S )Nc                 s   s    | ]	\}}|| V  qd S r   r   )r/   r0   yr   r   r   r2         z(FreeModuleElement.add.<locals>.<genexpr>)tupleziprJ   r   r   r   rM        zFreeModuleElement.addc                    r,   )Nc                 3   s    | ]}|  V  qd S r   r   r.   pr   r   r2         z(FreeModuleElement.mul.<locals>.<genexpr>rg   r   rQ   rk   r   rj   r   rR   
     zFreeModuleElement.mulc                    r,   )Nc                 3   s    | ]}|  V  qd S r   r   r.   rj   r   r   r2     rl   z(FreeModuleElement.div.<locals>.<genexpr>rm   rn   r   rj   r   rS     ro   zFreeModuleElement.divc                    sV   ddl m  j}tdd |D r fdd|D }ddfd	d|D  d
 S )Nr   sstrc                 s   s    | ]}t |tV  qd S r   )r   r   r.   r   r   r   r2     r3   z-FreeModuleElement.__repr__.<locals>.<genexpr>c                    s   g | ]	} j j|qS r   )rH   r   to_sympyr.   r1   r   r   
<listcomp>      z.FreeModuleElement.__repr__.<locals>.<listcomp>[, c                 3   s    | ]} |V  qd S r   r   r.   rp   r   r   r2     rl   ])sympy.printing.strrq   rI   anyjoin)r   rI   r   )r   rq   r   __repr__  s
    zFreeModuleElement.__repr__c                 C   
   | j  S r   )rI   __iter__r1   r   r   r   r}     r   zFreeModuleElement.__iter__c                 C   s
   | j | S r   rI   )r   idxr   r   r   __getitem__  r   zFreeModuleElement.__getitem__N)
rB   rC   rD   rE   rM   rR   rS   r{   r}   r   r   r   r   r   rd     s    rd   c                   @   s^   e Zd ZdZeZdd Zdd Zdd Zdd	d
Z	dd Z
dd Zdd Zdd Zdd ZdS )
FreeModulez
    Abstract base class for free modules.

    Additional attributes:

    - rank - rank of the free module

    Non-implemented methods:

    - submodule
    c                 C   s   t | | || _d S r   )r   r   rank)r   r   r   r   r   r   r   -  s   
zFreeModule.__init__c                 C      t | jd t | j S )N**reprr   r   r1   r   r   r   r{   1  ri   zFreeModule.__repr__c                 C   s:   t |tr
|j| kS t |tr|j| jko|j| jkS dS )a  
        Returns True if ``other`` is a submodule of ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> M = F.submodule([2, x])
        >>> F.is_submodule(F)
        True
        >>> F.is_submodule(M)
        True
        >>> M.is_submodule(F)
        False
        F)r   	SubModule	containerr   r   r   r!   r   r   r   r7   4  s
   


zFreeModule.is_submoduleNc                    s   t  tr% ju r S  jjjkrttt fdd jD S t rBtfdd D }t|jkr=tt|S t	 drTtj
dfj S t)a  
        Convert ``elem`` into the internal representation.

        This method is called implicitly whenever computations involve elements
        not in the internal representation.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> F.convert([1, 0])
        [1, 0]
        c                 3   s"    | ]}j | jj V  qd S r   )r   r   rH   r.   r   r   r   r   r2   b       z%FreeModule.convert.<locals>.<genexpr>c                 3   s    | ]	} j |V  qd S r   )r   r   r.   r1   r   r   r2   d  rf   r   )r   rd   rH   r   r	   rg   rI   r   lenr
   r   r   )r   r   r   tplr   r   r   r   L  s    



zFreeModule.convertc                 C   s
   | j dkS )a  
        Returns True if ``self`` is a zero module.

        (If, as this implementation assumes, the coefficient ring is not the
        zero ring, then this is equivalent to the rank being zero.)

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(0).is_zero()
        True
        >>> QQ.old_poly_ring(x).free_module(1).is_zero()
        False
        r   )r   r1   r   r   r   r<   m  s   
zFreeModule.is_zeroc                    s4   ddl m} |j t fddtjD S )z
        Return a set of basis elements.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(3).basis()
        ([1, 0, 0], [0, 1, 0], [0, 0, 1])
        r   )eyec                 3   s     | ]}  |V  qd S r   )r   rowr/   ir   r   r   r   r2     s    z#FreeModule.basis.<locals>.<genexpr>)sympy.matricesr   r   rg   range)r   r   r   r   r   basis  s   
zFreeModule.basisc                 C   s   t | j| |S )a  
        Return a quotient module.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x).free_module(2)
        >>> M.quotient_module(M.submodule([1, x], [x, 2]))
        QQ[x]**2/<[1, x], [x, 2]>

        Or more conicisely, using the overloaded division operator:

        >>> QQ.old_poly_ring(x).free_module(2) / [[1, x], [x, 2]]
        QQ[x]**2/<[1, x], [x, 2]>
        )QuotientModuler   )r   r   r   r   r   r#     s   zFreeModule.quotient_modulec                 C   s   | j |   |S )a=  
        Multiply ``self`` by the ideal ``other``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> I = QQ.old_poly_ring(x).ideal(x)
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> F.multiply_ideal(I)
        <[x, 0], [0, x]>
        )r   r   r=   r!   r   r   r   r=     s   zFreeModule.multiply_idealc                 C   s   ddl m} || | |  S )a/  
        Return the identity homomorphism on ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(2).identity_hom()
        Matrix([
        [1, 0], : QQ[x]**2 -> QQ[x]**2
        [0, 1]])
        r   )homomorphism)sympy.polys.agca.homomorphismsr   r   )r   r   r   r   r   rA     s   zFreeModule.identity_homr   )rB   rC   rD   rE   rd   r   r   r{   r7   r   r<   r   r#   r=   rA   r   r   r   r   r     s    
!r   c                   @       e Zd ZdZdd Zdd ZdS )FreeModulePolyRingaw  
    Free module over a generalized polynomial ring.

    Do not instantiate this, use the constructor method of the ring instead:

    Examples
    ========

    >>> from sympy.abc import x
    >>> from sympy import QQ
    >>> F = QQ.old_poly_ring(x).free_module(3)
    >>> F
    QQ[x]**3
    >>> F.contains([x, 1, 0])
    True
    >>> F.contains([1/x, 0, 1])
    False
    c                 C   sV   ddl m} t| || t||stdd|  t|jts)tdd|j  d S )Nr   )PolynomialRingBase$This implementation only works over zpolynomial rings, got %szGround domain must be a field, zgot %s)&sympy.polys.domains.old_polynomialringr   r   r   r   r   domr   )r   r   r   r   r   r   r   r     s   
zFreeModulePolyRing.__init__c                 O      t || fi |S )ae  
        Generate a submodule.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x, y).free_module(2).submodule([x, x + y])
        >>> M
        <[x, x + y]>
        >>> M.contains([2*x, 2*x + 2*y])
        True
        >>> M.contains([x, y])
        False
        )SubModulePolyRingr   r   optsr   r   r   r        zFreeModulePolyRing.submoduleN)rB   rC   rD   rE   r   r   r   r   r   r   r     s    
r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )FreeModuleQuotientRinga  
    Free module over a quotient ring.

    Do not instantiate this, use the constructor method of the ring instead:

    Examples
    ========

    >>> from sympy.abc import x
    >>> from sympy import QQ
    >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(3)
    >>> F
    (QQ[x]/<x**2 + 1>)**3

    Attributes

    - quot - the quotient module `R^n / IR^n`, where `R/I` is our ring
    c                 C   sZ   ddl m} t| || t||stdd|  | jj| j}|| jj	|  | _
d S )Nr   )QuotientRingr   zquotient rings, got %s) sympy.polys.domains.quotientringr   r   r   r   r   r   free_moduler   
base_idealquot)r   r   r   r   Fr   r   r   r     s   
zFreeModuleQuotientRing.__init__c                 C   s    dt | j d d t | j S )N()r   r   r1   r   r   r   r{     s    zFreeModuleQuotientRing.__repr__c                 O   r   )a  
        Generate a submodule.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y])
        >>> M
        <[x + <x**2 - y**2>, x + y + <x**2 - y**2>]>
        >>> M.contains([y**2, x**2 + x*y])
        True
        >>> M.contains([x, y])
        False
        )SubModuleQuotientRingr   r   r   r   r     r   z FreeModuleQuotientRing.submodulec                 C   s   | j dd |D S )ae  
        Lift the element ``elem`` of self to the module self.quot.

        Note that self.quot is the same set as self, just as an R-module
        and not as an R/I-module, so this makes sense.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2)
        >>> e = F.convert([1, 0])
        >>> e
        [1 + <x**2 + 1>, 0 + <x**2 + 1>]
        >>> L = F.quot
        >>> l = F.lift(e)
        >>> l
        [1, 0] + <[x**2 + 1, 0], [0, x**2 + 1]>
        >>> L.contains(l)
        True
        c                 S      g | ]}|j qS r   r~   r.   r   r   r   rs   B      z/FreeModuleQuotientRing.lift.<locals>.<listcomp>)r   r   r'   r   r   r   lift+  s   zFreeModuleQuotientRing.liftc                 C   s   |  |jS )a  
        Push down an element of self.quot to self.

        This undoes ``lift``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2)
        >>> e = F.convert([1, 0])
        >>> l = F.lift(e)
        >>> e == l
        False
        >>> e == F.unlift(l)
        True
        )r   rI   r'   r   r   r   unliftD  s   zFreeModuleQuotientRing.unliftN)	rB   rC   rD   rE   r   r{   r   r   r   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d1d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/d0 ZdS )2r   a  
    Base class for submodules.

    Attributes:

    - container - containing module
    - gens - generators (subset of containing module)
    - rank - rank of containing module

    Non-implemented methods:

    - _contains
    - _syzygies
    - _in_terms_of_generators
    - _intersect
    - _module_quotient

    Methods that likely need change in subclasses:

    - reduce_element
    c                    sH   t |  j t fdd|D | _ | _ j| _ j| _ j| _d S )Nc                 3   r-   r   r   r.   r   r   r   r2   w  r3   z%SubModule.__init__.<locals>.<genexpr>)r   r   r   rg   r   r   r   r   r   r   r   r   r   r   r   u  s   zSubModule.__init__c                 C   s   dd dd | jD  d S )N<rv   c                 s   s    | ]}t |V  qd S r   )r   r.   r   r   r   r2   ~  rl   z%SubModule.__repr__.<locals>.<genexpr>>)rz   r   r1   r   r   r   r{   }  s   zSubModule.__repr__c                 C   r   )zVImplementation of containment.
           Other is guaranteed to be FreeModuleElement.r   r!   r   r   r   	_contains     zSubModule._containsc                 C   r   )z9Implementation of syzygy computation wrt self generators.r   r1   r   r   r   	_syzygies  r    zSubModule._syzygiesc                 C   r   )z4Implementation of expression in terms of generators.r   r$   r   r   r   _in_terms_of_generators  r    z!SubModule._in_terms_of_generatorsNc                 C   sF   t || jjr|j| u r|S t| j||}| |_| |s!t|S )aF  
        Convert ``elem`` into the internal represantition.

        Mostly called implicitly.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, x])
        >>> M.convert([2, 2*x])
        [2, 2*x]
        )r   r   r   rH   r   r   r   r	   )r   r   r   rr   r   r   r     s   
zSubModule.convertc                 C   r   )zeImplementation of intersection.
           Other is guaranteed to be a submodule of same free module.r   r!   r   r   r   
_intersect  r   zSubModule._intersectc                 C   r   )zaImplementation of quotient.
           Other is guaranteed to be a submodule of same free module.r   r!   r   r   r   _module_quotient  r   zSubModule._module_quotientc                 K   @   t |tstd| |j| jkrtd| | j|fi |S )a  
        Returns the intersection of ``self`` with submodule ``other``.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x, y).free_module(2)
        >>> F.submodule([x, x]).intersect(F.submodule([y, y]))
        <[x*y, x*y]>

        Some implementation allow further options to be passed. Currently, to
        only one implemented is ``relations=True``, in which case the function
        will return a triple ``(res, rela, relb)``, where ``res`` is the
        intersection module, and ``rela`` and ``relb`` are lists of coefficient
        vectors, expressing the generators of ``res`` in terms of the
        generators of ``self`` (``rela``) and ``other`` (``relb``).

        >>> F.submodule([x, x]).intersect(F.submodule([y, y]), relations=True)
        (<[x*y, x*y]>, [(DMP_Python([[1, 0]], QQ),)], [(DMP_Python([[1], []], QQ),)])

        The above result says: the intersection module is generated by the
        single element `(-xy, -xy) = -y (x, x) = -x (y, y)`, where
        `(x, x)` and `(y, y)` respectively are the unique generators of
        the two modules being intersected.
        %s is not a SubModule*%s is contained in a different free module)r   r   	TypeErrorr   
ValueErrorr   r   r"   optionsr   r   r   	intersect  s   
zSubModule.intersectc                 K   r   )a  
        Returns the module quotient of ``self`` by submodule ``other``.

        That is, if ``self`` is the module `M` and ``other`` is `N`, then
        return the ideal `\{f \in R | fN \subset M\}`.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x, y
        >>> F = QQ.old_poly_ring(x, y).free_module(2)
        >>> S = F.submodule([x*y, x*y])
        >>> T = F.submodule([x, x])
        >>> S.module_quotient(T)
        <y>

        Some implementations allow further options to be passed. Currently, the
        only one implemented is ``relations=True``, which may only be passed
        if ``other`` is principal. In this case the function
        will return a pair ``(res, rel)`` where ``res`` is the ideal, and
        ``rel`` is a list of coefficient vectors, expressing the generators of
        the ideal, multiplied by the generator of ``other`` in terms of
        generators of ``self``.

        >>> S.module_quotient(T, relations=True)
        (<y>, [[DMP_Python([[1]], QQ)]])

        This means that the quotient ideal is generated by the single element
        `y`, and that `y (x, x) = 1 (xy, xy)`, `(x, x)` and `(xy, xy)` being
        the generators of `T` and `S`, respectively.
        r   r   )r   r   r   r   r   r   r   r   r   r   module_quotient  s   
!zSubModule.module_quotientc                 C   sD   t |tstd| |j| jkrtd| | | j|j | jS )a  
        Returns the module generated by the union of ``self`` and ``other``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(1)
        >>> M = F.submodule([x**2 + x]) # <x(x+1)>
        >>> N = F.submodule([x**2 - 1]) # <(x-1)(x+1)>
        >>> M.union(N) == F.submodule([x+1])
        True
        r   r   )r   r   r   r   r   rU   r   r!   r   r   r   union  s   
zSubModule.unionc                 C   s   t dd | jD S )aF  
        Return True if ``self`` is a zero module.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> F.submodule([x, 1]).is_zero()
        False
        >>> F.submodule([0, 0]).is_zero()
        True
        c                 s   s    | ]}|d kV  qdS )r   Nr   r.   r   r   r   r2     rl   z$SubModule.is_zero.<locals>.<genexpr>)r5   r   r1   r   r   r   r<     s   zSubModule.is_zeroc                 G   s(   |  |std|| f | || jS )a  
        Generate a submodule.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x).free_module(2).submodule([x, 1])
        >>> M.submodule([x**2, x])
        <[x**2, x]>
        z%s not a subset of %s)r6   r   rU   r   r   r   r   r   r      s   
zSubModule.submodulec                    s   t  fdd j D S )e  
        Return True if ``self`` is the entire free module.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> F.submodule([x, 1]).is_full_module()
        False
        >>> F.submodule([1, 1], [1, 2]).is_full_module()
        True
        c                 3   r-   r   r*   r.   r1   r   r   r2   @  r3   z+SubModule.is_full_module.<locals>.<genexpr>)r5   r   r   r1   r   r1   r   is_full_module1  s   zSubModule.is_full_modulec                    sR   t |tr j|jkot fdd|jD S t |ttfr' j|ko&  S dS )a  
        Returns True if ``other`` is a submodule of ``self``.

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> M = F.submodule([2, x])
        >>> N = M.submodule([2*x, x**2])
        >>> M.is_submodule(M)
        True
        >>> M.is_submodule(N)
        True
        >>> N.is_submodule(M)
        False
        c                 3   r-   r   r*   r.   r1   r   r   r2   T  r3   z)SubModule.is_submodule.<locals>.<genexpr>F)r   r   r   r5   r   r   r   r   r!   r   r1   r   r7   B  s   
zSubModule.is_submodulec                    s4   | j t| j  j fdd|  D i |S )a  
        Compute the syzygy module of the generators of ``self``.

        Suppose `M` is generated by `f_1, \ldots, f_n` over the ring
        `R`. Consider the homomorphism `\phi: R^n \to M`, given by
        sending `(r_1, \ldots, r_n) \to r_1 f_1 + \cdots + r_n f_n`.
        The syzygy module is defined to be the kernel of `\phi`.

        Examples
        ========

        The syzygy module is zero iff the generators generate freely a free
        submodule:

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(2).submodule([1, 0], [1, 1]).syzygy_module().is_zero()
        True

        A slightly more interesting example:

        >>> M = QQ.old_poly_ring(x, y).free_module(2).submodule([x, 2*x], [y, 2*y])
        >>> S = QQ.old_poly_ring(x, y).free_module(2).submodule([y, -x])
        >>> M.syzygy_module() == S
        True
        c                    s   g | ]}  |d kr|qS r   r   r.   r   r   r   rs   x      z+SubModule.syzygy_module.<locals>.<listcomp>)r   r   r   r   r   r   )r   r   r   r   r   syzygy_moduleY  s   zSubModule.syzygy_modulec                 C   s8   z|  |}W n ty   td|| f w | |S )a  
        Express element ``e`` of ``self`` in terms of the generators.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> M = F.submodule([1, 0], [1, 1])
        >>> M.in_terms_of_generators([x, x**2])  # doctest: +SKIP
        [DMP_Python([-1, 1, 0], QQ), DMP_Python([1, 0, 0], QQ)]
        z%s is not an element of %s)r   r	   r   r   r$   r   r   r   in_terms_of_generators{  s   
z SubModule.in_terms_of_generatorsc                 C   s   |S )z
        Reduce the element ``x`` of our ring modulo the ideal ``self``.

        Here "reduce" has no specific meaning, it could return a unique normal
        form, simplify the expression a bit, or just do nothing.
        r   )r   r0   r   r   r   reduce_element  s   zSubModule.reduce_elementc                 K   s6   |  |std|| f t| j| j|fi |S )aI  
        Return a quotient module.

        This is the same as taking a submodule of a quotient of the containing
        module.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> S1 = F.submodule([x, 1])
        >>> S2 = F.submodule([x**2, x])
        >>> S1.quotient_module(S2)
        <[x, 1] + <[x**2, x]>>

        Or more coincisely, using the overloaded division operator:

        >>> F.submodule([x, 1]) / [(x**2, x)]
        <[x, 1] + <[x**2, x]>>
        z%s not a submodule of %s)r7   r   SubQuotientModuler   r   r#   )r   r"   r   r   r   r   r#     s   

zSubModule.quotient_modulec                 C   s   | j | |S r   )r   r#   r   )r   othr   r   r   rX     s   zSubModule.__add__c                    s    j  fdd|jjD  S )a<  
        Multiply ``self`` by the ideal ``I``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> I = QQ.old_poly_ring(x).ideal(x**2)
        >>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, 1])
        >>> I*M
        <[x**2, x**2]>
        c                    s"   g | ]\} j D ]}|| qqS r   )r   )r/   r0   gr1   r   r   rs     s   " z,SubModule.multiply_ideal.<locals>.<listcomp>)r   _moduler   )r   Ir   r1   r   r=     s   zSubModule.multiply_idealc                 C   s   | j  | S )a  
        Return a homomorphism representing the inclusion map of ``self``.

        That is, the natural map from ``self`` to ``self.container``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).inclusion_hom()
        Matrix([
        [1, 0], : <[x, x]> -> QQ[x]**2
        [0, 1]])
        )r   rA   restrict_domainr1   r   r   r   inclusion_hom  s   zSubModule.inclusion_homc                 C   s   | j  | | S )aA  
        Return the identity homomorphism on ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).identity_hom()
        Matrix([
        [1, 0], : <[x, x]> -> <[x, x]>
        [0, 1]])
        )r   rA   r   restrict_codomainr1   r   r   r   rA     s
   
zSubModule.identity_homr   )rB   rC   rD   rE   r   r{   r   r   r   r   r   r   r   r   r   r<   r   r   r7   r   r   r   r#   rX   rb   r=   r   rA   r   r   r   r   r   ^  s4    
#("	r   c                   @   rc   )r   a  
    Submodule of a quotient module.

    Equivalently, quotient module of a submodule.

    Do not instantiate this, instead use the submodule or quotient_module
    constructing methods:

    >>> from sympy.abc import x
    >>> from sympy import QQ
    >>> F = QQ.old_poly_ring(x).free_module(2)
    >>> S = F.submodule([1, 0], [1, x])
    >>> Q = F/[(1, 0)]
    >>> S/[(1, 0)] == Q.submodule([5, x])
    True

    Attributes:

    - base - base module we are quotient of
    - killed_module - submodule used to form the quotient
    c                 K   sF   t | || | jj| _| jjjdd | jD i || j| _d S )Nc                 S   r   r   r~   r.   r   r   r   rs   	  r   z.SubQuotientModule.__init__.<locals>.<listcomp>)r   r   r   killed_modulebaser   r   r   )r   r   r   r   r   r   r   r     s   
zSubQuotientModule.__init__c                 C   s   | j |jS r   )r   r(   rI   r'   r   r   r   r     s   zSubQuotientModule._containsc                        fdd j  D S )Nc                    s   g | ]}|d t  j qS r   )r   r   )r/   Xr1   r   r   rs     r   z/SubQuotientModule._syzygies.<locals>.<listcomp>)r   r   r1   r   r1   r   r     s   zSubQuotientModule._syzygiesc                 C   s   | j |jd t| j S r   )r   r   rI   r   r   r$   r   r   r   r     s   z)SubQuotientModule._in_terms_of_generatorsc                 C   r|   )r   )r   r   r1   r   r   r   r     s   
z SubQuotientModule.is_full_modulec                 C      | j  | jS )a  
        Return the quotient homomorphism to self.

        That is, return the natural map from ``self.base`` to ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = (QQ.old_poly_ring(x).free_module(2) / [(1, x)]).submodule([1, 0])
        >>> M.quotient_hom()
        Matrix([
        [1, 0], : <[1, 0], [1, x]> -> <[1, 0] + <[1, x]>, [1, x] + <[1, x]>>
        [0, 1]])
        r   rA   quotient_codomainr   r1   r   r   r   quotient_hom0  r   zSubQuotientModule.quotient_homN)
rB   rC   rD   rE   r   r   r   r   r   r   r   r   r   r   r     s    r   c                 C   s   | d S )Nr   r   r0   r   r   r   <lambda>D  s    r   c                 C   s   | dd  S )N   r   r   r   r   r   r   E  s    c                   @   s   e Zd ZdZdd ZdS )ModuleOrderz<A product monomial order with a zeroth term as module index.c                 C   s8   |rt | |tf|tf d S t | |tf|tf d S r   )r   r   _subs1_subs0)r   o1o2TOPr   r   r   r   K  s   zModuleOrder.__init__N)rB   rC   rD   rE   r   r   r   r   r   r   H  s    r   c                   @   sl   e Zd ZdZdddZdd Zdd	d
ZdddZdd Zdd Z	dd Z
dddZdddZdddZdS )r   ax  
    Submodule of a free module over a generalized polynomial ring.

    Do not instantiate this, use the constructor method of FreeModule instead:

    >>> from sympy.abc import x, y
    >>> from sympy import QQ
    >>> F = QQ.old_poly_ring(x, y).free_module(2)
    >>> F.submodule([x, y], [1, 0])
    <[x, y], [1, 0]>

    Attributes:

    - order - monomial order used
    lexTc                 C   sN   t | || t|tstdd|  tt|| jj|| _d | _	d | _
d S )Nz)This implementation is for submodules of zFreeModulePolyRing, got %s)r   r   r   r   r   r   r   r   order_gb_gbe)r   r   r   r   r   r   r   r   r   f  s   

zSubModulePolyRing.__init__c                 C   s&   t |tr| j|jkrdS t| |S ra   )r   r   r   r   r8   r!   r   r   r   r8   o  s   zSubModulePolyRing.__eq__Fc                    s   ddl m}m}  jdu r0|r0| fdd jD | j jjdd\}}t|t| _	 _ j	du rJt| fdd jD | j jj _	|rR j	 jfS  j	S )	z%Returns a standard basis in sdm form.r   )sdm_groebnersdm_nf_moraNc                       g | ]
} j | jqS r   r   _vector_to_sdmr   r.   r1   r   r   rs   y      z/SubModulePolyRing._groebner.<locals>.<listcomp>Textendedc                    r   r   r   r.   r1   r   r   rs   ~  r   )
sympy.polys.distributedmodulesr   r   r   r   r   r   r   rg   r   )r   r   r   r   gbgber   r1   r   	_groebnert  s   

zSubModulePolyRing._groebnerc                    sN   |s fdd   D S  j dd\}} fdd|D  fdd|D fS )z)Returns a standard basis in element form.c              	      s&   g | ]}t  t j| jqS r   )rd   rg   r   _sdm_to_vectorr   r.   r1   r   r   rs     s
    z3SubModulePolyRing._groebner_vec.<locals>.<listcomp>Tr   c                    s"   g | ]}   j| jqS r   )r   r   r   r   r.   r1   r   r   rs         c                    s    g | ]} j |t jqS r   )r   r   r   r   r.   r1   r   r   rs          )r   )r   r   r   r   r   r1   r   _groebner_vec  s   

zSubModulePolyRing._groebner_vecc                 C   s:   ddl m}m} || j|| j|  | j| jj| kS )Nr   )sdm_zeror   )r   r   r   r   r   r   r   r   )r   r0   r   r   r   r   r   r     s   zSubModulePolyRing._containsc                    s   t | j}| j | jd| jd}| j | }g }t| jD ]9\}}dg |  }t|D ]
\}}	|| ||< q2t|D ]}||krI|n| | < qAt|t	|}|
| q#|j|ddd}
|
 } fdd|D }|S )z-Compute syzygies. See [SCA, algorithm 2.5.4].r   r   ilexFr   r   c                    s6   g | ]}t fd d|d  D r| d qS )c                 3   s    | ]}| kV  qd S r   r   r/   re   )zeror   r   r2     rl   z9SubModulePolyRing._syzygies.<locals>.<listcomp>.<genexpr>Nr4   r.   r   r   r   r   rs     s   6 z/SubModulePolyRing._syzygies.<locals>.<listcomp>)r   r   r   r   r   r   	enumerater   rd   rg   appendr   r   )r   koneRkrnewgensjfrP   r   vr   GG0r   r  r   r     s$   
zSubModulePolyRing._syzygiesc                    sb   j jj fj  }|jddd}| }fdd|D d   fdd dd	 D S )
z4Expression in terms of generators. See [SCA, 2.8.1].r   Fr   c                    s    g | ]} j |d  r|qS r   )r   is_unitr.   r1   r   r   rs     r   z=SubModulePolyRing._in_terms_of_generators.<locals>.<listcomp>r   c                    s   g | ]	}|  d   qS r   r   r.   )r%   r   r   rs     rt   r   N)r   r   r   r   r   r   r   )r   r%   r   Sr  r   )r%   r   r   r     s   z)SubModulePolyRing._in_terms_of_generatorsNc              	   C   sP   ddl m} |du r|}| j| j|| j|| j|  | j| jj	| j
S )z
        Reduce the element ``x`` of our container modulo ``self``.

        This applies the normal form ``NF`` to ``x``. If ``NF`` is passed
        as none, the default Mora normal form is used (which is not unique!).
        r   )r   N)r   r   r   r   r   r   r   r   r   r   r   )r   r0   NFr   r   r   r   r     s   
z SubModulePolyRing.reduce_elementc                    s   j  |j }jfddtD }tD ]}d|| |< d|| | < qfdd D }fdd|D }jd j|| |   }fdd|D }	jjfdd	|	D  }
 fd
d|	D } fdd|	D }|r~|
||fS |
S )Nc                    s   g | ]	}d gd   qS )r      r   )r/   _r   r   r   rs     rt   z0SubModulePolyRing._intersect.<locals>.<listcomp>r   c                    s   g | ]}t |d g   qS r   list)r/   r	  r  r   r   rs     r   c                    s   g | ]}d g  t | qS r   r  )r/   hr  r   r   rs     r   r  c                    s.   g | ]}t fd d|d  D r|qS )c                 3   s    | ]	}| j jkV  qd S r   r   r   r   r1   r   r   r2     rf   z:SubModulePolyRing._intersect.<locals>.<listcomp>.<genexpr>N)ry   r.   )r   r   r   r   rs     s   . c                 3   s&    | ]}d d |d  D V  qdS )c                 S      g | ]}| qS r   r   r   r   r   r   rs     r   z:SubModulePolyRing._intersect.<locals>.<genexpr>.<listcomp>Nr   r.   r  r   r   r2     s   $ z/SubModulePolyRing._intersect.<locals>.<genexpr>c                    s    g | ]}|t    qS r   r   r.   fir   r   r   rs     r   c                    s    g | ]}|t   d  qS r   r  r.   r  r   r   rs     r   )r   r   r   r   r   r   r   r   )r   r"   	relationshicir  dieisyznonzeroresreln1reln2r   )r  r   r   r   r     s"   "
zSubModulePolyRing._intersectc                    s  |rt |jdkrtt |jdkrjdS t |jdkr~t|jd dg }dd jD }jjd j|g| ddd}|sUjjfdd|	 D  S |j	d	d
\ fddt
 D }jj fdd|D  fdd|D fS tdd fdd|jD S )Nr   r   c                 S   s   g | ]	}t |d g qS r   r  r.   r   r   r   rs     rt   z6SubModulePolyRing._module_quotient.<locals>.<listcomp>r   Fr   c                    s2   g | ]}t  fd d|dd D r|d qS )c                 3       | ]	}| j jkV  qd S r   r  r   r1   r   r   r2     rf   @SubModulePolyRing._module_quotient.<locals>.<listcomp>.<genexpr>NrY   r4   r.   r1   r   r   rs     s    Tr   c                    s2   g | ]\}}t  fd d|dd D r|qS )c                 3   r%  r   r  r   r1   r   r   r2     rf   r&  NrY   r4   )r/   r   r0   r1   r   r   rs     s    
c                    s   g | ]} | d  qS )rY   r   r   )r  r   r   rs         c                    s&   g | ]}d d  | dd D qS )c                 S   r  r   r   r.   r   r   r   rs     r   zASubModulePolyRing._module_quotient.<locals>.<listcomp>.<listcomp>r   Nr   r   )Rr   r   rs     s   & c                 S   r)   r   )r   )r0   re   r   r   r   r     s   
 z4SubModulePolyRing._module_quotient.<locals>.<lambda>c                 3   s"    | ]}   j|V  qd S r   )r   r   r   r.   r1   r   r   r2     r   z5SubModulePolyRing._module_quotient.<locals>.<genexpr>)r   r   r   r   r>   r  r   r   r   r   r  r   )r   r"   r  g1gir   indicesr   )r  r(  r   r   r     s(   z"SubModulePolyRing._module_quotient)r   T)Fr   )rB   rC   rD   rE   r   r8   r   r   r   r   r   r   r   r   r   r   r   r   r   R  s    
	

!

r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   a  
    Class for submodules of free modules over quotient rings.

    Do not instantiate this. Instead use the submodule methods.

    >>> from sympy.abc import x, y
    >>> from sympy import QQ
    >>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y])
    >>> M
    <[x + <x**2 - y**2>, x + y + <x**2 - y**2>]>
    >>> M.contains([y**2, x**2 + x*y])
    True
    >>> M.contains([x, y])
    False

    Attributes:

    - quot - the subquotient of `R^n/IR^n` generated by lifts of our generators
    c                    s2   t  ||  jjj fdd jD   _d S )Nc                    s   g | ]} j |qS r   )r   r   r.   r1   r   r   rs     r'  z2SubModuleQuotientRing.__init__.<locals>.<listcomp>)r   r   r   r   r   r   r   r   r1   r   r     s   
zSubModuleQuotientRing.__init__c                 C   s   | j | j|S r   )r   r   r   r   r'   r   r   r   r      r9   zSubModuleQuotientRing._containsc                    r   )Nc                    s"   g | ]}t  fd d|D qS )c                 3   s"    | ]} j | jj V  qd S r   r   r   r   r   r1   r   r   r2   $  r   z=SubModuleQuotientRing._syzygies.<locals>.<listcomp>.<genexpr>rm   r.   r1   r   r   rs   $  r   z3SubModuleQuotientRing._syzygies.<locals>.<listcomp>)r   r   r1   r   r1   r   r   #  s   
zSubModuleQuotientRing._syzygiesc                    s"    fdd j  j|D S )Nc                    s   g | ]} j | jj qS r   r,  r.   r1   r   r   rs   (  r   zASubModuleQuotientRing._in_terms_of_generators.<locals>.<listcomp>)r   r   r   r   r'   r   r1   r   r   '  s   
z-SubModuleQuotientRing._in_terms_of_generatorsN)rB   rC   rD   rE   r   r   r   r   r   r   r   r   r     s    r   c                   @   r   )QuotientModuleElementzElement of a quotient module.c                 C   s   | j j|| S )zEquality comparison.)rH   r   r(   rJ   r   r   r   rT   3  s   zQuotientModuleElement.eqc                 C   s   t | jd t | jj S )Nz + )r   rI   rH   r   r1   r   r   r   r{   7  s   zQuotientModuleElement.__repr__N)rB   rC   rD   rE   rT   r{   r   r   r   r   r-  0  s    r-  c                   @   sV   e Zd ZdZeZdd Zdd Zdd Zdd	 Z	d
d Z
dddZdd Zdd ZdS )r   a  
    Class for quotient modules.

    Do not instantiate this directly. For subquotients, see the
    SubQuotientModule class.

    Attributes:

    - base - the base module we are a quotient of
    - killed_module - the submodule used to form the quotient
    - rank of the base
    c                 C   s>   t | | ||std||f || _|| _|j| _d S )Nz%s is not a submodule of %s)r   r   r7   r   r   r   r   )r   r   r   r   r   r   r   r   K  s   
zQuotientModule.__init__c                 C   r   )N/)r   r   r   r1   r   r   r   r{   S  ri   zQuotientModule.__repr__c                 C   s   | j | jkS )a  
        Return True if ``self`` is a zero module.

        This happens if and only if the base module is the same as the
        submodule being killed.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2)
        >>> (F/[(1, 0)]).is_zero()
        False
        >>> (F/[(1, 0), (0, 1)]).is_zero()
        True
        )r   r   r1   r   r   r   r<   V  s   zQuotientModule.is_zeroc                 C   s<   t |tr| j|jko| j|jS t |tr|j| kS dS )ah  
        Return True if ``other`` is a submodule of ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)]
        >>> S = Q.submodule([1, 0])
        >>> Q.is_submodule(S)
        True
        >>> S.is_submodule(Q)
        False
        F)r   r   r   r   r7   r   r   r!   r   r   r   r7   j  s   


zQuotientModule.is_submodulec                 O   r   )ad  
        Generate a submodule.

        This is the same as taking a quotient of a submodule of the base
        module.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)]
        >>> Q.submodule([x, 0])
        <[x, 0] + <[x, x]>>
        )r   r   r   r   r   r     s   zQuotientModule.submoduleNc                 C   sR   t |tr |j| u r|S | j|jjrt| | j|jS tt| | j|S )a  
        Convert ``elem`` into the internal representation.

        This method is called implicitly whenever computations involve elements
        not in the internal representation.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> F = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
        >>> F.convert([1, 0])
        [1, 0] + <[1, 2], [1, x]>
        )	r   r-  rH   r   r7   r   r   rI   r	   r   r   r   r   r     s   

zQuotientModule.convertc                 C   s   | j  | j| jS )av  
        Return the identity homomorphism on ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
        >>> M.identity_hom()
        Matrix([
        [1, 0], : QQ[x]**2/<[1, 2], [1, x]> -> QQ[x]**2/<[1, 2], [1, x]>
        [0, 1]])
        )r   rA   r   r   quotient_domainr1   r   r   r   rA     s
   
zQuotientModule.identity_homc                 C   r   )a  
        Return the quotient homomorphism to ``self``.

        That is, return a homomorphism representing the natural map from
        ``self.base`` to ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)]
        >>> M.quotient_hom()
        Matrix([
        [1, 0], : QQ[x]**2 -> QQ[x]**2/<[1, 2], [1, x]>
        [0, 1]])
        r   r1   r   r   r   r     s   
zQuotientModule.quotient_homr   )rB   rC   rD   rE   r-  r   r   r{   r<   r7   r   r   rA   r   r   r   r   r   r   ;  s    
r   N)"rE   r   	functoolsr   sympy.polys.agca.idealsr   sympy.polys.domains.fieldr   sympy.polys.orderingsr   r   sympy.polys.polyclassesr   sympy.polys.polyerrorsr	   sympy.core.basicr
   sympy.utilities.iterablesr   r   rG   rd   r   r   r   r   r   r   r   r   r   r   r-  r   r   r   r   r   <module>   s<    td )2f   W
 5*