Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type changes for modules over non commutative rings #3988

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ function pushforward(inc::ProjectiveClosedEmbedding, M::SubquoModule)
G, inc_G = sub(FT, vcat(gT, relT))
Q, inc_Q = sub(G, gens(G)[length(gT)+1:end])
MT = cokernel(inc_Q)
id = hom(MT, M, vcat(gens(M), elem_type(M)[zero(M) for i in 1:length(relT)]); check=false)
id = hom(MT, M, vcat(gens(M), elem_type(M)[zero(M) for i in 1:length(relT)]), S; check=false)
return MT, id
end

Expand Down
53 changes: 30 additions & 23 deletions src/Modules/ModuleTypes.jl
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
import AbstractAlgebra.WeakKeyIdDict

# The following type union gathers all types for elements for which
# we expect the `ModuleFP` framework to be functional and/or working.
# It can gradually be extended, but should not be considered to be
# visible or accessible to the outside world.
const AdmissibleModuleFPRingElem = Union{RingElem, PBWAlgQuoElem, PBWAlgElem}
const AdmissibleModuleFPRing = Union{Ring, PBWAlgQuo, PBWAlgRing}

@doc raw"""
ModuleFP{T}

The abstract supertype of all finitely presented modules.
The type variable `T` refers to the type of the elements of the base ring.
"""
abstract type ModuleFP{T} <: AbstractAlgebra.Module{T} end
abstract type ModuleFP{T <: AdmissibleModuleFPRingElem} <: AbstractAlgebra.Module{T} end

@doc raw"""
AbstractFreeMod{T} <: ModuleFP{T}

The abstract supertype of all finitely generated free modules.
"""
abstract type AbstractFreeMod{T} <: ModuleFP{T} end
abstract type AbstractFreeMod{T <: AdmissibleModuleFPRingElem} <: ModuleFP{T} end

@doc raw"""
AbstractSubQuo{T} <: ModuleFP{T}

The abstract supertype of all finitely presented subquotient modules.
"""
abstract type AbstractSubQuo{T} <: ModuleFP{T} end
abstract type AbstractSubQuo{T <: AdmissibleModuleFPRingElem} <: ModuleFP{T} end


@doc raw"""
ModuleFPElem{T} <: ModuleElem{T}

The abstract supertype of all elements of finitely presented modules.
"""
abstract type ModuleFPElem{T} <: ModuleElem{T} end
abstract type ModuleFPElem{T <: AdmissibleModuleFPRingElem} <: ModuleElem{T} end

@doc raw"""
AbstractFreeModElem{T} <: ModuleFPElem{T}

The abstract supertype of all elements of finitely generated free modules.
"""
abstract type AbstractFreeModElem{T} <: ModuleFPElem{T} end
abstract type AbstractFreeModElem{T <: AdmissibleModuleFPRingElem} <: ModuleFPElem{T} end

@doc raw"""
AbstractSubQuoElem{T} <: ModuleFPElem{T}

The abstract supertype of all elements of subquotient modules.
"""
abstract type AbstractSubQuoElem{T} <: ModuleFPElem{T} end
abstract type AbstractSubQuoElem{T <: AdmissibleModuleFPRingElem} <: ModuleFPElem{T} end

abstract type ModuleFPHomDummy end

Expand Down Expand Up @@ -70,8 +77,8 @@ Moreover, canonical incoming and outgoing morphisms are stored if the correspond
option is set in suitable functions.
`FreeMod{T}` is a subtype of `AbstractFreeMod{T}`.
"""
@attributes mutable struct FreeMod{T <: RingElem} <: AbstractFreeMod{T}
R::Ring
@attributes mutable struct FreeMod{T <: AdmissibleModuleFPRingElem} <: AbstractFreeMod{T}
R::NCRing
n::Int
S::Vector{Symbol}
d::Union{Vector{FinGenAbGroupElem}, Nothing}
Expand All @@ -91,7 +98,7 @@ option is set in suitable functions.
incoming::WeakKeyIdDict{<:ModuleFP, <:Tuple{<:SMat, <:Any}}
outgoing::WeakKeyIdDict{<:ModuleFP, <:Tuple{<:SMat, <:Any}}

function FreeMod{T}(n::Int,R::Ring,S::Vector{Symbol}) where T <: RingElem
function FreeMod{T}(n::Int, R::AdmissibleModuleFPRing, S::Vector{Symbol}) where T <: AdmissibleModuleFPRingElem
r = new{elem_type(R)}()
r.n = n
r.R = R
Expand All @@ -105,7 +112,7 @@ option is set in suitable functions.
end

@doc raw"""
FreeModElem{T} <: AbstractFreeModElem{T}
FreeModElem{T <: AdmissibleModuleFPRingElem} <: AbstractFreeModElem{T}

The type of free module elements. An element of a free module $F$ is given by a sparse row (`SRow`)
which specifies its coordinates with respect to the basis of standard unit vectors of $F$.
Expand All @@ -131,7 +138,7 @@ julia> f == g
true
```
"""
mutable struct FreeModElem{T} <: AbstractFreeModElem{T}
mutable struct FreeModElem{T <: AdmissibleModuleFPRingElem} <: AbstractFreeModElem{T}
coords::SRow{T} # also usable via coeffs()
parent::FreeMod{T}
d::Union{FinGenAbGroupElem, Nothing}
Expand All @@ -155,7 +162,7 @@ and all the conversion is taken care of here.
This data structure is also used for representing Gröbner / standard bases.
Relative Gröbner / standard bases are also supported.
"""
@attributes mutable struct ModuleGens{T} # T is the type of the elements of the ground ring.
@attributes mutable struct ModuleGens{T <: AdmissibleModuleFPRingElem} # T is the type of the elements of the ground ring.
O::Vector{FreeModElem{T}}
S::Singular.smodule
F::FreeMod{T}
Expand All @@ -166,7 +173,7 @@ Relative Gröbner / standard bases are also supported.
ordering::ModuleOrdering
quo_GB::ModuleGens{T} # Pointer to the quotient GB when having a relative GB

function ModuleGens{T}(O::Vector{<:FreeModElem}, F::FreeMod{T}) where {T}
function ModuleGens{T}(O::Vector{<:FreeModElem}, F::FreeMod{T}) where {T <: AdmissibleModuleFPRingElem}
r = new{T}()
r.O = O
r.F = F
Expand All @@ -175,7 +182,7 @@ Relative Gröbner / standard bases are also supported.

# ModuleGens from an Array of Oscar free module elements, specifying the free module
# and Singular free module, only useful indirectly
function ModuleGens{T}(O::Vector{<:FreeModElem}, F::FreeMod{T}, SF::Singular.FreeMod) where {T}
function ModuleGens{T}(O::Vector{<:FreeModElem}, F::FreeMod{T}, SF::Singular.FreeMod) where {T <: AdmissibleModuleFPRingElem}
r = new{T}()
r.O = O
r.SF = SF
Expand All @@ -184,7 +191,7 @@ Relative Gröbner / standard bases are also supported.
end

# ModuleGens from a Singular submodule
function ModuleGens{S}(F::FreeMod{S}, s::Singular.smodule) where {S} # FreeMod is necessary due to type S
function ModuleGens{S}(F::FreeMod{S}, s::Singular.smodule) where {S <: AdmissibleModuleFPRingElem} # FreeMod is necessary due to type S
r = new{S}()
r.F = F
if Singular.ngens(s) == 0
Expand All @@ -198,14 +205,14 @@ Relative Gröbner / standard bases are also supported.
end

@doc raw"""
SubModuleOfFreeModule{T} <: ModuleFP{T}
SubModuleOfFreeModule{T <: AdmissibleModuleFPRingElem} <: ModuleFP{T}

Data structure for submodules of free modules. `SubModuleOfFreeModule` shouldn't be
used by the end user.
When computed, a standard basis (computed via `standard_basis()`) and generating matrix (that is the rows of the matrix
generate the submodule) (computed via `generator_matrix()`) are cached.
"""
@attributes mutable struct SubModuleOfFreeModule{T} <: ModuleFP{T}
@attributes mutable struct SubModuleOfFreeModule{T <: AdmissibleModuleFPRingElem} <: ModuleFP{T}
F::FreeMod{T}
gens::ModuleGens{T}
groebner_basis::Dict{ModuleOrdering, ModuleGens{T}}
Expand All @@ -224,7 +231,7 @@ end


@doc raw"""
SubquoModule{T} <: AbstractSubQuo{T}
SubquoModule{T <: AdmissibleModuleFPRingElem} <: AbstractSubQuo{T}

The type of subquotient modules.
A subquotient module $M$ is a module where $M = A + B / B$ where $A$ and $B$ are
Expand All @@ -236,7 +243,7 @@ Moreover, canonical incoming and outgoing morphisms are stored if the correspond
option is set in suitable functions.
`SubquoModule{T}` is a subtype of `ModuleFP{T}`.
"""
@attributes mutable struct SubquoModule{T} <: AbstractSubQuo{T}
@attributes mutable struct SubquoModule{T <: AdmissibleModuleFPRingElem} <: AbstractSubQuo{T}
#meant to represent sub+ quo mod quo - as lazy as possible
F::FreeMod{T}
sub::SubModuleOfFreeModule
Expand Down Expand Up @@ -264,7 +271,7 @@ end


@doc raw"""
SubquoModuleElem{T} <: AbstractSubQuoElem{T}
SubquoModuleElem{T <: AdmissibleModuleFPRingElem} <: AbstractSubQuoElem{T}

The type of subquotient elements. An element $f$ of a subquotient $M$ over the ring $R$
is given by a sparse row (`SRow`) which specifies the coefficients of an $R$-linear
Expand Down Expand Up @@ -308,13 +315,13 @@ julia> f == g
true
```
"""
mutable struct SubquoModuleElem{T} <: AbstractSubQuoElem{T}
mutable struct SubquoModuleElem{T <: AdmissibleModuleFPRingElem} <: AbstractSubQuoElem{T}
parent::SubquoModule{T}
coeffs::SRow{T} # Need not be defined! Use `coordinates` as getter
repres::FreeModElem{T} # Need not be defined! Use `repres` as getter
is_reduced::Bool # `false` by default. Will be set by `simplify` and `simplify!`.

function SubquoModuleElem{R}(v::SRow{R}, SQ::SubquoModule) where {R}
function SubquoModuleElem{R}(v::SRow{R}, SQ::SubquoModule) where {R <: AdmissibleModuleFPRingElem}
@assert length(v) <= ngens(SQ.sub)
if isempty(v)
r = new{R}(SQ, v, zero(SQ.F))
Expand All @@ -326,7 +333,7 @@ mutable struct SubquoModuleElem{T} <: AbstractSubQuoElem{T}
return r
end

function SubquoModuleElem{R}(a::FreeModElem{R}, SQ::SubquoModule; is_reduced::Bool=false) where {R}
function SubquoModuleElem{R}(a::FreeModElem{R}, SQ::SubquoModule; is_reduced::Bool=false) where {R <: AdmissibleModuleFPRingElem}
@assert a.parent === SQ.F
r = new{R}(SQ)
r.repres = a
Expand Down
30 changes: 15 additions & 15 deletions src/Modules/ModulesGraded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
###############################################################################

@doc raw"""
graded_free_module(R::Ring, p::Int, W::Vector{FinGenAbGroupElem}=[grading_group(R)[0] for i in 1:p], name::String="e")
graded_free_module(R::AdmissibleModuleFPRing, p::Int, W::Vector{FinGenAbGroupElem}=[grading_group(R)[0] for i in 1:p], name::String="e")

Given a graded ring `R` with grading group `G`, say,
and given a vector `W` with `p` elements of `G`, create the free module $R^p$
equipped with its basis of standard unit vectors, and assign weights to these
vectors according to the entries of `W`. Return the resulting graded free module.

graded_free_module(R::Ring, W::Vector{FinGenAbGroupElem}, name::String="e")
graded_free_module(R::AdmissibleModuleFPRing, W::Vector{FinGenAbGroupElem}, name::String="e")

As above, with `p = length(W)`.

Expand All @@ -36,7 +36,7 @@
Graded free module R^1([-1]) + R^1([-2]) of rank 2 over R
```
"""
function graded_free_module(R::Ring, p::Int, W::Vector{FinGenAbGroupElem}=[grading_group(R)[0] for i in 1:p], name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, p::Int, W::Vector{FinGenAbGroupElem}=[grading_group(R)[0] for i in 1:p], name::String="e")
@assert length(W) == p
@assert is_graded(R)
all(x -> parent(x) == grading_group(R), W) || error("entries of W must be elements of the grading group of the base ring")
Expand All @@ -45,20 +45,20 @@
return M
end

function graded_free_module(R::Ring, p::Int, W::Vector{Any}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, p::Int, W::Vector{Any}, name::String="e")

Check warning on line 48 in src/Modules/ModulesGraded.jl

View check run for this annotation

Codecov / codecov/patch

src/Modules/ModulesGraded.jl#L48

Added line #L48 was not covered by tests
@assert length(W) == p
@assert is_graded(R)
p == 0 || error("W should be either an empty array or a Vector{FinGenAbGroupElem}")
W = FinGenAbGroupElem[]
return graded_free_module(R, p, W, name)
end

function graded_free_module(R::Ring, W::Vector{FinGenAbGroupElem}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, W::Vector{FinGenAbGroupElem}, name::String="e")
p = length(W)
return graded_free_module(R, p, W, name)
end

function graded_free_module(R::Ring, W::Vector{Any}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, W::Vector{Any}, name::String="e")
p = length(W)
@assert is_graded(R)
p == 0 || error("W should be either an empty array or a Vector{FinGenAbGroupElem}")
Expand All @@ -67,19 +67,19 @@
end

@doc raw"""
graded_free_module(R::Ring, W::Vector{<:Vector{<:IntegerUnion}}, name::String="e")
graded_free_module(R::AdmissibleModuleFPRing, W::Vector{<:Vector{<:IntegerUnion}}, name::String="e")

Given a graded ring `R` with grading group $G = \mathbb Z^m$,
and given a vector `W` of integer vectors of the same size `p`, say, create the free
module $R^p$ equipped with its basis of standard unit vectors, and assign weights to these
vectors according to the entries of `W`, converted to elements of `G`. Return the
resulting graded free module.

graded_free_module(R::Ring, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")
graded_free_module(R::AdmissibleModuleFPRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")

As above, converting the columns of `W`.

graded_free_module(R::Ring, W::Vector{<:IntegerUnion}, name::String="e")
graded_free_module(R::AdmissibleModuleFPRing, W::Vector{<:IntegerUnion}, name::String="e")

Given a graded ring `R` with grading group $G = \mathbb Z$,
and given a vector `W` of integers, set `p = length(W)`, create the free module $R^p$
Expand Down Expand Up @@ -113,7 +113,7 @@
true
```
"""
function graded_free_module(R::Ring, W::Vector{<:Vector{<:IntegerUnion}}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, W::Vector{<:Vector{<:IntegerUnion}}, name::String="e")
@assert is_zm_graded(R)
n = length(W[1])
@assert all(x->length(x) == n, W)
Expand All @@ -122,14 +122,14 @@
return graded_free_module(R, length(W), d, name)
end

function graded_free_module(R::Ring, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}}, name::String="e")
@assert is_zm_graded(R)
A = grading_group(R)
d = [A(W[:, i]) for i = 1:size(W, 2)]
return graded_free_module(R, size(W, 2), d, name)
end

function graded_free_module(R::Ring, W::Vector{<:IntegerUnion}, name::String="e")
function graded_free_module(R::AdmissibleModuleFPRing, W::Vector{<:IntegerUnion}, name::String="e")
@assert is_graded(R)
A = grading_group(R)
d = [W[i] * A[1] for i in 1:length(W)]
Expand Down Expand Up @@ -652,7 +652,7 @@
return graded_map(Fcdm, A)
end

function graded_map(F::FreeMod{T}, A::MatrixElem{T}; check::Bool=true) where {T <: RingElement}
function graded_map(F::FreeMod{T}, A::MatrixElem{T}; check::Bool=true) where {T <: AdmissibleModuleFPRingElem}
R = base_ring(F)
G = grading_group(R)
source_degrees = Vector{eltype(G)}()
Expand All @@ -669,7 +669,7 @@
return phi
end

function graded_map(F::FreeMod{T}, V::Vector{<:AbstractFreeModElem{T}}; check::Bool=true) where {T <: RingElement}
function graded_map(F::FreeMod{T}, V::Vector{<:AbstractFreeModElem{T}}; check::Bool=true) where {T <: AdmissibleModuleFPRingElem}
R = base_ring(F)
G = grading_group(R)
nrows = length(V)
Expand Down Expand Up @@ -697,7 +697,7 @@
end


function graded_map(F::SubquoModule{T}, V::Vector{<:ModuleFPElem{T}}; check::Bool=true) where {T <: RingElement}
function graded_map(F::SubquoModule{T}, V::Vector{<:ModuleFPElem{T}}; check::Bool=true) where {T <: AdmissibleModuleFPRingElem}
R = base_ring(F)
G = grading_group(R)
nrows = length(V)
Expand Down
8 changes: 5 additions & 3 deletions src/Modules/UngradedModules/FreeMod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ Additionally one can provide names for the generators. If one does
not provide names for the generators, the standard names e_i are used for
the standard unit vectors.
"""
function FreeMod(R::Ring, n::Int, name::VarName = :e; cached::Bool = false) # TODO cached?
function FreeMod(R::AdmissibleModuleFPRing, n::Int, name::VarName = :e; cached::Bool = false) # TODO cached?
return FreeMod{elem_type(R)}(n, R, [Symbol("$name[$i]") for i=1:n])
end

function FreeMod(R::Ring, names::Vector{String}; cached::Bool=false)
function FreeMod(R::AdmissibleModuleFPRing, names::Vector{String}; cached::Bool=false)
return FreeMod{elem_type(R)}(length(names), R, Symbol.(names))
end

function FreeMod(R::Ring, names::Vector{Symbol}; cached::Bool=false)
function FreeMod(R::AdmissibleModuleFPRing, names::Vector{Symbol}; cached::Bool=false)
return FreeMod{elem_type(R)}(length(names), R, names)
end

Expand Down Expand Up @@ -76,6 +76,8 @@ free_module(R::MPolyQuoRing, p::Int, name::VarName = :e; cached::Bool = false) =
free_module(R::MPolyLocRing, p::Int, name::VarName = :e; cached::Bool = false) = FreeMod(R, p, name, cached = cached)
free_module(R::MPolyQuoLocRing, p::Int, name::VarName = :e; cached::Bool = false) = FreeMod(R, p, name, cached = cached)

#free_module(R::NCRing, p::Int, name::VarName = :e; cached::Bool = false) = FreeMod(R, p, name, cached = cached)

#=XXX this cannot be as it is inherently ambiguous
- free_module(R, n)
- direct sum of rings, ie. a ring
Expand Down
Loading
Loading