From 5e0aa27db69cf5c3d8e0e627aebef9331f2e6520 Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Wed, 18 Sep 2024 15:29:01 +0200 Subject: [PATCH] Some advances on serialization. --- src/Serialization/MPolyMap.jl | 14 ++++- src/Serialization/Rings.jl | 109 +++++++++++++++++++++++++++++++++- src/Serialization/main.jl | 1 + test/Serialization/schemes.jl | 80 +++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 6 deletions(-) diff --git a/src/Serialization/MPolyMap.jl b/src/Serialization/MPolyMap.jl index a1b3e599645f..642cc44e75ee 100644 --- a/src/Serialization/MPolyMap.jl +++ b/src/Serialization/MPolyMap.jl @@ -17,25 +17,33 @@ function load_type_params(s::DeserializerState, ::Type{<:MPolyAnyMap}) return (d, c) end -function save_object(s::SerializerState, phi::MPolyAnyMap) +function save_object(s::SerializerState{T}, phi::MPolyAnyMap) where {T} save_data_dict(s) do save_object(s, _images(phi), :images) cm = coefficient_map(phi) + + @req _check_whether_this_is_admissible_serialization(typeof(cm), T) "the type of the coefficient map is not supported for long term storage" if !isnothing(cm) save_object(s, cm, :coeff_map) end end end +_check_whether_this_is_admissible_serialization(::Type{CMType}, ::Type{SerializeParam}) where {CMType, SerializeParam <: OscarSerializer} = false +_check_whether_this_is_admissible_serialization(::Type{Nothing}, ::Type{SerializeParam}) where {SerializeParam <: OscarSerializer} = true +# TODO This list can be extended for more types of coefficient maps if needed +_check_whether_this_is_admissible_serialization(::Type{CMType}, ::Type{SerializeParam}) where {CMType, SerializeParam <: IPCSerializer} = true + function load_object(s::DeserializerState, ::Type{<:MPolyAnyMap}, - params::Tuple{MPolyRing, MPolyRing}) + params::Tuple{<:Union{<:MPolyRing, <:MPolyQuoRing}, <:Ring} + ) d = params[1] c = params[2] imgs = load_object(s, Vector, c, :images) if haskey(s, :coeff_map) - throw("MPolyAnyMap with coefficient map serialization unimplemented") + return hom(d, c, load_object(s, :coeff_map), img_gens) end return MPolyAnyMap(d, c, nothing, imgs) end diff --git a/src/Serialization/Rings.jl b/src/Serialization/Rings.jl index d4a9c15bc941..23e62fe5ff73 100644 --- a/src/Serialization/Rings.jl +++ b/src/Serialization/Rings.jl @@ -287,6 +287,9 @@ end @register_serialization_type MPolyIdeal uses_params @register_serialization_type LaurentMPolyIdeal uses_params +@register_serialization_type MPolyLocalizedIdeal uses_params +@register_serialization_type MPolyQuoLocalizedIdeal uses_params +@register_serialization_type MPolyQuoIdeal uses_params # we should avoid this list getting too long and find a # way to abstract saving params soon @@ -294,7 +297,11 @@ const IdealOrdUnionType = Union{MPolyIdeal, LaurentMPolyIdeal, FreeAssociativeAlgebraIdeal, IdealGens, - MonomialOrdering} + MonomialOrdering, + MPolyLocalizedIdeal, + MPolyQuoLocalizedIdeal, + MPolyQuoIdeal + } function save_type_params(s::SerializerState, x::T) where T <: IdealOrdUnionType save_data_dict(s) do @@ -779,7 +786,7 @@ end function load_object(s::DeserializerState, ::Type{<:MPolyPowersOfElement}) R = load_typed_object(s, :ring) - dens = load_typed_object(s, :dens) + dens = Vector{elem_type(R)}(load_typed_object(s, :dens)) # casting is necessary for empty arrays return MPolyPowersOfElement(R, dens) end @@ -847,6 +854,102 @@ function load_object(s::DeserializerState, ::Type{<:MPolyLocRingElem}, prts::Vec RET = elem_type(P) num = load_object(s, RET, P, 1) den = load_object(s, RET, P, 2) - return L(num, den) + return L(num, den; check=false) end +@register_serialization_type MPolyQuoLocRing uses_id + +function save_object(s::SerializerState, L::MPolyQuoLocRing) + save_data_dict(s) do + save_typed_object(s, underlying_quotient(L), :quo_ring) + save_typed_object(s, inverted_set(L), :inv_set) + end +end + +function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocRing}) + Q = load_typed_object(s, :quo_ring) + U = load_typed_object(s, :inv_set) + return MPolyQuoLocRing(base_ring(Q), modulus(Q), U) +end + +@register_serialization_type MPolyQuoLocRingElem uses_params + +function save_object(s::SerializerState, a::MPolyQuoLocRingElem) + save_data_array(s) do + save_object(s, lifted_numerator(a)) + save_object(s, lifted_denominator(a)) + end +end + +function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocRingElem}, prts::Vector) + L = prts[end]::MPolyQuoLocRing + P = base_ring(L) + RET = elem_type(P) + num = load_object(s, RET, P, 1) + den = load_object(s, RET, P, 2) + return L(num, den; check=false) +end + +### Morphisms of the four types of rings + +#= +@register_serialization_type MPolyAnyMap uses_id + +function save_object(s::SerializerState, phi::MPolyAnyMap) + save_data_dict(s) do + save_typed_object(s, domain(phi), :domain) + save_typed_object(s, codomain(phi), :codomain) + _has_coefficient_map(phi) && save_object(s, coefficient_map(phi), :coeff_map) + save_object(s, _images(phi), :img_gens) + end +end + +function load_object(s::DeserializerState, ::Type{<:MPolyAnyMap}) + dom = load_typed_object(s, :domain) + cod = load_typed_object(s, :codomain) + img_gens = load_object(s, :img_gens) + if haskey(s, :coeff_map) + coeff_map = load_object(s, :coeff_map) + return hom(dom, cod, coeff_map, img_gens) + end + return hom(dom, cod, img_gens) +end +=# + + +@register_serialization_type MPolyLocalizedRingHom uses_id + +function save_object(s::SerializerState, phi::MPolyLocalizedRingHom) + save_data_dict(s) do + save_typed_object(s, domain(phi), :domain) + save_typed_object(s, codomain(phi), :codomain) + save_typed_object(s, restricted_map(phi), :res_map) + end +end + +function load_object(s::DeserializerState, ::Type{<:MPolyLocalizedRingHom}) + dom = load_typed_object(s, :domain) + cod = load_typed_object(s, :codomain) + res = load_typed_object(s, :res_map) + return MPolyLocalizedRingHom(dom, cod, res; check=false) +end + + +@register_serialization_type MPolyQuoLocalizedRingHom uses_id + +function save_object(s::SerializerState, phi::MPolyQuoLocalizedRingHom) + save_data_dict(s) do + save_typed_object(s, domain(phi), :domain) + save_typed_object(s, codomain(phi), :codomain) + save_typed_object(s, restricted_map(phi), :res_map) + end +end + +function load_object(s::DeserializerState, ::Type{<:MPolyQuoLocalizedRingHom}) + dom = load_typed_object(s, :domain) + cod = load_typed_object(s, :codomain) + res = load_typed_object(s, :res_map) + return MPolyQuoLocalizedRingHom(dom, cod, res; check=false) +end + + diff --git a/src/Serialization/main.jl b/src/Serialization/main.jl index 9e73730026fe..c9329986d56a 100644 --- a/src/Serialization/main.jl +++ b/src/Serialization/main.jl @@ -472,6 +472,7 @@ include("TropicalGeometry.jl") include("QuadForm.jl") include("GAP.jl") include("Groups.jl") +include("Schemes.jl") include("Upgrades/main.jl") diff --git a/test/Serialization/schemes.jl b/test/Serialization/schemes.jl index c5a24df18711..7878fe26c9d5 100644 --- a/test/Serialization/schemes.jl +++ b/test/Serialization/schemes.jl @@ -15,6 +15,10 @@ test_save_load_roundtrip(path, b) do loaded @test !is_unit(b) end + J = ideal(L, gens(L)) + test_save_load_roundtrip(path, J) do loaded + @test is_one(J) + end U = complement_of_prime_ideal(ideal(R, x+y)) L, _ = localization(R, U) @@ -30,6 +34,11 @@ test_save_load_roundtrip(path, b) do loaded @test !is_unit(b) end + J = ideal(L, gens(L)) + test_save_load_roundtrip(path, J) do loaded + @test is_one(J) + end + U = complement_of_point_ideal(R, QQ.([0, 0])) L, _ = localization(R, U) @@ -46,6 +55,77 @@ @test !is_unit(b) end + I = ideal(R, [x+y]) + Q, _ = quo(R, I) + U = powers_of_element(x*y) + L, _ = localization(Q, U) + test_save_load_roundtrip(path, L) do loaded + @test is_unit(L(x^2*y)) + @test !is_unit(L(x-1)) + end + a = L(x) + b = L(y*(x-1)) + test_save_load_roundtrip(path, a) do loaded + @test is_unit(a) + end + test_save_load_roundtrip(path, b) do loaded + @test !is_unit(b) + end + J = ideal(L, gens(L)) + test_save_load_roundtrip(path, J) do loaded + @test is_one(J) + end + end +end + +@testset "affine schemes" begin + mktempdir() do path + A = affine_space(QQ, 3) + test_save_load_roundtrip(path, A) do loaded + @test OO(A) isa MPolyRing{<:FieldElem} + @test ngens(OO(A)) == 3 + end + + (x, y, z) = gens(OO(A)) + U = PrincipalOpenSubset(A, [x, y]) + test_save_load_roundtrip(path, U) do loaded + @test OO(U) isa Oscar.MPolyLocRing + @test ngens(OO(U)) == 3 + @test is_unit(OO(U)(x)) + end end end +@testset "maps from polynomial rings" begin + mktempdir() do path + R, (x, y) = GF(29^2)[:x, :y] + phi = hom(R, R, x->x^29, gens(R)) + @test_throws ArgumentError save(path, phi) + # the following should in principle be supported for some serializations + # which are not for long term storage (to come) + # test_save_load_roundtrip(path, phi) do loaded + # @test phi(one(R)) == one(R) + # end + end +end + +@testset "covered schemes" begin + mktempdir() do path + IP = projective_space(GF(29), 3) + X = covered_scheme(IP) + cov = default_covering(X) + for U in affine_charts(X) + for V in affine_charts(X) + glue = cov[U, V] + glue isa SimpleGluing || continue + test_save_load_roundtrip(path, glue) do loaded + f, g = gluing_morphisms(glue) + @test is_isomorphism(f) + @test is_isomorphism(g) + end + end + end + end +end + +