# Ideals

Singular.jl allows the creation of ideals over a Singular polynomial ring. These are internally stored as a list of (polynomial) generators. This list of generators can also have the property of being a Groebner basis.

The default ideal type in Singular.jl is the Singular `sideal`

type.

Ideals objects have a parent object which represents the set of ideals they belong to, the data for which is given by the polynomial ring their generators belong to.

The types of ideals and associated parent objects are given in the following table according to the library providing them.

Library | Element type | Parent type |
---|---|---|

Singular | `sideal{T}` | `Singular.IdealSet{T}` |

These types are parameterised by the type of elements of the polynomial ring over which the ideals are defined.

All ideal types belong directly to the abstract type `Module{T}`

and all the ideal set parent object types belong to the abstract type `Set`

.

## Ideal functionality

Singular.jl ideals implement standard operations one would expect on modules. These include:

Operations common to all AbstractAlgebra objects, such as

`parent`

,`base_ring`

,`elem_type`

,`parent_type`

,`parent`

,`deepcopy`

, etc.Addition

Also implements is the following operations one expects for ideals:

Multiplication

Powering

Below, we describe all of the functionality for Singular.jl ideals that is not included in this list of basic operations.

### Constructors

Given a Singular polynomial ring $R$, the following constructors are available for creating ideals.

```
Ideal(R::PolyRing{T}, ids::spoly{T}...) where T <: Nemo.RingElem
Ideal(R::PolyRing{T}, ids::Vector{spoly{T}}) where T <: Nemo.RingElem
```

Construct the ideal over the polynomial ring $R$ whose (polynomial) generators are given by the given parameter list or array of polynomials, respectively. The list may be empty, resulting in the zero ideal.

**Examples**

```
julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
(Singular polynomial ring (ZZ),(x,y),(dp(2),C), spoly{n_Z}[x, y])
julia> I1 = Ideal(R, x*y + 1, x^2)
Singular ideal over Singular polynomial ring (ZZ),(x,y),(dp(2),C) with generators (x*y + 1, x^2)
julia> I2 = Ideal(R, [x*y + 1, x^2])
Singular ideal over Singular polynomial ring (ZZ),(x,y),(dp(2),C) with generators (x*y + 1, x^2)
```

### Basic manipulation

`AbstractAlgebra.number_of_generators`

— Method`number_of_generators(I::sideal)`

Return the number of generators in the internal representation of the ideal $I$.

`AbstractAlgebra.gens`

— Method`gens(I::sideal)`

Return the generators in the internal representation of the ideal $I$ as an array.

Singular.jl overloads the `setindex!`

and `getindex`

functions so that one can access the generators of an ideal using array notation.

`I[n::Int]`

`Base.iszero`

— Method`iszero(I::sideal)`

Return `true`

if the given ideal is algebraically the zero ideal.

`Singular.is_zerodim`

— Method`is_zerodim(I::sideal)`

Return `true`

if the given ideal is zero dimensional, i.e. the Krull dimension of $R/I$ is zero, where $R$ is the polynomial ring over which $I$ is an ideal.

`Singular.dimension`

— Method`dimension(I::sideal{spoly{T}}) where T <: Nemo.RingElem`

Given an ideal $I$ this function computes the Krull dimension of the ring $R/I$, where $R$ is the polynomial ring over which $I$ is an ideal. The ideal must be over a polynomial ring and a Groebner basis.

`AbstractAlgebra.is_constant`

— Method`is_constant(I::sideal)`

Return `true`

if the given ideal is a constant ideal, i.e. generated by constants in the polynomial ring over which it is an ideal.

`Singular.is_var_generated`

— Method`is_var_generated(I::sideal)`

Return `true`

if each generator in the representation of the ideal $I$ is a generator of the polynomial ring, i.e. a variable.

`LinearAlgebra.normalize!`

— Method`normalize!(I::sideal)`

Normalize the polynomial generators of the ideal $I$ in-place. This means to reduce their coefficients to lowest terms. In most cases this does nothing, but if the coefficient ring were the rational numbers for example, the coefficients of the polynomials would be reduced to lowest terms.

`Singular.interreduce`

— Method`interreduce(I::sideal{S}) where {T <: Nemo.RingElem, S <: Union{spoly{T}, spluralg{T}}}`

Interreduce the elements of I such that no leading term is divisible by another leading term. This returns a new ideal and does not modify the input ideal.

**Examples**

```
julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"])
(Singular polynomial ring (ZZ),(x,y),(dp(2),C), spoly{n_Z}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (ZZ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> n = number_of_generators(I)
2
julia> p = I[1]
x^2 + 1
julia> I[1] = 2x + y^2
y^2 + 2*x
julia> is_constant(I) == false
true
julia> is_var_generated(I) == false
true
julia> is_zerodim(I) == false
ERROR: Not a Groebner basis
julia> S, (u, v) = polynomial_ring(QQ, ["u", "v"])
(Singular polynomial ring (QQ),(u,v),(dp(2),C), spoly{n_Q}[u, v])
julia> J = Ideal(S, u^2 + 1, u*v)
Singular ideal over Singular polynomial ring (QQ),(u,v),(dp(2),C) with generators (u^2 + 1, u*v)
julia> dimension(std(J)) == 0
true
```

### Containment

`Base.contains`

— Method`contains(I::sideal{S}, J::sideal{S}) where S`

Return `true`

if the ideal $I$ contains the ideal $J$. This will be expensive if $I$ is not a Groebner ideal, since its standard basis must be computed.

**Examples**

```
julia> R, (x , y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> J = Ideal(R, x^2 + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1)
julia> contains(I, J) == true
true
```

### Comparison

Checking whether two ideals are algebraically equal is very expensive, as it usually requires computing Groebner bases. Therefore we do not overload the `==`

operator for ideals. Instead we have the following two functions.

`Base.isequal`

— Method`isequal(I1::sideal{S}, I2::sideal{S}) where S <: SPolyUnion`

Return `true`

if the given ideals have the same generators in the same order. Note that two algebraically equal ideals with different generators will return `false`

.

`Singular.equal`

— Method`equal(I1::sideal{S}, I2::sideal{S}) where S <: SPolyUnion`

Return `true`

if the two ideals are contained in each other, i.e. are the same ideal mathematically. This function should be called only as a last resort; it is exceptionally expensive to test equality of ideals! Do not define `==`

as an alias for this function!

**Examples**

```
julia> R, (x , y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> J = Ideal(R, x^2 + x*y + 1, x^2 - x*y + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + x*y + 1, x^2 - x*y + 1)
julia> isequal(I, J) == false
true
julia> equal(I, J) == true
true
```

### Intersection

`Singular.intersection`

— Method`intersection(I::sideal{S}, J::sideal{S}) where {T <: Nemo.RingElem, S <: Union{spoly{T}, spluralg{T}}}`

Return the intersection of the two given ideals.

**Examples**

```
julia> R, (x , y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> J = Ideal(R, x^2 + x*y + 1, x^2 - x*y + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + x*y + 1, x^2 - x*y + 1)
julia> V = intersection(I, J)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (y, x^2 - x*y + 1)
```

### Quotient

`Singular.quotient`

— Method`quotient(I::sideal{S}, J::sideal{S}) where S <: spoly`

Return the quotient of the two given ideals. Recall that the ideal quotient $(I:J)$ over a polynomial ring $R$ is defined by $\{r \in R \;|\; rJ \subseteq I\}$.

**Examples**

```
julia> R, (x , y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> J = Ideal(R, x + y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x + y)
julia> V = quotient(I, J)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (y, x^2 + 1)
```

`Singular.quotient`

— Method`quotient(I::sideal{S}, J::sideal{S}) where S <: spluralg`

Return the quotient of the two given ideals, where $J$ must be two-sided.

### Leading terms

`Singular.lead`

— Method`lead(I::sideal{S}) where S <: SPolyUnion`

Return the ideal generated by the leading terms of the polynomials generating $I$.

**Examples**

```
julia> R, (x , y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + 1, x*y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + 1, x*y)
julia> V = lead(I)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2, x*y)
```

### Homogeneous ideals

`Singular.is_homogeneous`

— Method`is_homogeneous(I::sideal)`

Return `true`

if each stored generator of `I`

is homogeneous, otherwise `false`

. If `base_ring(I)`

has a weighted monomial ordering, the test is conducted with respect to the corresponding weights.

`Singular.homogenize`

— Method`homogenize(I::sideal{S}, v::S) where S <: spoly`

Multiply each monomial in the generators of `I`

by a suitable power of the variable `v`

and return the corresponding homogeneous ideal. The variable `v`

must have weight `1`

.

### Saturation

`Singular.saturation`

— Method`saturation(I::sideal{T}, J::sideal{T}) where T <: Nemo.RingElem`

Return the saturation of the ideal $I$ with respect to $J$, i.e. returns the quotient ideal $(I:J^\infty)$ and the number of iterations.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, (x^2 + x*y + 1)*(2y^2+1)^3, (2y^2 + 3)*(2y^2+1)^2)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (8*x^2*y^6 + 8*x*y^7 + 12*x^2*y^4 + 12*x*y^5 + 8*y^6 + 6*x^2*y^2 + 6*x*y^3 + 12*y^4 + x^2 + x*y + 6*y^2 + 1, 8*y^6 + 20*y^4 + 14*y^2 + 3)
julia> J = Ideal(R, 2y^2 + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (2*y^2 + 1)
julia> S = saturation(I, J)
(Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (2*y^2 + 3, x^2 + x*y + 1), 2)
```

### Standard basis

`Statistics.std`

— Method`std(I::sideal{S}; complete_reduction::Bool=false) where S <: SPolyUnion`

Compute a Groebner basis for the ideal $I$. Note that without `complete_reduction`

set to `true`

, the generators of the Groebner basis only have unique leading terms (up to permutation and multiplication by constants). If `complete_reduction`

is set to `true`

(and the ordering is a global ordering) then the Groebner basis is unique.

`Singular.fglm`

— Method`fglm(I::sideal{spoly{T}}, ordering::Symbol) where T <: Nemo.RingElem`

Compute a Groebner basis for the zero - dimensional ideal $I$ in the ring $R$ using the FGLM algorithm. All involved orderings have to be global.

`Singular.satstd`

— Method`satstd(I::sideal{spoly{T}}, J::sideal{spoly{T}} = Ideal(base_ring(I), gens(base_ring(I)))) where T <: Nemo.RingElem`

Given an ideal $J$ generated by variables, computes a standard basis of `saturation(I, J)`

. This is accomplished by dividing polynomials that occur throughout the std computation by variables occurring in $J$, where possible. Thus the result can be obtained faster than by first computing the saturation and then the standard basis.

`Singular.lift_std`

— Method`lift_std(M::sideal{S}; complete_reduction::Bool = false) where S <: spoly`

Computes the Groebner base G of M and the transformation matrix T such that (Matrix(G) = Matrix(M) * T)

`Singular.lift_std_syz`

— Method`lift_std_syz(M::sideal{S}; complete_reduction::Bool = false) where S <: spoly`

Computes the Groebner base G of I, the transformation matrix T and the syzygies of M. Returns G,T,S (Matrix(G) = Matrix(I) * T, 0=Matrix(M)*Matrix(S))

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2 + x*y + 1, 2y^2 + 3)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2 + x*y + 1, 2*y^2 + 3)
julia> J = Ideal(R, 2*y^2 + 3, x^2 + x*y + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (2*y^2 + 3, x^2 + x*y + 1)
julia> A = std(I)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (2*y^2 + 3, x^2 + x*y + 1)
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, (x*y + 1)*(2x^2*y^2 + x*y - 2) + 2x*y^2 + x, 2x*y + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (2*x^3*y^3 + 3*x^2*y^2 + 2*x*y^2 - x*y + x - 2, 2*x*y + 1)
julia> J = Ideal(R, x)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x)
julia> B = satstd(I, J)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x - y - 1, 2*y^2 + 2*y + 1)
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"], ordering = :lex)
(Singular polynomial ring (QQ),(x,y,z),(lp(3),C), spoly{n_Q}[x, y, z])
julia> I = Ideal(R, y^3+x^2, x^2*y+x^2, x^3-x^2, z^4-x^2-y)
Singular ideal over Singular polynomial ring (QQ),(x,y,z),(lp(3),C) with generators (x^2 + y^3, x^2*y + x^2, x^3 - x^2, -x^2 - y + z^4)
julia> J = fglm(I, :degrevlex)
Singular ideal over Singular polynomial ring (QQ),(x,y,z),(lp(3),C) with generators (z^12, y*z^4 - z^8, y^2 + y - z^8 - z^4, x*y - x*z^4 - y + z^4, x^2 + y - z^4)
```

### Reduction

`Base.reduce`

— Method`reduce(I::sideal{S}, G::sideal{S}) where S <: SPolyUnion`

Return an ideal whose generators are the generators of $I$ reduced by the ideal $G$. The ideal $G$ need not be a Groebner basis. The returned ideal will have the same number of generators as $I$, even if they are zero. For PLURAL rings (S <: spluralg, GAlgebra, WeylAlgebra), the reduction is only a left reduction, and hence cannot be used to test containment in a two-sided ideal. For LETTERPLACE rings (S <: slpalg, FreeAlgebra), the reduction is two-sided as only two-sided ideals can be constructed here.

`Base.reduce`

— Method`reduce(p::S, G::sideal{S}) where S <: SPolyUnion`

Return the polynomial which is $p$ reduced by the polynomials generating $G$. The ideal $G$ need not be a Groebner basis. For PLURAL rings (S <: spluralg, GAlgebra, WeylAlgebra), the reduction is only a left reduction, and hence cannot be used to test membership in a two-sided ideal. For LETTERPLACE rings (S <: slpalg, FreeAlgebra), the reduction is the full two-sided reduction as only two-sided ideals can be constructed here.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> f = x^2*y + 2y + 1
x^2*y + 2*y + 1
julia> g = y^2 + 1
y^2 + 1
julia> I = Ideal(R, (x^2 + 1)*f + (x + y)*g + x + 1, (2y^2 + x)*f + y)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^4*y + 3*x^2*y + x*y^2 + y^3 + x^2 + 2*x + 3*y + 2, 2*x^2*y^3 + x^3*y + 4*y^3 + 2*x*y + 2*y^2 + x + y)
julia> J = std(Ideal(R, f, g))
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (y^2 + 1, x^2 - y + 2)
julia> V = reduce(I, J)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x + 1, y)
julia> h1 = (x^2 + 1)*f + (x + y)*g + x + 1
x^4*y + 3*x^2*y + x*y^2 + y^3 + x^2 + 2*x + 3*y + 2
julia> h2 = reduce(h1, J)
x + 1
```

### Elimination

`Singular.eliminate`

— Method`eliminate(I::sideal{S}, polys::S...) where {T <: Nemo.RingElem, S <: Union{spoly{T}, spluralg{T}}}`

Given a list of polynomials which are variables, construct the ideal corresponding geometrically to the projection of the variety given by the ideal $I$ where those variables have been eliminated.

**Examples**

```
julia> R, (x, y, t) = polynomial_ring(QQ, ["x", "y", "t"])
(Singular polynomial ring (QQ),(x,y,t),(dp(3),C), spoly{n_Q}[x, y, t])
julia> I = Ideal(R, x - t^2, y - t^3)
Singular ideal over Singular polynomial ring (QQ),(x,y,t),(dp(3),C) with generators (-t^2 + x, -t^3 + y)
julia> J = eliminate(I, t)
Singular ideal over Singular polynomial ring (QQ),(x,y,t),(dp(3),C) with generators (x^3 - y^2)
```

### Syzygies

`Singular.syz`

— Method`syz(I::sideal)`

Compute the module of syzygies of the ideal.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2*y + 2y + 1, y^2 + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2*y + 2*y + 1, y^2 + 1)
julia> F = syz(I)
Singular Module over Singular polynomial ring (QQ),(x,y),(dp(2),C), with Generators:
x^2*y*gen(2)-y^2*gen(1)+2*y*gen(2)+gen(2)-gen(1)
julia> M = Singular.Matrix(I)
[x^2*y + 2*y + 1, y^2 + 1]
julia> N = Singular.Matrix(F)
[-y^2 - 1
x^2*y + 2*y + 1]
julia> iszero(M*N) # check they are actually syzygies
true
```

### Free resolutions

`Singular.fres`

— Method`fres(id::sideal{spoly{T}}, max_length::Int, method::String="complete") where T <: Nemo.FieldElem`

Compute a free resolution of the given ideal up to the maximum given length. The ideal must be over a polynomial ring over a field, and a Groebner basis. The possible methods are "complete", "frame", "extended frame" and "single module". The result is given as a resolution, whose i-th entry is the syzygy module of the previous module, starting with the given ideal/module. The `max_length`

can be set to $0$ if the full free resolution is required.

`Singular.sres`

— Method`sres(id::sideal{spoly{T}}, max_length::Int) where T <: Nemo.FieldElem`

Compute a (free) Schreyer resolution of the given ideal up to the maximum given length. The ideal must be over a polynomial ring over a field, and a Groebner basis. The result is given as a resolution, whose i-th entry is the syzygy module of the previous module, starting with the given ideal. The `max_length`

can be set to $0$ if the full free resolution is required.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, x^2*y + 2y + 1, y^2 + 1)
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^2*y + 2*y + 1, y^2 + 1)
julia> F1 = fres(std(I), 0)
Singular Resolution:
R^1 <- R^2 <- R^1
julia> F2 = sres(std(I), 2)
Singular Resolution:
R^1 <- R^2 <- R^1
```

### Differential operations

`Singular.jet`

— Method`jet(I::sideal{S}, n::Int) where {T <: Nemo.RingElem, S <: Union{spoly{T}, spluralg{T}}}`

Given an ideal $I$ this function truncates the generators of $I$ up to degree $n$.

**Examples**

```
julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Singular polynomial ring (QQ),(x,y,z),(dp(3),C), spoly{n_Q}[x, y, z])
julia> I = Ideal(R, x^5 - y^2, y^3 - x^6 + z^3)
Singular ideal over Singular polynomial ring (QQ),(x,y,z),(dp(3),C) with generators (x^5 - y^2, -x^6 + y^3 + z^3)
julia> J1 = jet(I, 3)
Singular ideal over Singular polynomial ring (QQ),(x,y,z),(dp(3),C) with generators (-y^2, y^3 + z^3)
```

### Operations on zero-dimensional ideals

`Singular.vdim`

— Method`vdim(I::sideal{S}) where {T <: Nemo.FieldElem, S <: Union{spoly{T}, spluralg{T}}}`

Given a zero-dimensional ideal $I$ this function computes the dimension of the vector space `base_ring(I)/I`

, where `base_ring(I)`

must be a polynomial ring over a field, and $I$ must be a Groebner basis. The return is $-1$ if `!is_zerodim(I)`

.

`Singular.kbase`

— Method`kbase(I::sideal{S}) where {T <: Nemo.FieldElem, S <: Union{spoly{T}, spluralg{T}}}`

Given a zero-dimensional ideal $I$ this function computes a vector space basis of the vector space `base_ring(I)/I`

, where `base_ring(I)`

must be a polynomial ring over a field, and $I$ must be a Groebner basis. The array of vector space basis elements is returned as a Singular ideal, and this array consists of one zero polynomial if `!is_zerodim(I)`

.

`Singular.highcorner`

— Method`highcorner(I::sideal{S}) where {T <: Nemo.FieldElem, S <: Union{spoly{T}, spluralg{T}}}`

Given a zero-dimensional ideal $I$ this function computes its highest corner, which is a polynomial. The ideal must be over a polynomial ring over a field, and a Groebner basis. The return is the zero polynomial if `!is_zerodim(I)`

.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]; ordering=:negdegrevlex)
(Singular polynomial ring (QQ),(x,y),(ds(2),C), spoly{n_Q}[x, y])
julia> I = Ideal(R, 3*x^2 + y^3, x*y^2)
Singular ideal over Singular polynomial ring (QQ),(x,y),(ds(2),C) with generators (3*x^2 + y^3, x*y^2)
julia> I = std(I)
Singular ideal over Singular polynomial ring (QQ),(x,y),(ds(2),C) with generators (3*x^2 + y^3, x*y^2, y^5)
julia> n = vdim(I)
7
julia> J = kbase(I)
Singular ideal over Singular polynomial ring (QQ),(x,y),(ds(2),C) with generators (y^4, y^3, y^2, x*y, y, x, 1)
julia> f = highcorner(I)
y^4
```

### Operations over local rings

If the base ring `R`

is a local ring, a minimal generating set can be computed using the following function

`Singular.minimal_generating_set`

— Method`minimal_generating_set(I::sideal{S}) where S <: spoly`

Given an ideal $I$ in ring $R$ with local ordering, this returns an array containing the minimal generators of $I$.

**Examples**

```
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]; ordering=:negdegrevlex)
(Singular polynomial ring (QQ),(x,y),(ds(2),C), spoly{n_Q}[x, y])
julia> has_local_ordering(R) == true
true
julia> I = Ideal(R, y, x^2, (1 + y^3) * (x^2 - y))
Singular ideal over Singular polynomial ring (QQ),(x,y),(ds(2),C) with generators (y, x^2, -y + x^2 - y^4 + x^2*y^3)
julia> min = minimal_generating_set(I)
2-element Vector{spoly{n_Q}}:
x^2
y
```

### Independent sets of monomial ideals

Let $I$ be an ideal of $K[x_1, ..., x_n].$ An `independent set`

is a subset $u \subseteq \{x_1, ..., x_n\},$ such that $I \cap K[u]= 0.$ In case $u$ cannot be enlarged, it is called `non-extendable independent set`

. If in addition $|u| = dim(K[x_1, ..., x_n]/I),$ $u$ is called `maximal independent set`

. Using Singular.jl one can compute non-extendable, resp. maximal independent sets for monomial ideals. If an arbitrary ideal $I$ is passed to the function, the computation is performed on the leading ideal of $I$.

`Singular.independent_sets`

— Method`independent_sets(I::sideal{spoly{T}}) where T <: Nemo.FieldElem`

Return all non-extendable independent sets of $lead(I)$. $I$ has to be given by a Groebner basis.

`Singular.maximal_independent_set`

— Method`maximal_independent_set(I::sideal{spoly{T}}; all::Bool = false) where T <: Nemo.FieldElem`

Returns, by default, an array containing a maximal independent set of $lead(I)$. $I$ has to be given by a Groebner basis. If the additional parameter "all" is set to true, an array containing all maximal independent sets of $lead(I)$ is returned.

```
julia> R, (x, y, u, v, w) = polynomial_ring(QQ, ["x", "y", "u", "v", "w"])
(Singular polynomial ring (QQ),(x,y,u,v,w),(dp(5),C), spoly{n_Q}[x, y, u, v, w])
julia> has_local_ordering(R) == true
false
julia> I = Ideal(R, x*y*w, y*v*w, u*y*w, x*v)
Singular ideal over Singular polynomial ring (QQ),(x,y,u,v,w),(dp(5),C) with generators (x*y*w, y*v*w, y*u*w, x*v)
julia> I = std(I)
Singular ideal over Singular polynomial ring (QQ),(x,y,u,v,w),(dp(5),C) with generators (x*v, y*v*w, y*u*w, x*y*w)
julia> L1 = independent_sets(I)
5-element Vector{Vector{spoly{n_Q}}}:
[x, y, u]
[y, u, v]
[x, u, w]
[u, v, w]
[y, w]
julia> L2 = maximal_independent_set(I)
3-element Vector{spoly{n_Q}}:
x
y
u
julia> L3 = maximal_independent_set(I, all = true)
4-element Vector{Vector{spoly{n_Q}}}:
[x, y, u]
[y, u, v]
[x, u, w]
[u, v, w]
```