From 9e8825416f661993aaa6b7075dceefa1292f872a Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Wed, 14 Aug 2024 12:14:26 +0200 Subject: [PATCH 01/17] some changes --- src/Rings/FreeAssAlgIdeal.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index 99a0c64a7eb1..9d0898ced973 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -134,7 +134,7 @@ function (A::FreeAssAlgebra)(a::Singular.slpalg) return finish(B) end -_to_lpring(a::FreeAssAlgebra, deg_bound::Int) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound) +_to_lpring(a::FreeAssAlgebra, deg_bound::Int; ordering::Symbol=:degrevlex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) @doc raw""" groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; protocol::Bool=false) @@ -157,16 +157,16 @@ Ideal generating system with elements 4 -> y^2*x + y*z*y ``` """ -function groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; protocol::Bool=false) +function groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) isdefined(I, :gb) && return I.gb - I.gb = groebner_basis(IdealGens(gens(I)), deg_bound, protocol=protocol) + I.gb = groebner_basis(IdealGens(gens(I)), deg_bound; ordering=ordering, protocol=protocol) return I.gb end -function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, deg_bound::Int=-1; protocol::Bool=false) - gb = groebner_basis(collect(g), deg_bound, protocol=protocol) +function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) + gb = groebner_basis(collect(g), deg_bound; ordering=ordering, protocol=protocol) return IdealGens(gb) end -function groebner_basis(g::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1; protocol::Bool=false) +function groebner_basis(g::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) R = parent(g[1]) @assert all(x -> parent(x) == R, g) "parent mismatch" @assert deg_bound >= 0 || !protocol "computing with a protocol requires a degree bound" @@ -175,7 +175,7 @@ function groebner_basis(g::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1; protocol return AbstractAlgebra.groebner_basis(g) end - lpring, _ = _to_lpring(R, deg_bound) + lpring, _ = _to_lpring(R, deg_bound; ordering=ordering) lp_I_gens = lpring.(g) I = Singular.Ideal(lpring, lp_I_gens) From 0e42541e4f5260c6166ad7a104b6b78c5e4c866e Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Wed, 21 Aug 2024 12:08:46 +0200 Subject: [PATCH 02/17] added ordering support, as well as minor changes, plus some tests --- src/Rings/FreeAssAlgIdeal.jl | 100 ++++++++++++++++++++++++++-------- src/exports.jl | 1 + src/imports.jl | 1 + test/Rings/FreeAssAlgIdeal.jl | 43 +++++++++++++-- 4 files changed, 115 insertions(+), 30 deletions(-) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index cfe9f65ebffd..e93092ceab24 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -17,18 +17,23 @@ Two-sided ideal of a free associative algebra with elements of type `T`. mutable struct FreeAssAlgIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} - - function FreeAssAlgIdeal(R::FreeAssAlgebra, g::Vector{T}) where T <: FreeAssAlgElem + deg_bound::Int + function FreeAssAlgIdeal(g::IdealGens{T}) where T <: FreeAssAlgElem r = new{T}() - r.gens = IdealGens(R, g) + r.gens = g + if base_ring(base_ring(g)) isa Field && is_groebner_basis(g) + r.gb = g + r.deg_bound = -1 + end return r end end -function AbstractAlgebra.expressify(a::FreeAssAlgIdeal; context = nothing) - return Expr(:call, :ideal, [expressify(g, context = context) for g in collect(a.gens)]...) +Base.show(io::IO, a::FreeAssAlgIdeal) = print(io, "Ideal of ", base_ring(a), " with ", number_of_generators(a), " generators") + +function Base.:(==)(I2::FreeAssAlgIdeal, I1::FreeAssAlgIdeal) + return I1 in I2 && I2 in I1 end -@enable_all_show_via_expressify FreeAssAlgIdeal @doc raw""" ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) @@ -37,16 +42,20 @@ Return the two-sided ideal of $R$ generated by $g$. """ function ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) @assert all(x -> parent(x) == R, g) "parent mismatch" - return FreeAssAlgIdeal(R, g) + return FreeAssAlgIdeal(IdealGens(R, g)) end function ideal(g::Vector{<:FreeAssAlgElem}) @assert length(g) > 0 "cannot infer base ring" algebra = parent(g[1]) return ideal(algebra, g) +end +function ideal(g::IdealGens{T}) where T <: FreeAssAlgElem + return FreeAssAlgIdeal(g) end + function base_ring(I::FreeAssAlgIdeal{T}) where T return I.gens.Ox::parent_type(T) end @@ -79,6 +88,9 @@ function Base.:*(a::FreeAssAlgIdeal{T}, b::FreeAssAlgIdeal{T}) where T return ideal(R, [i*j for i in gens(a) for j in gens(b)]) end +AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::FreeAssAlgIdeal) = normal_form(f, gens(I)) +AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::IdealGens{<:FreeAssAlgElem}) = normal_form(f, collect(I)) + @doc raw""" ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int) @@ -98,7 +110,9 @@ true ``` """ function ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int=-1) - return ideal_membership(a, IdealGens(gens(I)), deg_bound) + isdefined(I, :gb) && (I.deg_bound == -1 || I.deg_bound >= deg_bound) && return iszero(normal_form(a, I.gb)) + groebner_basis(I, deg_bound) + return ideal_membership(a, I, deg_bound) end function ideal_membership(a::FreeAssAlgElem, I::IdealGens{<:FreeAssAlgElem}, deg_bound::Int=-1) return ideal_membership(a, collect(I), deg_bound) @@ -106,16 +120,16 @@ end function ideal_membership(a::FreeAssAlgElem, I::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1) R = parent(a) @assert all(x -> parent(x) == R, I) "parent mismatch" - gb = groebner_basis(I, deg_bound; protocol=false) - deg_bound = max(maximum(total_degree.(gb)),total_degree(a)) - lpring, _ = _to_lpring(R, deg_bound) + gb = groebner_basis(I, deg_bound) + return iszero(normal_form(a, gb)) +end - lp_I = Singular.Ideal(lpring, lpring.(gb)) - return iszero(reduce(lpring(a), lp_I)) +function Base.in(a::FreeAssAlgElem, I::FreeAssAlgIdeal) + return ideal_membership(a, I) end -function Base.in(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int) - return ideal_membership(a, I, deg_bound) +function Base.in(I1, I2::FreeAssAlgIdeal) + return all(x -> in(x, I2), gens(I1)) end function (R::Singular.LPRing)(a::FreeAssAlgElem) @@ -134,7 +148,7 @@ function (A::FreeAssAlgebra)(a::Singular.slpalg) return finish(B) end -_to_lpring(a::FreeAssAlgebra, deg_bound::Int; ordering::Symbol=:degrevlex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) +_to_lpring(a::FreeAssAlgebra, deg_bound::Int; ordering::Symbol=:deglex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) @doc raw""" groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; protocol::Bool=false) @@ -161,22 +175,38 @@ Ideal generating system with elements 4 -> y^2*x + y*z*y ``` """ -function groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) - isdefined(I, :gb) && return I.gb - I.gb = groebner_basis(IdealGens(gens(I)), deg_bound; ordering=ordering, protocol=protocol) +function groebner_basis(I::FreeAssAlgIdeal, + deg_bound::Int=-1; + protocol::Bool=false, + interreduce::Bool=false) + isdefined(I, :gb) && (I.deg_bound == -1 || I.deg_bound >= deg_bound) && return I.gb + I.gb = groebner_basis(IdealGens(gens(I)), deg_bound; ordering=:deglex, protocol=protocol, interreduce=interreduce) + I.deg_bound = deg_bound return I.gb end -function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) - gb = groebner_basis(collect(g), deg_bound; ordering=ordering, protocol=protocol) +function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, + deg_bound::Int=-1; + ordering::Symbol=:deglex, + protocol::Bool=false, + interreduce::Bool=false) + gb = groebner_basis(collect(g), deg_bound; ordering=ordering, protocol=protocol, interreduce=interreduce) return IdealGens(gb) end -function groebner_basis(g::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1; ordering::Symbol=:degrevlex, protocol::Bool=false) +function groebner_basis(g::Vector{<:FreeAssAlgElem}, + deg_bound::Int=-1; + ordering::Symbol=:deglex, + protocol::Bool=false, + interreduce::Bool=false) + R = parent(g[1]) @assert all(x -> parent(x) == R, g) "parent mismatch" @assert deg_bound >= 0 || !protocol "computing with a protocol requires a degree bound" + @assert ordering == :deglex || deg_bound > 0 "only :deglex ordering is supported for no degree bound" if deg_bound == -1 - return AbstractAlgebra.groebner_basis(g) + gb = AbstractAlgebra.groebner_basis(g) + interreduce && return interreduce!(gb) + return gb end lpring, _ = _to_lpring(R, deg_bound; ordering=ordering) @@ -188,5 +218,27 @@ function groebner_basis(g::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1; ordering Singular.with_prot(protocol) do; gb = gens(Singular.std(I)) end - return R.(gb) + gb = R.(gb) + interreduce && return interreduce!(gb) + return gb +end + +is_groebner_basis(g::IdealGens{<:FreeAssAlgElem}) = is_groebner_basis(collect(g)) + +function is_groebner_basis(gb::Vector{<:FreeAssAlgElem}) + obsructions = AbstractAlgebra.Generic.get_obstructions(gb) + while !isempty(obsructions) + f = AbstractAlgebra.Generic.s_polynomial(popfirst!(obsructions)[1]) + iszero(normal_form(f, gb)) || return false + end + return true +end + + +function interreduce!(I::FreeAssAlgIdeal) + I.gb = interreduce!(I.gb) + return I +end +function interreduce!(gb::IdealGens{<:FreeAssAlgElem}) + return IdealGens(interreduce!(collect(gb))) end diff --git a/src/exports.jl b/src/exports.jl index af15915697df..386f0ce2e07e 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -703,6 +703,7 @@ export inradical export integral_basis export integrate export interior_lattice_points +export interreduce! export intersect export intersection_form export intersection_multiplicity diff --git a/src/imports.jl b/src/imports.jl index a0c09fbf2144..d7e8251a76f3 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -75,6 +75,7 @@ import AbstractAlgebra: gen, Generic, Generic.finish, + Generic.interreduce!, Generic.MPolyBuildCtx, Generic.MPolyCoeffs, Generic.MPolyExponentVectors, diff --git a/test/Rings/FreeAssAlgIdeal.jl b/test/Rings/FreeAssAlgIdeal.jl index c07a431e9490..f0869d8013ff 100644 --- a/test/Rings/FreeAssAlgIdeal.jl +++ b/test/Rings/FreeAssAlgIdeal.jl @@ -17,17 +17,16 @@ end @testset "FreeAssAlgIdeal.membership" begin R, (x, y, z) = free_associative_algebra(QQ, ["x", "y", "z"]) I = ideal(R, [x*y - y*x, x*z - z*x]) - @test !in(x, I, 5) - @test !in(x, I, 10) - @test in(x*y*z - y*z*x, I, 9) # 9 should be enough + @test !ideal_membership(x, I, 5) + @test !ideal_membership(x, I, 10) + @test ideal_membership(x*y*z - y*z*x, I, 9) # 9 should be enough f1 = x*y + y*z I2 = ideal([f1]) @test !ideal_membership(x*y, I2, 3) @test ideal_membership(f1, I2, 4) @test ideal_membership(f1, I2) - @test !isdefined(I2, :gb) - gb = groebner_basis(I2, 3; protocol=true) + gb = groebner_basis(I2, 3; protocol=false) @test isdefined(I2, :gb) end @@ -56,9 +55,41 @@ end f2 = x^2 + y^2 I = ideal([f1, f2]) - gb = groebner_basis(I, 3; protocol=true) + gb = groebner_basis(I, 3; protocol=false) @test maximum(total_degree.(gb))==3 @test isdefined(I, :gb) gb2 = groebner_basis([f1, f2], 5; protocol=false) @test maximum(total_degree.(gb2))==5 end + +@testset "FreeAssAlgIdeal.groebner_basis.quantum_automorphism_group" begin + M = uniform_matroid(3,4) + qAut1 = gens(quantum_automorphism_group(M)) + gb1 = groebner_basis(qAut1; interreduce=true) + gb2 = groebner_basis(qAut1, 4,ordering=:deglex,interreduce=true) + @test sort(leading_monomial.(gb2)) == sort(leading_monomial.(gb1)) + @test is_groebner_basis(gb1) + @test is_groebner_basis(gb2) + I1 = ideal(gb1); I2 = ideal(gb2) + @test I1 == I2 + + qAut2 = quantum_symmetric_group(4) + gena = gens(qAut2) + + gb3 = groebner_basis(gena; interreduce=true) + + gb4 = groebner_basis(gena, 4,ordering=:deglex,interreduce=true) + @test is_groebner_basis(gb3) + @test is_groebner_basis(gb4) + @test sort(leading_monomial.(gb3)) == sort(leading_monomial.(gb4)) + + I1 = ideal(gb3); I2 = ideal(gb4) + @test I1 == I2 + + x = base_ring(I1)[1]; y = base_ring(I1)[7] + @test !(x*y - y*x in I1) + + gb5 = groebner_basis(gens(quantum_symmetric_group(3)); interreduce=true) + x = base_ring(ideal(gb5))[1]; y = base_ring(ideal(gb5))[7] + @test x*y - y*x in ideal(gb5) +end From 217c9d22710dc696cf9117bd3958c05812bbf933 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Wed, 21 Aug 2024 12:34:59 +0200 Subject: [PATCH 03/17] in to is_subset --- src/Rings/FreeAssAlgIdeal.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index e93092ceab24..0a111188d0d2 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -32,7 +32,7 @@ end Base.show(io::IO, a::FreeAssAlgIdeal) = print(io, "Ideal of ", base_ring(a), " with ", number_of_generators(a), " generators") function Base.:(==)(I2::FreeAssAlgIdeal, I1::FreeAssAlgIdeal) - return I1 in I2 && I2 in I1 + return is_subset(I1,I2) && is_subset(I2,I1) end @doc raw""" @@ -128,7 +128,7 @@ function Base.in(a::FreeAssAlgElem, I::FreeAssAlgIdeal) return ideal_membership(a, I) end -function Base.in(I1, I2::FreeAssAlgIdeal) +function is_subset(I1::FreeAssAlgIdeal, I2::FreeAssAlgIdeal) return all(x -> in(x, I2), gens(I1)) end From fd814e782021436829eed1a78eab5fd7d896fe44 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Wed, 21 Aug 2024 14:15:37 +0200 Subject: [PATCH 04/17] fixed the slowdown caused by is_groebner_basis (The function is still slow). --- src/Rings/FreeAssAlgIdeal.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index 0a111188d0d2..81f86582557b 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -18,10 +18,11 @@ mutable struct FreeAssAlgIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} deg_bound::Int - function FreeAssAlgIdeal(g::IdealGens{T}) where T <: FreeAssAlgElem + function FreeAssAlgIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem r = new{T}() r.gens = g - if base_ring(base_ring(g)) isa Field && is_groebner_basis(g) + @req !check_groebner_basis || base_ring(base_ring(g)) isa Field "Groebner basis check requires a field base ring" + if check_groebner_basis && base_ring(base_ring(g)) isa Field && is_groebner_basis(g) r.gb = g r.deg_bound = -1 end From aa4d7c77fd6f7204b61cba8991b5e332fc384d26 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Wed, 21 Aug 2024 15:33:48 +0200 Subject: [PATCH 05/17] improving codecov --- src/Rings/FreeAssAlgIdeal.jl | 4 ++-- test/Rings/FreeAssAlgIdeal.jl | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index 81f86582557b..855d949def74 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -52,8 +52,8 @@ function ideal(g::Vector{<:FreeAssAlgElem}) return ideal(algebra, g) end -function ideal(g::IdealGens{T}) where T <: FreeAssAlgElem - return FreeAssAlgIdeal(g) +function ideal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem + return FreeAssAlgIdeal(g, check_groebner_basis) end diff --git a/test/Rings/FreeAssAlgIdeal.jl b/test/Rings/FreeAssAlgIdeal.jl index f0869d8013ff..f094665b58f8 100644 --- a/test/Rings/FreeAssAlgIdeal.jl +++ b/test/Rings/FreeAssAlgIdeal.jl @@ -28,11 +28,13 @@ end @test ideal_membership(f1, I2) gb = groebner_basis(I2, 3; protocol=false) @test isdefined(I2, :gb) + @test length(gens(I * I2)) == 2 end @testset "FreeAssAlgIdeal.utils" begin R, (x, y, z) = free_associative_algebra(QQ, ["x", "y", "z"]) - I = Oscar.ideal(R, [x*y - y*x, x*z - z*x]) + I = ideal(R, [x*y - y*x, x*z - z*x]) + @test base_ring(I) == R @test isa(ngens(I),Int) @test isequal(ngens(I),2) @test isa(gen(I,ngens(I)),FreeAssAlgElem{QQFieldElem}) @@ -56,10 +58,12 @@ end I = ideal([f1, f2]) gb = groebner_basis(I, 3; protocol=false) + @test !is_groebner_basis(gb) @test maximum(total_degree.(gb))==3 @test isdefined(I, :gb) gb2 = groebner_basis([f1, f2], 5; protocol=false) @test maximum(total_degree.(gb2))==5 + @test !is_groebner_basis(gb2) end @testset "FreeAssAlgIdeal.groebner_basis.quantum_automorphism_group" begin @@ -76,7 +80,10 @@ end qAut2 = quantum_symmetric_group(4) gena = gens(qAut2) - gb3 = groebner_basis(gena; interreduce=true) + gb3 = groebner_basis(gena; interreduce=false) + @test length(gb3) == 146 + interreduce!(gb3) + @test length(gb3) == 78 gb4 = groebner_basis(gena, 4,ordering=:deglex,interreduce=true) @test is_groebner_basis(gb3) @@ -84,12 +91,18 @@ end @test sort(leading_monomial.(gb3)) == sort(leading_monomial.(gb4)) I1 = ideal(gb3); I2 = ideal(gb4) + @test gb4[end] in I1 + @test normal_form(gb4[end],I1) == 0 @test I1 == I2 x = base_ring(I1)[1]; y = base_ring(I1)[7] @test !(x*y - y*x in I1) gb5 = groebner_basis(gens(quantum_symmetric_group(3)); interreduce=true) + A = parent(gb5[1]) + I3 = ideal(Oscar.IdealGens(A, gb5),true) + @test is_groebner_basis(I3.gens) + x = base_ring(ideal(gb5))[1]; y = base_ring(ideal(gb5))[7] @test x*y - y*x in ideal(gb5) end From 5fa7b08becb09326bf9b0806e06b2ebc9219dfc9 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 22 Aug 2024 10:14:15 +0200 Subject: [PATCH 06/17] even more tests for coverage --- test/Rings/FreeAssAlgIdeal.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/Rings/FreeAssAlgIdeal.jl b/test/Rings/FreeAssAlgIdeal.jl index f094665b58f8..c45b935d1c28 100644 --- a/test/Rings/FreeAssAlgIdeal.jl +++ b/test/Rings/FreeAssAlgIdeal.jl @@ -25,7 +25,9 @@ end I2 = ideal([f1]) @test !ideal_membership(x*y, I2, 3) @test ideal_membership(f1, I2, 4) + @test ideal_membership(f1, I2.gens, 4) @test ideal_membership(f1, I2) + @test ideal_membership(f1, I2.gens) gb = groebner_basis(I2, 3; protocol=false) @test isdefined(I2, :gb) @test length(gens(I * I2)) == 2 @@ -81,10 +83,16 @@ end gena = gens(qAut2) gb3 = groebner_basis(gena; interreduce=false) + I1 = ideal(copy(gb3)) + groebner_basis(I1) @test length(gb3) == 146 interreduce!(gb3) + @test length(I1.gb) == 146 + interreduce!(I1) + @test length(I1.gb) == 78 @test length(gb3) == 78 + gb4 = groebner_basis(gena, 4,ordering=:deglex,interreduce=true) @test is_groebner_basis(gb3) @test is_groebner_basis(gb4) From ed1643f30a0d4bda786a26fad33adf9097058149 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Tue, 27 Aug 2024 09:44:18 +0200 Subject: [PATCH 07/17] added Lars suggestion for hash function --- src/Rings/FreeAssAlgIdeal.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssAlgIdeal.jl index 855d949def74..d96461eb5e72 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssAlgIdeal.jl @@ -36,6 +36,10 @@ function Base.:(==)(I2::FreeAssAlgIdeal, I1::FreeAssAlgIdeal) return is_subset(I1,I2) && is_subset(I2,I1) end +function Base.hash(a::FreeAssAlgIdeal, h::UInt) + return hash(base_ring(a), h) +end + @doc raw""" ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) From 5532ef1329cc2f3f655c9c864aa1a4186a235d71 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 15:14:00 +0200 Subject: [PATCH 08/17] `FreeAssAlgIdeal` -> `FreeAssociativeAlgebraIdeal` --- .../free_associative_algebra.md | 6 +-- ...deal.jl => FreeAssociativeAlgebraIdeal.jl} | 46 +++++++++---------- src/Rings/Rings.jl | 2 +- src/Serialization/Algebras.jl | 2 +- src/Serialization/Rings.jl | 2 +- src/deprecations.jl | 3 ++ ...deal.jl => FreeAssociativeAlgebraIdeal.jl} | 12 ++--- 7 files changed, 38 insertions(+), 35 deletions(-) rename src/Rings/{FreeAssAlgIdeal.jl => FreeAssociativeAlgebraIdeal.jl} (78%) rename test/Rings/{FreeAssAlgIdeal.jl => FreeAssociativeAlgebraIdeal.jl} (89%) diff --git a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md index 36b32886a245..eecdd8a30056 100644 --- a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md +++ b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md @@ -9,7 +9,7 @@ CurrentModule = Oscar ### Types The OSCAR type for two-sided ideals in a free associative algebra is -`FreeAssAlgIdeal{T}`, where `T` is the element type of the algebra. +`FreeAssociativeAlgebraIdeal{T}`, where `T` is the element type of the algebra. ### Constructors @@ -25,11 +25,11 @@ Non-commutative polynomial rings are not Noetherian. Hence, in general, Groebne Setting the parameter `deg_bound` to a positive value yields the truncation of the Groebner bases to a fixed degree. Such a truncation is always finite. ```@docs -groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; protocol::Bool=false) +groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false) ``` If a finite Gröbner basis exists, it solves the ideal membership problem. ```@docs -ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int) +ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) ``` diff --git a/src/Rings/FreeAssAlgIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl similarity index 78% rename from src/Rings/FreeAssAlgIdeal.jl rename to src/Rings/FreeAssociativeAlgebraIdeal.jl index d96461eb5e72..f0a3876212ef 100644 --- a/src/Rings/FreeAssAlgIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -10,15 +10,15 @@ # necessarily be confined to a degree bound. @doc raw""" - mutable struct FreeAssAlgIdeal{T} + mutable struct FreeAssociativeAlgebraIdeal{T} Two-sided ideal of a free associative algebra with elements of type `T`. """ -mutable struct FreeAssAlgIdeal{T} <: Ideal{T} +mutable struct FreeAssociativeAlgebraIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} deg_bound::Int - function FreeAssAlgIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem + function FreeAssociativeAlgebraIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem r = new{T}() r.gens = g @req !check_groebner_basis || base_ring(base_ring(g)) isa Field "Groebner basis check requires a field base ring" @@ -30,13 +30,13 @@ mutable struct FreeAssAlgIdeal{T} <: Ideal{T} end end -Base.show(io::IO, a::FreeAssAlgIdeal) = print(io, "Ideal of ", base_ring(a), " with ", number_of_generators(a), " generators") +Base.show(io::IO, a::FreeAssociativeAlgebraIdeal) = print(io, "Ideal of ", base_ring(a), " with ", number_of_generators(a), " generators") -function Base.:(==)(I2::FreeAssAlgIdeal, I1::FreeAssAlgIdeal) +function Base.:(==)(I2::FreeAssociativeAlgebraIdeal, I1::FreeAssociativeAlgebraIdeal) return is_subset(I1,I2) && is_subset(I2,I1) end -function Base.hash(a::FreeAssAlgIdeal, h::UInt) +function Base.hash(a::FreeAssociativeAlgebraIdeal, h::UInt) return hash(base_ring(a), h) end @@ -47,7 +47,7 @@ Return the two-sided ideal of $R$ generated by $g$. """ function ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) @assert all(x -> parent(x) == R, g) "parent mismatch" - return FreeAssAlgIdeal(IdealGens(R, g)) + return FreeAssociativeAlgebraIdeal(IdealGens(R, g)) end function ideal(g::Vector{<:FreeAssAlgElem}) @@ -57,47 +57,47 @@ function ideal(g::Vector{<:FreeAssAlgElem}) end function ideal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem - return FreeAssAlgIdeal(g, check_groebner_basis) + return FreeAssociativeAlgebraIdeal(g, check_groebner_basis) end -function base_ring(I::FreeAssAlgIdeal{T}) where T +function base_ring(I::FreeAssociativeAlgebraIdeal{T}) where T return I.gens.Ox::parent_type(T) end -function base_ring_type(::Type{<:FreeAssAlgIdeal{T}}) where T +function base_ring_type(::Type{<:FreeAssociativeAlgebraIdeal{T}}) where T return parent_type(T) end -function number_of_generators(a::FreeAssAlgIdeal) +function number_of_generators(a::FreeAssociativeAlgebraIdeal) return length(a.gens) end -function gen(a::FreeAssAlgIdeal{T}, i::Int) where T +function gen(a::FreeAssociativeAlgebraIdeal{T}, i::Int) where T return a.gens[Val(:O), i] end -function gens(a::FreeAssAlgIdeal{T}) where T +function gens(a::FreeAssociativeAlgebraIdeal{T}) where T return T[gen(a,i) for i in 1:ngens(a)] end -function Base.:+(a::FreeAssAlgIdeal{T}, b::FreeAssAlgIdeal{T}) where T +function Base.:+(a::FreeAssociativeAlgebraIdeal{T}, b::FreeAssociativeAlgebraIdeal{T}) where T R = base_ring(a) @assert R == base_ring(b) "parent mismatch" return ideal(R, vcat(gens(a), gens(b))) end -function Base.:*(a::FreeAssAlgIdeal{T}, b::FreeAssAlgIdeal{T}) where T +function Base.:*(a::FreeAssociativeAlgebraIdeal{T}, b::FreeAssociativeAlgebraIdeal{T}) where T R = base_ring(a) @assert R == base_ring(b) "parent mismatch" return ideal(R, [i*j for i in gens(a) for j in gens(b)]) end -AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::FreeAssAlgIdeal) = normal_form(f, gens(I)) +AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal) = normal_form(f, gens(I)) AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::IdealGens{<:FreeAssAlgElem}) = normal_form(f, collect(I)) @doc raw""" - ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int) + ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) Returns `true` if intermediate degree calculations bounded by `deg_bound` prove that $a$ is in $I$. Otherwise, returning `false` indicates an inconclusive answer, but larger `deg_bound`s give more confidence in a negative answer. @@ -114,7 +114,7 @@ julia> ideal_membership(f1, I, 4) true ``` """ -function ideal_membership(a::FreeAssAlgElem, I::FreeAssAlgIdeal, deg_bound::Int=-1) +function ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1) isdefined(I, :gb) && (I.deg_bound == -1 || I.deg_bound >= deg_bound) && return iszero(normal_form(a, I.gb)) groebner_basis(I, deg_bound) return ideal_membership(a, I, deg_bound) @@ -129,11 +129,11 @@ function ideal_membership(a::FreeAssAlgElem, I::Vector{<:FreeAssAlgElem}, deg_bo return iszero(normal_form(a, gb)) end -function Base.in(a::FreeAssAlgElem, I::FreeAssAlgIdeal) +function Base.in(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal) return ideal_membership(a, I) end -function is_subset(I1::FreeAssAlgIdeal, I2::FreeAssAlgIdeal) +function is_subset(I1::FreeAssociativeAlgebraIdeal, I2::FreeAssociativeAlgebraIdeal) return all(x -> in(x, I2), gens(I1)) end @@ -156,7 +156,7 @@ end _to_lpring(a::FreeAssAlgebra, deg_bound::Int; ordering::Symbol=:deglex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) @doc raw""" - groebner_basis(I::FreeAssAlgIdeal, deg_bound::Int=-1; protocol::Bool=false) + groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false) Return the Groebner basis of `I` with respect to the degree bound `deg_bound`. If `protocol` is `true`, the protocol of the computation is also returned. @@ -180,7 +180,7 @@ Ideal generating system with elements 4 -> y^2*x + y*z*y ``` """ -function groebner_basis(I::FreeAssAlgIdeal, +function groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false, interreduce::Bool=false) @@ -240,7 +240,7 @@ function is_groebner_basis(gb::Vector{<:FreeAssAlgElem}) end -function interreduce!(I::FreeAssAlgIdeal) +function interreduce!(I::FreeAssociativeAlgebraIdeal) I.gb = interreduce!(I.gb) return I end diff --git a/src/Rings/Rings.jl b/src/Rings/Rings.jl index 15838de1fe2f..7ec21f35cf30 100644 --- a/src/Rings/Rings.jl +++ b/src/Rings/Rings.jl @@ -34,7 +34,7 @@ include("binomial_ideals.jl") include("PBWAlgebra.jl") include("PBWAlgebraQuo.jl") -include("FreeAssAlgIdeal.jl") +include("FreeAssociativeAlgebraIdeal.jl") include("hilbert.jl") include("primary_decomposition_helpers.jl") include("resultant.jl") diff --git a/src/Serialization/Algebras.jl b/src/Serialization/Algebras.jl index b8f0b95d305e..c9023e8e0f29 100644 --- a/src/Serialization/Algebras.jl +++ b/src/Serialization/Algebras.jl @@ -53,4 +53,4 @@ function load_object(s::DeserializerState, ::Type{<:FreeAssAlgElem}, parents::Ve end # Ideals -@register_serialization_type FreeAssAlgIdeal uses_params +@register_serialization_type FreeAssociativeAlgebraIdeal uses_params diff --git a/src/Serialization/Rings.jl b/src/Serialization/Rings.jl index 7637c2804e15..1ce86ed6d19d 100644 --- a/src/Serialization/Rings.jl +++ b/src/Serialization/Rings.jl @@ -292,7 +292,7 @@ end # way to abstract saving params soon const IdealOrdUnionType = Union{MPolyIdeal, LaurentMPolyIdeal, - FreeAssAlgIdeal, + FreeAssociativeAlgebraIdeal, IdealGens, MonomialOrdering} diff --git a/src/deprecations.jl b/src/deprecations.jl index 2f577d91222a..fb2d27a26d9a 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -136,3 +136,6 @@ Base.@deprecate_binding MPolyRingElemLoc MPolyLocRingElem # deprecated for 1.2 Base.@deprecate_binding QQAbElem QQAbFieldElem + +Base.@deprecate_binding FreeAssAlgIdeal FreeAssociativeAlgebraIdeal + diff --git a/test/Rings/FreeAssAlgIdeal.jl b/test/Rings/FreeAssociativeAlgebraIdeal.jl similarity index 89% rename from test/Rings/FreeAssAlgIdeal.jl rename to test/Rings/FreeAssociativeAlgebraIdeal.jl index c45b935d1c28..5a55e6953412 100644 --- a/test/Rings/FreeAssAlgIdeal.jl +++ b/test/Rings/FreeAssociativeAlgebraIdeal.jl @@ -1,4 +1,4 @@ -@testset "FreeAssAlgIdeal.basic" begin +@testset "FreeAssociativeAlgebraIdeal.basic" begin Zt = polynomial_ring(ZZ, "t")[1] R, (x, y, z) = free_associative_algebra(Zt, ["x", "y", "z", "w"]) I = ideal(R, [x*y*x, y*z^2]) @@ -8,13 +8,13 @@ end end -@testset "FreeAssAlgIdeal.printing" begin +@testset "FreeAssociativeAlgebraIdeal.printing" begin R, (x, y, z) = free_associative_algebra(GF(5), ["x", "y", "z", "w"]) I = ideal(R, [x*y*x, y*z^2]) @test length(string(I)) > 3 end -@testset "FreeAssAlgIdeal.membership" begin +@testset "FreeAssociativeAlgebraIdeal.membership" begin R, (x, y, z) = free_associative_algebra(QQ, ["x", "y", "z"]) I = ideal(R, [x*y - y*x, x*z - z*x]) @test !ideal_membership(x, I, 5) @@ -33,7 +33,7 @@ end @test length(gens(I * I2)) == 2 end -@testset "FreeAssAlgIdeal.utils" begin +@testset "FreeAssociativeAlgebraIdeal.utils" begin R, (x, y, z) = free_associative_algebra(QQ, ["x", "y", "z"]) I = ideal(R, [x*y - y*x, x*z - z*x]) @test base_ring(I) == R @@ -53,7 +53,7 @@ end @test isa(F1,FreeAssAlgElem) end -@testset "FreeAssAlgIdeal.groebner_basis" begin +@testset "FreeAssociativeAlgebraIdeal.groebner_basis" begin free, (x,y,z) = free_associative_algebra(QQ, ["x", "y", "z"]) f1 = x*y + y*z f2 = x^2 + y^2 @@ -68,7 +68,7 @@ end @test !is_groebner_basis(gb2) end -@testset "FreeAssAlgIdeal.groebner_basis.quantum_automorphism_group" begin +@testset "FreeAssociativeAlgebraIdeal.groebner_basis.quantum_automorphism_group" begin M = uniform_matroid(3,4) qAut1 = gens(quantum_automorphism_group(M)) gb1 = groebner_basis(qAut1; interreduce=true) From b02dec03403005c7829596fdc661905074c147f2 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 15:24:37 +0200 Subject: [PATCH 09/17] update AbstractAlgebra and rename FreeAssAlgebra - Updated AbstractAlgebra version from 0.42.0 to 0.42.3 in Project.toml - `FreeAssAlgebra` -> `FreeAssociativeAlgebra` --- Project.toml | 2 +- .../src/NoncommutativeAlgebra/free_associative_algebra.md | 2 +- src/Rings/FreeAssociativeAlgebraIdeal.jl | 8 ++++---- src/Serialization/Algebras.jl | 8 ++++---- src/Serialization/Rings.jl | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Project.toml b/Project.toml index c59cf4839421..61bfb6f67c55 100644 --- a/Project.toml +++ b/Project.toml @@ -25,7 +25,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" cohomCalg_jll = "5558cf25-a90e-53b0-b813-cadaa3ae7ade" [compat] -AbstractAlgebra = "0.42.0" +AbstractAlgebra = "0.42.3" AlgebraicSolving = "0.5.1" Distributed = "1.6" GAP = "0.10.2" diff --git a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md index eecdd8a30056..998b960603fb 100644 --- a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md +++ b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md @@ -14,7 +14,7 @@ The OSCAR type for two-sided ideals in a free associative algebra is ### Constructors ```julia -ideal(R::FreeAssAlgebra, g::Vector{T}) where T <: FreeAssAlgElem +ideal(R::FreeAssociativeAlgebra, g::Vector{T}) where T <: FreeAssAlgElem ideal(g::Vector{T}) where T <: FreeAssAlgElem ``` diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index f0a3876212ef..a641ed458fed 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -41,11 +41,11 @@ function Base.hash(a::FreeAssociativeAlgebraIdeal, h::UInt) end @doc raw""" - ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) + ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssAlgElem}) Return the two-sided ideal of $R$ generated by $g$. """ -function ideal(R::FreeAssAlgebra, g::Vector{<:FreeAssAlgElem}) +function ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssAlgElem}) @assert all(x -> parent(x) == R, g) "parent mismatch" return FreeAssociativeAlgebraIdeal(IdealGens(R, g)) end @@ -145,7 +145,7 @@ function (R::Singular.LPRing)(a::FreeAssAlgElem) return finish(B) end -function (A::FreeAssAlgebra)(a::Singular.slpalg) +function (A::FreeAssociativeAlgebra)(a::Singular.slpalg) B = MPolyBuildCtx(A) for (c,e) in zip(Oscar.coefficients(a), Singular.exponent_words(a)) push_term!(B, base_ring(A)(c), e) @@ -153,7 +153,7 @@ function (A::FreeAssAlgebra)(a::Singular.slpalg) return finish(B) end -_to_lpring(a::FreeAssAlgebra, deg_bound::Int; ordering::Symbol=:deglex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) +_to_lpring(a::FreeAssociativeAlgebra, deg_bound::Int; ordering::Symbol=:deglex) = Singular.FreeAlgebra(base_ring(a), String.(symbols(a)), deg_bound; ordering=ordering) @doc raw""" groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool=false) diff --git a/src/Serialization/Algebras.jl b/src/Serialization/Algebras.jl index c9023e8e0f29..fb5c18f8cebe 100644 --- a/src/Serialization/Algebras.jl +++ b/src/Serialization/Algebras.jl @@ -1,17 +1,17 @@ ################################################################################ -# FreeAssAlgebra +# FreeAssociativeAlgebra # Free associative algebra serialization -@register_serialization_type FreeAssAlgebra uses_id +@register_serialization_type FreeAssociativeAlgebra uses_id -function save_object(s::SerializerState, A::FreeAssAlgebra) +function save_object(s::SerializerState, A::FreeAssociativeAlgebra) save_data_dict(s) do save_typed_object(s, base_ring(A), :base_ring), save_object(s, symbols(A), :symbols) end end -function load_object(s::DeserializerState, ::Type{<:FreeAssAlgebra}) +function load_object(s::DeserializerState, ::Type{<:FreeAssociativeAlgebra}) R = load_typed_object(s, :base_ring) gens = load_object(s, Vector{Symbol}, :symbols) return free_associative_algebra(R, gens)[1] diff --git a/src/Serialization/Rings.jl b/src/Serialization/Rings.jl index 1ce86ed6d19d..5b05fdeb8f5f 100644 --- a/src/Serialization/Rings.jl +++ b/src/Serialization/Rings.jl @@ -5,7 +5,7 @@ const RingMatElemUnion = Union{RingElem, MatElem, FreeAssAlgElem, SMat} # this union will also need a better name at some point -const RingMatSpaceUnion = Union{Ring, MatSpace, SMatSpace, FreeAssAlgebra} +const RingMatSpaceUnion = Union{Ring, MatSpace, SMatSpace, FreeAssociativeAlgebra} ################################################################################ # Utility functions for ring parent tree From f95b0b2b0b459644a2635e7c956129d4dd7a1322 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 15:35:08 +0200 Subject: [PATCH 10/17] `FreeAssAlgElem` -> `FreeAssociativeAlgebraElem` --- .../free_associative_algebra.md | 6 ++-- src/Groups/action.jl | 8 ++--- src/Rings/FreeAssociativeAlgebraIdeal.jl | 36 +++++++++---------- src/Serialization/Algebras.jl | 6 ++-- src/Serialization/Rings.jl | 2 +- test/Rings/FreeAssociativeAlgebraIdeal.jl | 4 +-- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md index 998b960603fb..9f3b8dc80179 100644 --- a/docs/src/NoncommutativeAlgebra/free_associative_algebra.md +++ b/docs/src/NoncommutativeAlgebra/free_associative_algebra.md @@ -14,8 +14,8 @@ The OSCAR type for two-sided ideals in a free associative algebra is ### Constructors ```julia -ideal(R::FreeAssociativeAlgebra, g::Vector{T}) where T <: FreeAssAlgElem -ideal(g::Vector{T}) where T <: FreeAssAlgElem +ideal(R::FreeAssociativeAlgebra, g::Vector{T}) where T <: FreeAssociativeAlgebraElem +ideal(g::Vector{T}) where T <: FreeAssociativeAlgebraElem ``` ### Ideal Membership @@ -31,5 +31,5 @@ groebner_basis(I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1; protocol::Bool If a finite Gröbner basis exists, it solves the ideal membership problem. ```@docs -ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) +ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) ``` diff --git a/src/Groups/action.jl b/src/Groups/action.jl index 0165be9256e2..37037e5d606e 100644 --- a/src/Groups/action.jl +++ b/src/Groups/action.jl @@ -256,12 +256,12 @@ end @doc raw""" on_indeterminates(f::GapObj, p::PermGroupElem) on_indeterminates(f::MPolyRingElem, p::PermGroupElem) - on_indeterminates(f::FreeAssAlgElem, p::PermGroupElem) + on_indeterminates(f::FreeAssociativeAlgebraElem, p::PermGroupElem) on_indeterminates(f::MPolyIdeal, p::PermGroupElem) Return the image of `f` under `p` where `p` acts via permuting the indeterminates. -For `MPolyRingElem`, `FreeAssAlgElem`, and `MPolyIdeal` objects, +For `MPolyRingElem`, `FreeAssociativeAlgebraElem`, and `MPolyIdeal` objects, one can also call `^` instead of `on_indeterminates`. # Examples @@ -303,7 +303,7 @@ function on_indeterminates(f::MPolyRingElem, s::PermGroupElem) return finish(g) end -function on_indeterminates(f::FreeAssAlgElem{T}, s::PermGroupElem) where T +function on_indeterminates(f::FreeAssociativeAlgebraElem{T}, s::PermGroupElem) where T G = parent(s) S = parent(f) @assert ngens(S) == degree(G) @@ -374,7 +374,7 @@ end ^(f::MPolyRingElem, p::PermGroupElem) = on_indeterminates(f, p) -^(f::FreeAssAlgElem, p::PermGroupElem) = on_indeterminates(f, p) +^(f::FreeAssociativeAlgebraElem, p::PermGroupElem) = on_indeterminates(f, p) ^(f::MPolyRingElem{T}, p::MatrixGroupElem{T, S}) where T where S = on_indeterminates(f, p) diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index a641ed458fed..7192236c60da 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -18,7 +18,7 @@ mutable struct FreeAssociativeAlgebraIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} deg_bound::Int - function FreeAssociativeAlgebraIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem + function FreeAssociativeAlgebraIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem r = new{T}() r.gens = g @req !check_groebner_basis || base_ring(base_ring(g)) isa Field "Groebner basis check requires a field base ring" @@ -41,22 +41,22 @@ function Base.hash(a::FreeAssociativeAlgebraIdeal, h::UInt) end @doc raw""" - ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssAlgElem}) + ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssociativeAlgebraElem}) Return the two-sided ideal of $R$ generated by $g$. """ -function ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssAlgElem}) +function ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssociativeAlgebraElem}) @assert all(x -> parent(x) == R, g) "parent mismatch" return FreeAssociativeAlgebraIdeal(IdealGens(R, g)) end -function ideal(g::Vector{<:FreeAssAlgElem}) +function ideal(g::Vector{<:FreeAssociativeAlgebraElem}) @assert length(g) > 0 "cannot infer base ring" algebra = parent(g[1]) return ideal(algebra, g) end -function ideal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssAlgElem +function ideal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem return FreeAssociativeAlgebraIdeal(g, check_groebner_basis) end @@ -93,11 +93,11 @@ function Base.:*(a::FreeAssociativeAlgebraIdeal{T}, b::FreeAssociativeAlgebraIde return ideal(R, [i*j for i in gens(a) for j in gens(b)]) end -AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal) = normal_form(f, gens(I)) -AbstractAlgebra.normal_form(f::FreeAssAlgElem, I::IdealGens{<:FreeAssAlgElem}) = normal_form(f, collect(I)) +AbstractAlgebra.normal_form(f::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal) = normal_form(f, gens(I)) +AbstractAlgebra.normal_form(f::FreeAssociativeAlgebraElem, I::IdealGens{<:FreeAssociativeAlgebraElem}) = normal_form(f, collect(I)) @doc raw""" - ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) + ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int) Returns `true` if intermediate degree calculations bounded by `deg_bound` prove that $a$ is in $I$. Otherwise, returning `false` indicates an inconclusive answer, but larger `deg_bound`s give more confidence in a negative answer. @@ -114,22 +114,22 @@ julia> ideal_membership(f1, I, 4) true ``` """ -function ideal_membership(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1) +function ideal_membership(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal, deg_bound::Int=-1) isdefined(I, :gb) && (I.deg_bound == -1 || I.deg_bound >= deg_bound) && return iszero(normal_form(a, I.gb)) groebner_basis(I, deg_bound) return ideal_membership(a, I, deg_bound) end -function ideal_membership(a::FreeAssAlgElem, I::IdealGens{<:FreeAssAlgElem}, deg_bound::Int=-1) +function ideal_membership(a::FreeAssociativeAlgebraElem, I::IdealGens{<:FreeAssociativeAlgebraElem}, deg_bound::Int=-1) return ideal_membership(a, collect(I), deg_bound) end -function ideal_membership(a::FreeAssAlgElem, I::Vector{<:FreeAssAlgElem}, deg_bound::Int=-1) +function ideal_membership(a::FreeAssociativeAlgebraElem, I::Vector{<:FreeAssociativeAlgebraElem}, deg_bound::Int=-1) R = parent(a) @assert all(x -> parent(x) == R, I) "parent mismatch" gb = groebner_basis(I, deg_bound) return iszero(normal_form(a, gb)) end -function Base.in(a::FreeAssAlgElem, I::FreeAssociativeAlgebraIdeal) +function Base.in(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal) return ideal_membership(a, I) end @@ -137,7 +137,7 @@ function is_subset(I1::FreeAssociativeAlgebraIdeal, I2::FreeAssociativeAlgebraId return all(x -> in(x, I2), gens(I1)) end -function (R::Singular.LPRing)(a::FreeAssAlgElem) +function (R::Singular.LPRing)(a::FreeAssociativeAlgebraElem) B = MPolyBuildCtx(R) for (c, e) in zip(coefficients(a), exponent_words(a)) push_term!(B, base_ring(R)(c), e) @@ -189,7 +189,7 @@ function groebner_basis(I::FreeAssociativeAlgebraIdeal, I.deg_bound = deg_bound return I.gb end -function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, +function groebner_basis(g::IdealGens{<:FreeAssociativeAlgebraElem}, deg_bound::Int=-1; ordering::Symbol=:deglex, protocol::Bool=false, @@ -197,7 +197,7 @@ function groebner_basis(g::IdealGens{<:FreeAssAlgElem}, gb = groebner_basis(collect(g), deg_bound; ordering=ordering, protocol=protocol, interreduce=interreduce) return IdealGens(gb) end -function groebner_basis(g::Vector{<:FreeAssAlgElem}, +function groebner_basis(g::Vector{<:FreeAssociativeAlgebraElem}, deg_bound::Int=-1; ordering::Symbol=:deglex, protocol::Bool=false, @@ -228,9 +228,9 @@ function groebner_basis(g::Vector{<:FreeAssAlgElem}, return gb end -is_groebner_basis(g::IdealGens{<:FreeAssAlgElem}) = is_groebner_basis(collect(g)) +is_groebner_basis(g::IdealGens{<:FreeAssociativeAlgebraElem}) = is_groebner_basis(collect(g)) -function is_groebner_basis(gb::Vector{<:FreeAssAlgElem}) +function is_groebner_basis(gb::Vector{<:FreeAssociativeAlgebraElem}) obsructions = AbstractAlgebra.Generic.get_obstructions(gb) while !isempty(obsructions) f = AbstractAlgebra.Generic.s_polynomial(popfirst!(obsructions)[1]) @@ -244,6 +244,6 @@ function interreduce!(I::FreeAssociativeAlgebraIdeal) I.gb = interreduce!(I.gb) return I end -function interreduce!(gb::IdealGens{<:FreeAssAlgElem}) +function interreduce!(gb::IdealGens{<:FreeAssociativeAlgebraElem}) return IdealGens(interreduce!(collect(gb))) end diff --git a/src/Serialization/Algebras.jl b/src/Serialization/Algebras.jl index fb5c18f8cebe..a2b34ac2bcb9 100644 --- a/src/Serialization/Algebras.jl +++ b/src/Serialization/Algebras.jl @@ -18,11 +18,11 @@ function load_object(s::DeserializerState, ::Type{<:FreeAssociativeAlgebra}) end # Free associative algebra element serialization -@register_serialization_type FreeAssAlgElem uses_params +@register_serialization_type FreeAssociativeAlgebraElem uses_params # see save_type_params in Rings -function save_object(s::SerializerState, f::FreeAssAlgElem) +function save_object(s::SerializerState, f::FreeAssociativeAlgebraElem) save_data_array(s) do for term in terms(f) save_data_array(s) do @@ -33,7 +33,7 @@ function save_object(s::SerializerState, f::FreeAssAlgElem) end end -function load_object(s::DeserializerState, ::Type{<:FreeAssAlgElem}, parents::Vector) +function load_object(s::DeserializerState, ::Type{<:FreeAssociativeAlgebraElem}, parents::Vector) parent_algebra = parents[end] coeff_type = elem_type(base_ring(parent_algebra)) elem = MPolyBuildCtx(parent_algebra) diff --git a/src/Serialization/Rings.jl b/src/Serialization/Rings.jl index 5b05fdeb8f5f..dfc1415f5b98 100644 --- a/src/Serialization/Rings.jl +++ b/src/Serialization/Rings.jl @@ -2,7 +2,7 @@ # Common union types # this will need a better name at some point -const RingMatElemUnion = Union{RingElem, MatElem, FreeAssAlgElem, SMat} +const RingMatElemUnion = Union{RingElem, MatElem, FreeAssociativeAlgebraElem, SMat} # this union will also need a better name at some point const RingMatSpaceUnion = Union{Ring, MatSpace, SMatSpace, FreeAssociativeAlgebra} diff --git a/test/Rings/FreeAssociativeAlgebraIdeal.jl b/test/Rings/FreeAssociativeAlgebraIdeal.jl index 5a55e6953412..8a13b179e78d 100644 --- a/test/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/test/Rings/FreeAssociativeAlgebraIdeal.jl @@ -39,7 +39,7 @@ end @test base_ring(I) == R @test isa(ngens(I),Int) @test isequal(ngens(I),2) - @test isa(gen(I,ngens(I)),FreeAssAlgElem{QQFieldElem}) + @test isa(gen(I,ngens(I)),FreeAssociativeAlgebraElem{QQFieldElem}) @test isa(gens(I),Vector) lpring, _ = Oscar._to_lpring(R, 3) @@ -50,7 +50,7 @@ end f1 = x*y + y*z F1 = free(f1) - @test isa(F1,FreeAssAlgElem) + @test isa(F1,FreeAssociativeAlgebraElem) end @testset "FreeAssociativeAlgebraIdeal.groebner_basis" begin From 1f144800ce513e4bcfd9202eb8a635482a0106f9 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 16:43:57 +0200 Subject: [PATCH 11/17] upgrade script --- src/Rings/FreeAssociativeAlgebraIdeal.jl | 4 +- src/Serialization/Upgrades/1.2.0.jl | 50 ++++++++++++++++++++++++ src/Serialization/Upgrades/main.jl | 1 + 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/Serialization/Upgrades/1.2.0.jl diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index 7192236c60da..ff92e3801b46 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -18,7 +18,7 @@ mutable struct FreeAssociativeAlgebraIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} deg_bound::Int - function FreeAssociativeAlgebraIdeal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem + function FreeAssociativeAlgebraIdeal(g::IdealGens{T}; check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem r = new{T}() r.gens = g @req !check_groebner_basis || base_ring(base_ring(g)) isa Field "Groebner basis check requires a field base ring" @@ -56,7 +56,7 @@ function ideal(g::Vector{<:FreeAssociativeAlgebraElem}) return ideal(algebra, g) end -function ideal(g::IdealGens{T}, check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem +function ideal(g::IdealGens{T}; check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem return FreeAssociativeAlgebraIdeal(g, check_groebner_basis) end diff --git a/src/Serialization/Upgrades/1.2.0.jl b/src/Serialization/Upgrades/1.2.0.jl new file mode 100644 index 000000000000..38ef986cd5b9 --- /dev/null +++ b/src/Serialization/Upgrades/1.2.0.jl @@ -0,0 +1,50 @@ +################################################################################ +# Upgrade Summary +# +# `FreeAssAlgebra`: We renamed `FreeAssAlgebra` to `FreeAssociativeAlgebra`, +# as well as `FreeAssAlgElem` to `FreeAssociativeAlgebraElem` and this upgrade script takes care of this renaming. + +push!(upgrade_scripts_set, UpgradeScript( + v"1.2.0", + function upgrade_1_2_0(s::UpgradeState, dict::Dict) + upgraded_dict = dict + + renamings = Dict{String,String}([ + ("FreeAssAlgebra", "FreeAssociativeAlgebra"), + ("FreeAssAlgElem", "FreeAssociativeAlgebraElem"), + ("FreeAssAlgIdeal", "FreeAssociativeAlgebraIdeal"), + ]) + + function upgrade_type(d::String) + return get(renamings, d, d) + end + function upgrade_type(d::Dict) + upg_d = d + upg_d[:name] = get(renamings, d[:name], d[:name]) + if d[:params] isa Dict && haskey(d[:params], :_type) + upg_d[:params][:_type] = upgrade_type(d[:params][:_type]) + elseif d[:params] isa Vector + upg_d[:params] = [upgrade_type(v) for v in d[:params]] + end + return upg_d + end + + if haskey(dict, :_type) + upgraded_dict[:_type] = upgrade_type(dict[:_type]) + end + + if haskey(dict, :data) && dict[:data] isa Dict + upgraded_dict[:data] = upgrade_1_2_0(s, dict[:data]) + end + + if haskey(dict, :_refs) + upgraded_refs = Dict() + for (k, v) in dict[:_refs] + upgraded_refs[k] = upgrade_1_2_0(s, v) + end + upgraded_dict[:_refs] = upgraded_refs + end + + return upgraded_dict + end +)) diff --git a/src/Serialization/Upgrades/main.jl b/src/Serialization/Upgrades/main.jl index 8f16414cc99c..89790e31b1d0 100644 --- a/src/Serialization/Upgrades/main.jl +++ b/src/Serialization/Upgrades/main.jl @@ -93,6 +93,7 @@ include("0.12.2.jl") include("0.13.0.jl") include("0.15.0.jl") include("1.1.0.jl") +include("1.2.0.jl") const upgrade_scripts = collect(upgrade_scripts_set) sort!(upgrade_scripts; by=version) From 87b9206f88b43ec86b8d11a3282e4a3a156b1570 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 16:52:39 +0200 Subject: [PATCH 12/17] fix of kwarg change in FreeAssAlgebraIdeal --- src/Rings/FreeAssociativeAlgebraIdeal.jl | 2 +- test/Rings/FreeAssociativeAlgebraIdeal.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index ff92e3801b46..5d5083a0d215 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -57,7 +57,7 @@ function ideal(g::Vector{<:FreeAssociativeAlgebraElem}) end function ideal(g::IdealGens{T}; check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem - return FreeAssociativeAlgebraIdeal(g, check_groebner_basis) + return FreeAssociativeAlgebraIdeal(g, check_groebner_basis=check_groebner_basis) end diff --git a/test/Rings/FreeAssociativeAlgebraIdeal.jl b/test/Rings/FreeAssociativeAlgebraIdeal.jl index 8a13b179e78d..73e4638f544c 100644 --- a/test/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/test/Rings/FreeAssociativeAlgebraIdeal.jl @@ -108,7 +108,7 @@ end gb5 = groebner_basis(gens(quantum_symmetric_group(3)); interreduce=true) A = parent(gb5[1]) - I3 = ideal(Oscar.IdealGens(A, gb5),true) + I3 = ideal(Oscar.IdealGens(A, gb5);check_groebner_basis=true) @test is_groebner_basis(I3.gens) x = base_ring(ideal(gb5))[1]; y = base_ring(ideal(gb5))[7] From 52bd76348f58799946083424133ca6dd74e2e237 Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 16:59:05 +0200 Subject: [PATCH 13/17] removed the check_groebner_basis functionality --- src/Rings/FreeAssociativeAlgebraIdeal.jl | 11 +++-------- test/Rings/FreeAssociativeAlgebraIdeal.jl | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index 5d5083a0d215..d44dd655a08d 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -18,14 +18,9 @@ mutable struct FreeAssociativeAlgebraIdeal{T} <: Ideal{T} gens::IdealGens{T} gb::IdealGens{T} deg_bound::Int - function FreeAssociativeAlgebraIdeal(g::IdealGens{T}; check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem + function FreeAssociativeAlgebraIdeal(g::IdealGens{T}) where T <: FreeAssociativeAlgebraElem r = new{T}() r.gens = g - @req !check_groebner_basis || base_ring(base_ring(g)) isa Field "Groebner basis check requires a field base ring" - if check_groebner_basis && base_ring(base_ring(g)) isa Field && is_groebner_basis(g) - r.gb = g - r.deg_bound = -1 - end return r end end @@ -56,8 +51,8 @@ function ideal(g::Vector{<:FreeAssociativeAlgebraElem}) return ideal(algebra, g) end -function ideal(g::IdealGens{T}; check_groebner_basis::Bool=false) where T <: FreeAssociativeAlgebraElem - return FreeAssociativeAlgebraIdeal(g, check_groebner_basis=check_groebner_basis) +function ideal(g::IdealGens{T}) where T <: FreeAssociativeAlgebraElem + return FreeAssociativeAlgebraIdeal(g) end diff --git a/test/Rings/FreeAssociativeAlgebraIdeal.jl b/test/Rings/FreeAssociativeAlgebraIdeal.jl index 73e4638f544c..9697ea3eb56f 100644 --- a/test/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/test/Rings/FreeAssociativeAlgebraIdeal.jl @@ -108,7 +108,7 @@ end gb5 = groebner_basis(gens(quantum_symmetric_group(3)); interreduce=true) A = parent(gb5[1]) - I3 = ideal(Oscar.IdealGens(A, gb5);check_groebner_basis=true) + I3 = ideal(Oscar.IdealGens(A, gb5)) @test is_groebner_basis(I3.gens) x = base_ring(ideal(gb5))[1]; y = base_ring(ideal(gb5))[7] From af5a479022c757ef4cca76d79a14fa4e5e7f9ccf Mon Sep 17 00:00:00 2001 From: Marcel Wack Date: Thu, 29 Aug 2024 17:23:54 +0200 Subject: [PATCH 14/17] switched out assert, added a base_ring check to is_subset --- src/Rings/FreeAssociativeAlgebraIdeal.jl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Rings/FreeAssociativeAlgebraIdeal.jl b/src/Rings/FreeAssociativeAlgebraIdeal.jl index d44dd655a08d..7e34f422c963 100644 --- a/src/Rings/FreeAssociativeAlgebraIdeal.jl +++ b/src/Rings/FreeAssociativeAlgebraIdeal.jl @@ -41,12 +41,12 @@ end Return the two-sided ideal of $R$ generated by $g$. """ function ideal(R::FreeAssociativeAlgebra, g::Vector{<:FreeAssociativeAlgebraElem}) - @assert all(x -> parent(x) == R, g) "parent mismatch" + @req all(x -> parent(x) == R, g) "parent mismatch" return FreeAssociativeAlgebraIdeal(IdealGens(R, g)) end function ideal(g::Vector{<:FreeAssociativeAlgebraElem}) - @assert length(g) > 0 "cannot infer base ring" + @req length(g) > 0 "cannot infer base ring" algebra = parent(g[1]) return ideal(algebra, g) end @@ -78,13 +78,13 @@ end function Base.:+(a::FreeAssociativeAlgebraIdeal{T}, b::FreeAssociativeAlgebraIdeal{T}) where T R = base_ring(a) - @assert R == base_ring(b) "parent mismatch" + @req R == base_ring(b) "parent mismatch" return ideal(R, vcat(gens(a), gens(b))) end function Base.:*(a::FreeAssociativeAlgebraIdeal{T}, b::FreeAssociativeAlgebraIdeal{T}) where T R = base_ring(a) - @assert R == base_ring(b) "parent mismatch" + @req R == base_ring(b) "parent mismatch" return ideal(R, [i*j for i in gens(a) for j in gens(b)]) end @@ -119,7 +119,7 @@ function ideal_membership(a::FreeAssociativeAlgebraElem, I::IdealGens{<:FreeAsso end function ideal_membership(a::FreeAssociativeAlgebraElem, I::Vector{<:FreeAssociativeAlgebraElem}, deg_bound::Int=-1) R = parent(a) - @assert all(x -> parent(x) == R, I) "parent mismatch" + @req all(x -> parent(x) == R, I) "parent mismatch" gb = groebner_basis(I, deg_bound) return iszero(normal_form(a, gb)) end @@ -129,6 +129,10 @@ function Base.in(a::FreeAssociativeAlgebraElem, I::FreeAssociativeAlgebraIdeal) end function is_subset(I1::FreeAssociativeAlgebraIdeal, I2::FreeAssociativeAlgebraIdeal) + @req base_ring(I1) === base_ring(I2) "parent mismatch" + I1 === I2 && return true + gens(I1) == gens(I2) && return true + isdefined(I1, :gb) && isdefined(I2, :gb) && I1.gb == I2.gb && return true return all(x -> in(x, I2), gens(I1)) end @@ -199,9 +203,9 @@ function groebner_basis(g::Vector{<:FreeAssociativeAlgebraElem}, interreduce::Bool=false) R = parent(g[1]) - @assert all(x -> parent(x) == R, g) "parent mismatch" - @assert deg_bound >= 0 || !protocol "computing with a protocol requires a degree bound" - @assert ordering == :deglex || deg_bound > 0 "only :deglex ordering is supported for no degree bound" + @req all(x -> parent(x) == R, g) "parent mismatch" + @req deg_bound >= 0 || !protocol "computing with a protocol requires a degree bound" + @req ordering == :deglex || deg_bound > 0 "only :deglex ordering is supported for no degree bound" if deg_bound == -1 gb = AbstractAlgebra.groebner_basis(g) From 8990f925154bba28bf26ddd2c7a63b168a3cd1f1 Mon Sep 17 00:00:00 2001 From: Antony Della Vecchia Date: Thu, 29 Aug 2024 19:02:52 +0200 Subject: [PATCH 15/17] refactored upgrade types + fix upgrade script for dicts + test --- src/Serialization/Upgrades/0.15.0.jl | 23 +-- src/Serialization/Upgrades/1.2.0.jl | 20 +-- src/Serialization/Upgrades/main.jl | 29 ++++ .../file_version_less_than_1.2.0.json | 158 ++++++++++++++++++ test/Serialization/upgrades/runtests.jl | 6 + 5 files changed, 196 insertions(+), 40 deletions(-) create mode 100644 test/Serialization/upgrades/file_version_less_than_1.2.0.json diff --git a/src/Serialization/Upgrades/0.15.0.jl b/src/Serialization/Upgrades/0.15.0.jl index 10d8a2fb7c2a..eb4a6b8ead0a 100644 --- a/src/Serialization/Upgrades/0.15.0.jl +++ b/src/Serialization/Upgrades/0.15.0.jl @@ -5,9 +5,6 @@ push!(upgrade_scripts_set, UpgradeScript( v"0.15.0", function upgrade_0_15_0(s::UpgradeState, dict::Dict) - - upgraded_dict = dict - renamings = Dict{String,String}([ ("FlintPadicField", "PadicField"), ("padic", "PadicFieldElem"), @@ -31,24 +28,8 @@ push!(upgrade_scripts_set, UpgradeScript( ("EmbeddedElem", "EmbeddedNumFieldElem"), ]) - function upgrade_type(d::String) - return get(renamings, d, d) - end - function upgrade_type(d::Dict) - upg_d = d - upg_d[:name] = get(renamings, d[:name], d[:name]) - if d[:params] isa Dict && haskey(d[:params], :_type) - upg_d[:params][:_type] = upgrade_type(d[:params][:_type]) - elseif d[:params] isa Vector - upg_d[:params] = [upgrade_type(v) for v in d[:params]] - end - return upg_d - end - - if haskey(dict, :_type) - upgraded_dict[:_type] = upgrade_type(dict[:_type]) - end - + upgraded_dict = upgrade_types(dict, renamings) + if haskey(dict, :data) && dict[:data] isa Dict upgraded_dict[:data] = upgrade_0_15_0(s, dict[:data]) end diff --git a/src/Serialization/Upgrades/1.2.0.jl b/src/Serialization/Upgrades/1.2.0.jl index 38ef986cd5b9..7f828705c15f 100644 --- a/src/Serialization/Upgrades/1.2.0.jl +++ b/src/Serialization/Upgrades/1.2.0.jl @@ -7,32 +7,14 @@ push!(upgrade_scripts_set, UpgradeScript( v"1.2.0", function upgrade_1_2_0(s::UpgradeState, dict::Dict) - upgraded_dict = dict - renamings = Dict{String,String}([ ("FreeAssAlgebra", "FreeAssociativeAlgebra"), ("FreeAssAlgElem", "FreeAssociativeAlgebraElem"), ("FreeAssAlgIdeal", "FreeAssociativeAlgebraIdeal"), ]) - function upgrade_type(d::String) - return get(renamings, d, d) - end - function upgrade_type(d::Dict) - upg_d = d - upg_d[:name] = get(renamings, d[:name], d[:name]) - if d[:params] isa Dict && haskey(d[:params], :_type) - upg_d[:params][:_type] = upgrade_type(d[:params][:_type]) - elseif d[:params] isa Vector - upg_d[:params] = [upgrade_type(v) for v in d[:params]] - end - return upg_d - end + upgraded_dict = upgrade_types(dict, renamings) - if haskey(dict, :_type) - upgraded_dict[:_type] = upgrade_type(dict[:_type]) - end - if haskey(dict, :data) && dict[:data] isa Dict upgraded_dict[:data] = upgrade_1_2_0(s, dict[:data]) end diff --git a/src/Serialization/Upgrades/main.jl b/src/Serialization/Upgrades/main.jl index 89790e31b1d0..2c7ba12bc8bf 100644 --- a/src/Serialization/Upgrades/main.jl +++ b/src/Serialization/Upgrades/main.jl @@ -87,6 +87,35 @@ function upgrade_data(upgrade::Function, s::UpgradeState, dict::Dict) return upgraded_dict end +# upgrades all types in dict based on renamings +function upgrade_types(dict::Dict, renamings::Dict{String, String}) + function upgrade_type(d::String) + return get(renamings, d, d) + end + + function upgrade_type(d::Dict) + upg_d = d + upg_d[:name] = get(renamings, d[:name], d[:name]) + if d[:params] isa Dict + if haskey(d[:params], :_type) + upg_d[:params][:_type] = upgrade_type(d[:params][:_type]) + else + for (k, v) in d[:params] + upg_d[:params][k] = upgrade_type(d[:params][k]) + end + end + elseif d[:params] isa Vector + upg_d[:params] = [upgrade_type(v) for v in d[:params]] + end + return upg_d + end + + if haskey(dict, :_type) + dict[:_type] = upgrade_type(dict[:_type]) + end + return dict +end + include("0.11.3.jl") include("0.12.0.jl") include("0.12.2.jl") diff --git a/test/Serialization/upgrades/file_version_less_than_1.2.0.json b/test/Serialization/upgrades/file_version_less_than_1.2.0.json new file mode 100644 index 000000000000..6758721f2054 --- /dev/null +++ b/test/Serialization/upgrades/file_version_less_than_1.2.0.json @@ -0,0 +1,158 @@ +{ + "_ns": { + "Oscar": [ + "https://github.com/oscar-system/Oscar.jl", + "1.1.0-DEV-bd8e18b45854187743733b0ba1b9c56c27f7f73a" + ] + }, + "_type": { + "name": "Dict", + "params": { + "key_type": "String", + "revlex_basis_encoding": "String", + "Aut_bases_timed": "Float64", + "Aut_bases_lp": { + "name": "Vector", + "params": { + "name": "FreeAssAlgElem", + "params": "235311eb-8527-4a86-84b4-f146ec0a12ba" + } + }, + "Aut_bases": { + "name": "Vector", + "params": { + "name": "FreeAssAlgElem", + "params": "235311eb-8527-4a86-84b4-f146ec0a12ba" + } + }, + "Aut_bases_lp_timed": "Float64", + "Aut_bases_lp_prot": { + "name": "Vector", + "params": "UInt8" + }, + "Aut_bases_lp_degree_bound": "Base.Int" + } + }, + "data": { + "revlex_basis_encoding": "*", + "Aut_bases_timed": "0.073384228", + "Aut_bases_lp": [ + [ + [ + [ + "1" + ], + "1" + ], + [ + [], + "-1" + ] + ] + ], + "Aut_bases": [ + [ + [ + [ + "1", + "1" + ], + "1" + ], + [ + [ + "1" + ], + "-1" + ] + ], + [ + [ + [ + "1" + ], + "1" + ], + [ + [], + "-1" + ] + ], + [ + [ + [ + "1" + ], + "1" + ], + [ + [], + "-1" + ] + ] + ], + "Aut_bases_lp_timed": "0.030181131", + "Aut_bases_lp_prot": [ + "49", + "40", + "50", + "41", + "115", + "50", + "45", + "10", + "112", + "114", + "111", + "100", + "117", + "99", + "116", + "32", + "99", + "114", + "105", + "116", + "101", + "114", + "105", + "111", + "110", + "58", + "48", + "32", + "99", + "104", + "97", + "105", + "110", + "32", + "99", + "114", + "105", + "116", + "101", + "114", + "105", + "111", + "110", + "58", + "48", + "10" + ], + "Aut_bases_lp_degree_bound": "3" + }, + "_refs": { + "235311eb-8527-4a86-84b4-f146ec0a12ba": { + "_type": "FreeAssAlgebra", + "data": { + "base_ring": { + "_type": "QQField" + }, + "symbols": [ + "u[1,1]" + ] + } + } + } +} diff --git a/test/Serialization/upgrades/runtests.jl b/test/Serialization/upgrades/runtests.jl index a66641b0d2c3..01dad397d4d4 100644 --- a/test/Serialization/upgrades/runtests.jl +++ b/test/Serialization/upgrades/runtests.jl @@ -21,4 +21,10 @@ loaded_p = load(joinpath(@__DIR__, "file_version_less_than_0.12.0.json"); params=Rx); @test p == loaded_p end + + @testset "< 1.2.0 Upgrade" begin + # test loading + loaded = load(joinpath(@__DIR__, "file_version_less_than_1.2.0.json")); + @test loaded isa Dict + end end From 2709e35bc3b2481c31d8ea8c4e3597a777829b3d Mon Sep 17 00:00:00 2001 From: antonydellavecchia Date: Fri, 30 Aug 2024 18:19:27 +0200 Subject: [PATCH 16/17] fix tests --- src/Serialization/Upgrades/main.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Serialization/Upgrades/main.jl b/src/Serialization/Upgrades/main.jl index 2c7ba12bc8bf..6591908c9981 100644 --- a/src/Serialization/Upgrades/main.jl +++ b/src/Serialization/Upgrades/main.jl @@ -95,7 +95,14 @@ function upgrade_types(dict::Dict, renamings::Dict{String, String}) function upgrade_type(d::Dict) upg_d = d - upg_d[:name] = get(renamings, d[:name], d[:name]) + + if haskey(d, :name) + upg_d[:name] = get(renamings, d[:name], d[:name]) + else + upg_d[:_type] = get(renamings, d[:_type], d[:_type]) + return upg_d + end + if d[:params] isa Dict if haskey(d[:params], :_type) upg_d[:params][:_type] = upgrade_type(d[:params][:_type]) From 473d8f151098ebf4e96df03f84a1a86d1f376c9c Mon Sep 17 00:00:00 2001 From: Antony Della Vecchia Date: Mon, 2 Sep 2024 10:08:24 +0200 Subject: [PATCH 17/17] fixes backwards compatibility test --- src/Serialization/Upgrades/main.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Serialization/Upgrades/main.jl b/src/Serialization/Upgrades/main.jl index 6591908c9981..56345cf0ed17 100644 --- a/src/Serialization/Upgrades/main.jl +++ b/src/Serialization/Upgrades/main.jl @@ -92,6 +92,10 @@ function upgrade_types(dict::Dict, renamings::Dict{String, String}) function upgrade_type(d::String) return get(renamings, d, d) end + + function upgrade_type(v::Vector) + return map(upgrade_type, v) + end function upgrade_type(d::Dict) upg_d = d @@ -112,7 +116,7 @@ function upgrade_types(dict::Dict, renamings::Dict{String, String}) end end elseif d[:params] isa Vector - upg_d[:params] = [upgrade_type(v) for v in d[:params]] + upg_d[:params] = upgrade_type(d[:params]) end return upg_d end