
    \hU                         S r SSKJrJrJrJrJr  SSKJr   " S S5      r	 " S S\	5      r
 " S S	\
5      r " S
 S\
5      rS rg)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                       \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS r\rS rS rS rS rS rS rS r S r!S r"S r#g!)"ModuleHomomorphism   a  
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                 @   [        U[        5      (       d  [        SU-  5      e[        U[        5      (       d  [        SU-  5      eUR                  UR                  :w  a  [	        SU< SU< 35      eXl        X l        UR                  U l        S U l        S U l        g )NzSource must be a module, got %szTarget must be a module, got %sz0Source and codomain must be over same ring, got z != )	
isinstancer   	TypeErrorring
ValueErrordomaincodomain_ker_img)selfr   r   s      V/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/agca/homomorphisms.py__init__ModuleHomomorphism.__init__8   s    &&))=FGG(F++=HII;;(--'/5xA B B KK			    c                 ^    U R                   c  U R                  5       U l         U R                   $ )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]>
)r   _kernelr   s    r   kernelModuleHomomorphism.kernelF   s%    $ 99DIyyr   c                 ^    U R                   c  U R                  5       U l         U 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
)r   _imager   s    r   imageModuleHomomorphism.image\   s%    $ 99DIyyr   c                     [         e)zCompute the kernel of ``self``.NotImplementedErrorr   s    r   r   ModuleHomomorphism._kernelr       !!r   c                     [         e)zCompute the image of ``self``.r$   r   s    r   r    ModuleHomomorphism._imagev   r'   r   c                     [         ez%Implementation of domain restriction.r$   r   sms     r   _restrict_domain#ModuleHomomorphism._restrict_domainz   r'   r   c                     [         ez'Implementation of codomain restriction.r$   r,   s     r   _restrict_codomain%ModuleHomomorphism._restrict_codomain~   r'   r   c                     [         ez"Implementation of domain quotient.r$   r,   s     r   _quotient_domain#ModuleHomomorphism._quotient_domain   r'   r   c                     [         ez$Implementation of codomain quotient.r$   r,   s     r   _quotient_codomain%ModuleHomomorphism._quotient_codomain   r'   r   c                     U R                   R                  U5      (       d  [        SU R                   < SU< 35      eXR                   :X  a  U $ U R                  U5      $ )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 , got )r   is_submoduler   r.   r,   s     r   restrict_domain"ModuleHomomorphism.restrict_domain   sU    @ {{''++ $R1 2 2K$$R((r   c                     UR                  U R                  5       5      (       d!  [        SU R                  5       < SU< 35      eXR                  :X  a  U $ U R	                  U5      $ )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  must contain sm, got )r>   r!   r   r   r2   r,   s     r   restrict_codomain$ModuleHomomorphism.restrict_codomain   sV    2 tzz|,, $

b2 3 3K&&r**r   c                     U R                  5       R                  U5      (       d!  [        SU R                  5       < SU< 35      eUR                  5       (       a  U $ U R	                  U5      $ )a  
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 rB   )r   r>   r   is_zeror6   r,   s     r   quotient_domain"ModuleHomomorphism.quotient_domain   sY    0 {{}))"--"kkmR1 2 2::<<K$$R((r   c                     U R                   R                  U5      (       d  [        SU R                   < SU< 35      eUR                  5       (       a  U $ U R	                  U5      $ )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 r=   )r   r>   r   rF   r:   r,   s     r   quotient_codomain$ModuleHomomorphism.quotient_codomain   sU    > }}))"-- $r3 4 4::<<K&&r**r   c                     [         e)zApply ``self`` to ``elem``.r$   r   elems     r   _applyModuleHomomorphism._apply  r'   r   c                     U R                   R                  U R                  U R                  R                  U5      5      5      $ N)r   convertrO   r   rM   s     r   __call__ModuleHomomorphism.__call__  s/    }}$$T[[1D1DT1J%KLLr   c                     [         e)z
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   oths     r   _composeModuleHomomorphism._compose  s
     "!r   c                     [         e)z8Scalar multiplication. ``c`` is guaranteed in self.ring.r$   )r   cs     r   _mul_scalarModuleHomomorphism._mul_scalar'  r'   r   c                     [         e)z^
Homomorphism addition.
``oth`` is guaranteed to be a homomorphism with same domain/codomain.
r$   rW   s     r   _addModuleHomomorphism._add+  s
    
 "!r   c                     [        U[        5      (       d  gUR                  U R                  :H  =(       a    UR                  U R                  :H  $ )zEHelper to check that oth is a homomorphism with same domain/codomain.F)r   r
   r   r   rW   s     r   
_check_homModuleHomomorphism._check_hom2  s8    #122zzT[[(JS\\T]]-JJr   c                    [        U[        5      (       a+  U R                  UR                  :X  a  UR	                  U 5      $  U R                  U R                  R                  U5      5      $ ! [         a	    [        s $ f = frR   )
r   r
   r   r   rY   r]   r   rS   r   NotImplementedrW   s     r   __mul__ModuleHomomorphism.__mul__8  sh    c-..4;;#,,3N<<%%	"##DII$5$5c$:;; 	"!!	"s   )A, ,A?>A?c                      U R                  SU R                  R                  U5      -  5      $ ! [         a	    [        s $ f = f)N   )r]   r   rS   r   rf   rW   s     r   __truediv__ModuleHomomorphism.__truediv__C  sA    	"##Adii&7&7&<$<== 	"!!	"s   ,/ AAc                 \    U R                  U5      (       a  U R                  U5      $ [        $ rR   )rc   r`   rf   rW   s     r   __add__ModuleHomomorphism.__add__I  s%    ??399S>!r   c                     U R                  U5      (       a9  U R                  UR                  U R                  R	                  S5      5      5      $ [
        $ )N)rc   r`   r]   r   rS   rf   rW   s     r   __sub__ModuleHomomorphism.__sub__N  s>    ??399S__TYY->->r-BCDDr   c                 >    U R                  5       R                  5       $ )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   rF   r   s    r   is_injectiveModuleHomomorphism.is_injectiveS  s    * {{}$$&&r   c                 <    U R                  5       U R                  :H  $ )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   s    r   is_surjective ModuleHomomorphism.is_surjectivej  s    * zz|t}},,r   c                 P    U R                  5       =(       a    U R                  5       $ )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
)ru   rx   r   s    r   is_isomorphism!ModuleHomomorphism.is_isomorphism  s!    ,   ";t'9'9';;r   c                 >    U R                  5       R                  5       $ )a  
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!   rF   r   s    r   rF   ModuleHomomorphism.is_zero  s    . zz|##%%r   c                 H     X-
  R                  5       $ ! [         a     gf = f)NF)rF   r   rW   s     r   __eq__ModuleHomomorphism.__eq__  s*    	J'')) 		s    
!!c                     X:X  + $ rR    rW   s     r   __ne__ModuleHomomorphism.__ne__  s      r   )r   r   r   r   r   N)$__name__
__module____qualname____firstlineno____doc__r   r   r!   r   r    r.   r2   r6   r:   r?   rC   rG   rJ   rO   rT   rY   r]   r`   rc   rg   __rmul__rk   rn   rr   ru   rx   r{   rF   r   r   __static_attributes__r   r   r   r
   r
      s    #J,,""""""%)N+@)>$+L"M"""K" H"

'.-.<0&2!r   r
   c                   T    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rSrg)MatrixHomomorphismi  a  
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                   ^ [         R                  XU5        [        U5      UR                  :w  a&  [	        SUR                  < S[        U5      < 35      eU R
                  R                  m[        U R
                  [        [        45      (       a   U R
                  R                  R                  m[        U4S jU 5       5      U l        g )NzNeed to provide z elements, got c              3   4   >#    U  H  nT" U5      v   M     g 7frR   r   ).0x	converters     r   	<genexpr>.MatrixHomomorphism.__init__.<locals>.<genexpr>  s     9&QIaLL&s   )r
   r   lenrankr   r   rS   r   r   r   	containertuplematrix)r   r   r   r   r   s       @r   r   MatrixHomomorphism.__init__  s    ##D(;v;&++% &S[: ; ; MM))	dmmi1B%CDD//77I9&99r   c                 4   SSK Jn  S n[        U R                  [        [
        45      (       a  S nU" U R                   VVs/ s H3  o2" U5       Vs/ s H  o@R                  R                  U5      PM     snPM5     snn5      R                  $ s  snf s  snnf )z=Helper function which returns a SymPy matrix ``self.matrix``.r   )Matrixc                     U $ rR   r   r   s    r   <lambda>2MatrixHomomorphism._sympy_matrix.<locals>.<lambda>  s    ar   c                     U R                   $ rR   )datar   s    r   r   r     s    !&&r   )
sympy.matricesr   r   r   r   r   r   r   to_sympyT)r   r   r\   r   ys        r   _sympy_matrix MatrixHomomorphism._sympy_matrix  sp    )dmmn6G%HII AdkkRkqt<t!		**1-t<kRSUUU<Rs   B
$B6B
B
c                    [        U R                  5       5      R                  S5      nSU R                  < SU R                  < 3nS[        U5      -  n[        U5      n[        US-  5       H  nX==   U-  ss'   M     XS-  ==   U-  ss'   [        US-  S-   U5       H  nX==   U-  ss'   M     SR                  U5      $ )N
z : z ->     rj   )reprr   splitr   r   r   rangejoin)r   linestsnis         r   __repr__MatrixHomomorphism.__repr__  s    T'')*006![[$--8AJJqAvAHMH 1fq!tax#AHMH $yyr   c                 B    [        XR                  U R                  5      $ r+   )SubModuleHomomorphismr   r   r,   s     r   r.   #MatrixHomomorphism._restrict_domain  s    $RDDr   c                 N    U R                  U R                  XR                  5      $ r1   )	__class__r   r   r,   s     r   r2   %MatrixHomomorphism._restrict_codomain  s    ~~dkk2{{;;r   c                 j    U R                  U R                  U-  U R                  U R                  5      $ r5   r   r   r   r   r,   s     r   r6   #MatrixHomomorphism._quotient_domain  s%    ~~dkk"ndmmT[[IIr   c           
      @   U R                   U-  nUR                  n[        U R                   [        5      (       a  UR                  R                  nU R                  U R                  U R                   U-  U R                   Vs/ s H
  oC" U5      PM     sn5      $ s  snf r9   )r   rS   r   r   r   r   r   r   )r   r-   Qr   r   s        r   r:   %MatrixHomomorphism._quotient_codomain  sx    MM"II	dmmY//++I~~dkk4==+;#';;/;aYq\;/1 	1/s   Bc           
          U R                  U R                  U R                  [        U R                  UR                  5       VVs/ s H	  u  p#X#-   PM     snn5      $ s  snnf rR   )r   r   r   zipr   )r   rX   r   r   s       r   r`   MatrixHomomorphism._add  sK    ~~dkk4==14T[[#**1MN1Mqu1MNP 	PNs   Ac           	          U R                  U R                  U R                  U R                   Vs/ s H  o!U-  PM	     sn5      $ s  snf rR   r   )r   r\   r   s      r   r]   MatrixHomomorphism._mul_scalar  s5    ~~dkk4==:T1Q3:TUU:Ts   Ac           
          U R                  U R                  UR                  U R                   Vs/ s H
  o!" U5      PM     sn5      $ s  snf rR   r   )r   rX   r   s      r   rY   MatrixHomomorphism._compose  s7    ~~dkk3<<$++9V+Q#a&+9VWW9Vs   A)r   N)r   r   r   r   r   r   r   r   r.   r2   r6   r:   r`   r]   rY   r   r   r   r   r   r     s?    :	:V
 E<J1PVXr   r   c                   *    \ rS rSrSrS rS rS rSrg)FreeModuleHomomorphismi  a  
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                     [        U R                  [        5      (       a  UR                  n[	        S [        XR                  5       5       5      $ )Nc              3   .   #    U  H  u  pX-  v   M     g 7frR   r   r   r   es      r   r   0FreeModuleHomomorphism._apply.<locals>.<genexpr>/       <%;TQ15%;   )r   r   r   r   sumr   r   rM   s     r   rO   FreeModuleHomomorphism._apply,  s6    dkk>2299D<S{{%;<<<r   c                 H    U R                   R                  " U R                  6 $ rR   )r   	submoduler   r   s    r   r    FreeModuleHomomorphism._image1  s    }}&&44r   c                     U R                  5       R                  5       nU R                  R                  " UR                  6 $ rR   )r!   syzygy_moduler   r   gens)r   syzs     r   r   FreeModuleHomomorphism._kernel4  s1     jjl((*{{$$chh//r   r   N	r   r   r   r   r   rO   r    r   r   r   r   r   r   r     s    $=
50r   r   c                   *    \ rS rSrSrS rS rS rSrg)r   i>  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                     [        U R                  [        5      (       a  UR                  n[	        S [        XR                  5       5       5      $ )Nc              3   .   #    U  H  u  pX-  v   M     g 7frR   r   r   s      r   r   /SubModuleHomomorphism._apply.<locals>.<genexpr>T  r   r   )r   r   r   r   r   r   r   rM   s     r   rO   SubModuleHomomorphism._applyQ  s7    dkk#45599D<S{{%;<<<r   c                     U R                   R                  " U R                  R                   Vs/ s H
  o" U5      PM     sn6 $ s  snf rR   )r   r   r   r   )r   r   s     r   r    SubModuleHomomorphism._imageV  s9    }}&&$++:J:J(K:JQa:J(KLL(Ks   Ac                 
   U R                  5       R                  5       nU R                  R                  " UR                   Vs/ s H2  n[        S [        X R                  R                  5       5       5      PM4     sn6 $ s  snf )Nc              3   .   #    U  H  u  pX-  v   M     g 7frR   r   )r   xigis      r   r   0SubModuleHomomorphism._kernel.<locals>.<genexpr>\  s     ?&>FB"%&>r   )r!   r   r   r   r   r   r   )r   r   r   s      r   r   SubModuleHomomorphism._kernelY  sk    jjl((*{{$$xx!! ?c![[-=-=&>??!" 	"!s   9B r   Nr   r   r   r   r   r   >  s    $=
M"r   r   c           
          S nU" U 5      u  pEpgU" U5      u  pp[        XHU Vs/ s H
  o" U5      PM     sn5      R                  U5      R                  U	5      R                  U
5      R	                  U5      $ s  snf )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                   ^  [        T [        5      (       a  T T T R                  5       U 4S j4$ [        T [        5      (       a(  T R                  T R                  T R
                  U 4S j4$ [        T [        5      (       a2  T R                  R                  T R                  T R
                  U 4S j4$ T R                  T T R                  5       U 4S j4$ )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                 &   > TR                  U 5      $ rR   )rS   r   modules    r   r   0homomorphism.<locals>.freepres.<locals>.<lambda>  s    PQARr   c                 :   > TR                  U 5      R                  $ rR   )rS   r   r   s    r   r   r     s    fnnQ/44r   c                 N   > TR                   R                  U 5      R                  $ rR   )r   rS   r   r   s    r   r   r     s    f..66q9>>r   c                 :   > TR                   R                  U 5      $ rR   )r   rS   r   s    r   r   r     s    &**2215r   )r   r   r   r   basekilled_moduler   r   )r   s   `r   freepreshomomorphism.<locals>.freepres  s     fj))66#3#3#57RRRfn--KKf.B.B46 6f/00KK))6;;8L8L>@ @   &&*:*:*<57 	7r   )r   r?   rC   rJ   rG   )r   r   r   r   SFSSSQ_TFTSTQr\   r   s                r   homomorphismr  `  sx    x7$ V$MBBX&MBB!"*@A1Q4*@ ?200  R !45*@s   A8N)r   sympy.polys.agca.modulesr   r   r   r   r   sympy.polys.polyerrorsr   r
   r   r   r   r  r   r   r   <module>r     sX   " " 1g! g!TZX+ ZXz"0/ "0J". "DS5r   