# Subquotients

A subquotient is a submodule of a quotient of a free module. In this section, the expression *subquotient* refers to a subquotient over a ring of type `MPolyRing`

, `MPolyQuoRing`

, `MPolyLocRing`

, or `MPolyQuoLocRing`

. That is, given a ring $R$ of one of these types, a subquotient $M$ over $R$ is a module of type

\[M = (\text{im } a + \text{im } b)/\text{im } b,\]

where

\[a:R^s ⟶R^p \;\text{ and }\; b:R^t ⟶R^p\]

are two homomorphisms of free $R$-modules with the same codomain. We then refer to

- the module $M$ as the
*subquotient defined by $a$ and $b$*, - the codomain $R^p$ as the
*ambient free module*of $M$, - the images of the canonical basis vectors of $R^s$ in $R^p$ as the
*ambient representatives of the generators*of $M$, and - the images of the canonical basis vectors of $R^t$ in $R^p$ as the
*relations*of $M$.

Alternatively, we speak of the *subquotient of* $\;\text{im } a\;$ *by* $\;\text{im } b\;$ or the *subquotient defined by $A$ and $B$*, where $A$ and $B$ are the matrices representing $a$ and $b$, respectively.

Finally, we refer to

- the quotient of $R^p$ by the submodule generated by the relations of $M$ as the
*ambient module of $M$*,

and regard $M$ as a submodule of that ambient module, embedded in the natural way.

Recall from the section on free modules that by a free $R$-module we mean a free module of type $R^p$ , where we think of $R^p$ as a free module with a given basis, namely the basis of standard unit vectors. Accordingly, elements of free modules are represented by coordinate vectors, and homomorphisms between free modules by matrices. Here, by convention, vectors are row vectors, and matrices operate by multiplication on the right.

## Types

All OSCAR types for the finitely presented modules considered here belong to the abstract type `ModuleFP{T}`

, where `T`

is the element type of the underlying ring. The subquotients belong to the abstract subtype `AbstractSubQuo{T} <: ModuleFP{T}`

, they are modelled as objects of the concrete type `SubquoModule{T} <: AbstractSubQuo{T}`

.

Canonical maps such us the canonical projection onto a quotient module arise in many constructions in commutative algebra. The `SubquoModule`

type is designed so that it allows for the caching of such maps when executing functions. The `tensor_product`

function discussed in this section provides an example.

## Constructors

`subquotient`

— Method`subquotient(a::FreeModuleHom, b::FreeModuleHom)`

Given homomorphisms `a`

and `b`

between free modules such that `codomain(a) === codomain(b)`

, return $(\text{im } a + \text{im } b)/\text{im } b$.

`subquotient(F::FreeMod{T}, A::MatElem{T}, B::MatElem{T}) where T`

Given matrices `A`

and `B`

with rank `F`

columns, return $(\text{im } a + \text{im } b)/\text{im } b$, where `a`

and `b`

are free module homomorphisms with codomain `F`

represented by `A`

and `B`

.

`subquotient(A::MatElem{T}, B::MatElem{T}) where T`

Given matrices `A`

and `B`

with the same number of columns, create a free module `F`

whose rank is that number, and return $(\text{im } a + \text{im } b)/\text{im } b$, where `a`

and `b`

are free module homomorphisms with codomain `F`

represented by `A`

and `B`

.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
julia> FR = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AR = R[x; y]
[x]
[y]
julia> BR = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> MR = SubquoModule(FR, AR, BR)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> P = ideal(R, [x, y, z]);
julia> U = complement_of_prime_ideal(P);
julia> RL, _ = Localization(R, U);
julia> FRL = free_module(RL, 1)
Free module of rank 1 over localization of Multivariate Polynomial Ring in x, y, z over Rational Field at the complement of ideal(x, y, z)
julia> ARL = RL[x; y]
[x]
[y]
julia> BRL = RL[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> MRL = SubquoModule(FRL, ARL, BRL)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> RQ, _ = quo(R, ideal(R, [2*x^2-y^3, 2*x^2-y^5]));
julia> FRQ = free_module(RQ, 1)
Free module of rank 1 over Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(2*x^2 - y^3, 2*x^2 - y^5)
julia> ARQ = RQ[x; y]
[x]
[y]
julia> BRQ = RQ[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> MRQ = SubquoModule(FRQ, ARQ, BRQ)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> 2*x^2*e[1]
3 -> z^4*e[1]
julia> RQL, _ = Localization(RQ, U);
julia> FRQL = free_module(RQL, 1)
Free module of rank 1 over Localization of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(2*x^2 - y^3, 2*x^2 - y^5) at the multiplicative set complement of ideal(x, y, z)
julia> ARQL = RQL[x; y]
[x]
[y]
julia> BRQL = RQL[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> MRQL = SubquoModule(FRQL, ARQL, BRQL)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> 0
2 -> 0
3 -> z^4*e[1]
```

## Data Associated to Subqotients

If `M`

is a subquotient with ambient free `R`

-module `F`

, then

`base_ring(M)`

refers to`R`

,`ambient_free_module(M)`

to`F`

,`gens(M)`

to the generators of`M`

,`ngens(M)`

to the number of these generators,`M[i]`

,`gen(M, i)`

to the`i`

th such generator,`ambient_representatives_generators(M)`

to the ambient representatives of the generators of`M`

in`F`

,`relations(M)`

to the relations of`M`

, and`ambient_module(M)`

to the ambient module of`M`

.

##### Examples

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> base_ring(M)
Multivariate Polynomial Ring in x, y, z over Rational Field
julia> F === ambient_free_module(M)
true
julia> gens(M)
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
x*e[1]
y*e[1]
julia> ngens(M)
2
julia> gen(M, 2)
y*e[1]
julia> ambient_representatives_generators(M)
2-element Vector{FreeModElem{QQMPolyRingElem}}:
x*e[1]
y*e[1]
julia> relations(M)
3-element Vector{FreeModElem{QQMPolyRingElem}}:
x^2*e[1]
y^3*e[1]
z^4*e[1]
julia> ambient_module(M)
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
```

## Elements of Subqotients

All OSCAR types for elements of finitely presented modules considered here belong to the abstract type `ModuleElemFP{T}`

, where `T`

is the element type of the polynomial ring. For elements of subquotients, there are the abstract subtype `AbstractSubQuoElem{T} <: ModuleFPElem{T}`

and its concrete descendant `SubquoModuleElem{T}`

which implements an element $m$ of a subquotient $M$ over a ring $R$ as a sparse row, that is, as an object of type `SRow{T}`

. This object specifies the coefficients of an $R$-linear combination of the generators of $M$ giving $m$. To create an element, enter the coefficients as a sparse row or a vector:

`(M::SubquoModule{T})(c::SRow{T}) where T`

`(M::SubquoModule{T})(c::Vector{T}) where T`

Alternatively, directly write the element as an $R$-linear combination of generators of $M$.

##### Examples

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> m = M(sparse_row(R, [(1,z),(2,one(R))]))
(x*z + y)*e[1]
julia> n = M([z, one(R)])
(x*z + y)*e[1]
julia> o = z*M[1] + M[2]
(x*z + y)*e[1]
julia> m == n == o
true
```

Given an element `m`

of a subquotient `M`

over a ring $R$ with element type `T`

,

`parent(m)`

refers to`M`

,`coordinates(m)`

to an object of type`SRow{T}`

specifying the coefficients of an $R$-linear combination of the generators of $M$ which gives $m$, and`ambient_representative(m)`

to an element of the ambient free module of`M`

which represents`m`

.

Given an element `f`

of the ambient free module of a subquotient `M`

such that `f`

represents an element of `M`

, the function below creates the represented element:

`(M::SubquoModule{T})(f::FreeModElem{T}; check::Bool = true) where T`

By default (`check = true`

), it is tested whether `f`

indeed represents an element of `M`

. If this is already clear, it may be convenient to omit the test (`check = false`

).

##### Examples

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> m = z*M[1] + M[2]
(x*z + y)*e[1]
julia> parent(m)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> coordinates(m)
Sparse row with positions [1, 2] and values QQMPolyRingElem[z, 1]
julia> fm = ambient_representative(m)
(x*z + y)*e[1]
julia> typeof(m)
SubquoModuleElem{QQMPolyRingElem}
julia> typeof(fm)
FreeModElem{QQMPolyRingElem}
julia> parent(fm) === ambient_free_module(M)
true
julia> F = ambient_free_module(M)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> f = x*F[1]
x*e[1]
julia> M(f)
x*e[1]
julia> typeof(f)
FreeModElem{QQMPolyRingElem}
julia> typeof(M(f))
SubquoModuleElem{QQMPolyRingElem}
```

The zero element of a subquotient is obtained as follows:

`zero`

— Method`zero(M::SubquoModule)`

Return the zero element of `M`

.

Whether a given element of a subquotient is zero can be tested as follows:

`is_zero`

— Method`is_zero(m::SubquoModuleElem)`

Return `true`

if `m`

is zero, `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> is_zero(M[1])
false
julia> is_zero(x*M[1])
true
```

## Tests on Subqotients

`==`

— Method`==(M::SubquoModule{T}, N::SubquoModule{T}) where {T}`

Given subquotients `M`

and `N`

such that `ambient_module(M) == ambient_module(N)`

, return `true`

if `M`

equals `N`

, where `M`

and `N`

are regarded as submodules of the common ambient module.

Here, `ambient_module(M) == ambient_module(N)`

if

`ambient_free_module(M) === ambient_free_module(N)`

, and- the submodules of the common ambient free module generated by the relations of
`M`

and`N`

, respectively, are equal.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AM = R[x;]
[x]
julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> AN = R[x; y]
[x]
[y]
julia> BN = R[x^2+y^4; y^3; z^4]
[x^2 + y^4]
[ y^3]
[ z^4]
julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> (x^2 + y^4)*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> M == N
false
```

`is_subset`

— Method`is_subset(M::SubquoModule{T}, N::SubquoModule{T}) where T`

Given subquotients `M`

and `N`

such that `ambient_module(M) == ambient_module(N)`

, return `true`

if `M`

is contained in `N`

, where `M`

and `N`

are regarded as submodules of the common ambient module.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AM = R[x;]
[x]
julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> AN = R[x; y]
[x]
[y]
julia> BN = R[x^2+y^4; y^3; z^4]
[x^2 + y^4]
[ y^3]
[ z^4]
julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> (x^2 + y^4)*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> is_subset(M, N)
true
```

`is_zero`

— Method`is_zero(M::SubquoModule)`

Return `true`

if `M`

is the zero module, `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x^2+y^2;]
[x^2 + y^2]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 1 generator
1 -> (x^2 + y^2)*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> is_zero(M)
false
```

## Basic Operations on Subquotients

`+`

— Method`+(M::SubquoModule{T},N::SubquoModule{T}) where T`

Given subquotients `M`

and `N`

such that `ambient_module(M) == ambient_module(N)`

, return the sum of `M`

and `N`

regarded as submodules of the common ambient module.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AM = R[x;]
[x]
julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> AN = R[y;]
[y]
julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> O = M + N
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
```

`sum`

— Method`sum(M::SubquoModule{T},N::SubquoModule{T}) where T`

Given subquotients `M`

and `N`

such that `ambient_module(M) == ambient_module(N)`

, return the sum of `M`

and `N`

regarded as submodules of the common ambient module.

Additionally, return the inclusion maps `M`

$\to$ `M + N`

and `N`

$\to$ `M + N`

.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AM = R[x;]
[x]
julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> AN = R[y;]
[y]
julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> O = sum(M, N);
julia> O[1]
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> O[2]
Map with following data
Domain:
=======
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> O[3]
Map with following data
Domain:
=======
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
```

`intersect`

— Method`intersect(M::SubquoModule{T}, N::SubquoModule{T}) where T`

Given subquotients `M`

and `N`

such that `ambient_module(M) == ambient_module(N)`

, return the intersection of `M`

and `N`

regarded as submodules of the common ambient module.

Additionally, return the inclusion maps `M`

$\cap$ `N`

$\to$ `M`

and `M`

$\cap$ `N`

$\to$ `N`

.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> AM = R[x;]
[x]
julia> BM = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, AM, BM)
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> AN = R[y;]
[y]
julia> BN = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> N = SubquoModule(F, AN, BN)
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> intersect(M, N)
(Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> x*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1], Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> -x*y*e[1]
2 -> x*z^4*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1])
```

## Submodules and Quotients

`sub`

— Method`sub(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T`

Given a vector `V`

of elements of `M`

, return the submodule of `M`

generated by these elements.

Put more precisely, return this submodule as an object of type `SubquoModule`

.

Additionally, if `N`

denotes this object,

- return the inclusion map
`N`

$\to$`M`

if`task = :with_morphism`

(default), - return and cache the inclusion map
`N`

$\to$`M`

if`task = :cache_morphism`

, - do none of the above if
`task = :none`

.

If `task = :only_morphism`

, return only the inclusion map.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
julia> F = free_module(R, 1);
julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];
julia> N, incl = sub(F, V);
julia> N
Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
represented as subquotient with no relations.
julia> incl
Map with following data
Domain:
=======
Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
represented as subquotient with no relations.
Codomain:
=========
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
```

`quo`

— Method`quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, task::Symbol = :with_morphism) where T`

Given a vector `V`

of elements of `M`

, return the quotient of `M`

by the submodule of `M`

which is generated by these elements.

Put more precisely, return the quotient as an object of type `SubquoModule`

.

Additionally, if `N`

denotes this object,

- return the projection map
`M`

$\to$`N`

if`task = :with_morphism`

(default), - return and cache the projection map
`M`

$\to$`N`

if`task = :cache_morphism`

, - do none of the above if
`task = :none`

or`task = :module`

.

If `task = :only_morphism`

, return only the projection map.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]);
julia> F = free_module(R, 1);
julia> V = [x^2*F[1]; y^3*F[1]; z^4*F[1]];
julia> N, proj = quo(F, V);
julia> N
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> proj
Map with following data
Domain:
=======
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
```

## Homomorphisms From Subqotients

All OSCAR types for homomorphisms of finitely presented modules considered here belong to the abstract type `ModuleFPHom{T1, T2}`

, where `T1`

and `T2`

are the types of domain and codomain respectively. For homomorphisms from subquotients, OSCAR provides the concrete type `SubQuoHom{T1, T2} <: ModuleFPHom{T1, T2}`

as well as the following constructors:

`hom`

— Method`hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T`

Given a vector `V`

of `ngens(M)`

elements of `N`

, return the homomorphism `M`

$\to$ `N`

which sends the `i`

-th generator `M[i]`

of `M`

to the `i`

-th entry of `V`

.

`hom(M::SubquoModule{T}, N::ModuleFP{T}, A::MatElem{T})) where T`

Given a matrix `A`

with `ngens(M)`

rows and `ngens(N)`

columns, return the homomorphism `M`

$\to$ `N`

which sends the `i`

-th generator `M[i]`

of `M`

to the linear combination $\sum_j A[i,j]*N[j]$ of the generators `N[j]`

of `N`

.

The functions do not check whether the resulting homomorphism is well-defined, that is, whether it sends the relations of `M`

into the relations of `N`

.

If you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time.

`is_welldefined(a::ModuleFPHom)`

Return `true`

if `a`

is well-defined, and `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> N = M;
julia> V = [y^2*N[1], x*N[2]]
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
x*y^2*e[1]
x*y*e[1]
julia> a = hom(M, N, V)
Map with following data
Domain:
=======
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
Codomain:
=========
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> is_welldefined(a)
true
julia> W = R[y^2 0; 0 x]
[y^2 0]
[ 0 x]
julia> b = hom(M, N, W);
julia> a == b
true
```

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y];
julia> B = R[x^2; y^3; z^4];
julia> M = SubquoModule(F, A, B);
julia> N = M;
julia> W = [y*N[1], x*N[2]]
2-element Vector{SubquoModuleElem{QQMPolyRingElem}}:
x*y*e[1]
x*y*e[1]
julia> c = hom(M, N, W);
julia> is_welldefined(c)
false
```

Given a homomorphism of type `SubQuoHom`

, a matrix `A`

representing it is recovered by the following function:

`matrix`

— Method`matrix(a::SubQuoHom)`

Given a homomorphism `a`

of type `SubQuoHom`

with domain `M`

and codomain `N`

, return a matrix `A`

with `ngens(M)`

rows and `ngens(N)`

columns such that `a == hom(M, N, A)`

.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, QQMPolyRingElem[x, y, z])
julia> F = free_module(R, 1)
Free module of rank 1 over Multivariate Polynomial Ring in x, y, z over Rational Field
julia> A = R[x; y]
[x]
[y]
julia> B = R[x^2; y^3; z^4]
[x^2]
[y^3]
[z^4]
julia> M = SubquoModule(F, A, B)
Subquotient of Submodule with 2 generators
1 -> x*e[1]
2 -> y*e[1]
by Submodule with 3 generators
1 -> x^2*e[1]
2 -> y^3*e[1]
3 -> z^4*e[1]
julia> N = M;
julia> V = [y^2*N[1], x*N[2]];
julia> a = hom(M, N, V);
julia> A = matrix(a)
[y^2 0]
[ 0 x]
julia> a(M[1])
x*y^2*e[1]
```

The domain and codomain of a homomorphism `a`

of type `SubQuoHom`

can be recovered by entering `domain(a)`

and `codomain(a)`

, respectively.