From c5e121a406dfcabe0b6f1152979f55a3ca08eec8 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 4 Jul 2024 17:37:07 +0200 Subject: [PATCH] Revise check_parent for ResElem and ResFieldElem Also remove check_parent_type. Previously, we allowed binary operations involving two ResElem instances of *different type*, with the type of the result depending on the argument order. For example, this: julia> using Nemo julia> R = quo(ZZ, 2)[1] Integers modulo 2 julia> S = Nemo.AbstractAlgebra.EuclideanRingResidueRing{UInt}(UInt(2)) Residue ring of integers modulo 2 julia> typeof(R) zzModRing julia> typeof(S) EuclideanRingResidueRing{UInt64} julia> S(1) + R(1) 0 julia> typeof(S(1) + R(1)) EuclideanRingResidueRingElem{UInt64} julia> typeof(R(1) + S(1)) zzModRingElem But this seems questionable at best. I think we are better of forbidding this -- which this PR effectively does. --- src/Residue.jl | 15 ++++++--------- src/ResidueField.jl | 16 +++++++--------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/Residue.jl b/src/Residue.jl index 112a5dd88..707730885 100644 --- a/src/Residue.jl +++ b/src/Residue.jl @@ -22,17 +22,14 @@ function is_exact_type(a::Type{T}) where {S <: RingElement, T <: ResElem{S}} return is_exact_type(S) end -function check_parent_type(a::ResidueRing{T}, b::ResidueRing{T}) where {T <: RingElement} - # exists only to check types of parents agree -end - function check_parent(a::ResElem, b::ResElem, throw::Bool = true) - if parent(a) != parent(b) - check_parent_type(parent(a), parent(b)) - fl = modulus(parent(a)) != modulus(parent(b)) - fl && throw && error("Incompatible moduli in residue operation") - return !fl + Ra = parent(a) + Rb = parent(b) + if Ra != Rb + fl = typeof(Ra) == typeof(Rb) && modulus(Ra) == modulus(Rb) + !fl && throw && error("Incompatible moduli in residue operation") #CF: maybe extend to divisibility? + return fl end return true end diff --git a/src/ResidueField.jl b/src/ResidueField.jl index e1fdecddb..fc45c5cfb 100644 --- a/src/ResidueField.jl +++ b/src/ResidueField.jl @@ -22,16 +22,14 @@ function is_exact_type(a::Type{T}) where {S <: RingElement, T <: ResFieldElem{S} return is_exact_type(S) end -function check_parent_type(a::ResidueField{T}, b::ResidueField{T}) where {T <: RingElement} - # exists only to check types of parents agree -end - function check_parent(a::ResFieldElem, b::ResFieldElem, throw::Bool = true) - if parent(a) != parent(b) - check_parent_type(parent(a), parent(b)) - fl = modulus(parent(a)) != modulus(parent(b)) - fl && throw && error("Incompatible moduli in residue operation") #CF: maybe extend to divisibility? - return !fl + Ra = parent(a) + Rb = parent(b) + if Ra != Rb + fl = typeof(Ra) == typeof(Rb) && modulus(Ra) == modulus(Rb) + !fl && throw && error("Incompatible moduli in residue operation") + #CF: maybe extend to divisibility? + return fl end return true end