diff --git a/Project.toml b/Project.toml index 23c03e103c..2c63e04f09 100644 --- a/Project.toml +++ b/Project.toml @@ -13,7 +13,7 @@ SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" [compat] -AbstractAlgebra = "0.44.1" +AbstractAlgebra = "0.44.2" FLINT_jll = "^300.100.100" Libdl = "1.6" LinearAlgebra = "1.6" diff --git a/src/Exports.jl b/src/Exports.jl index cb77d506d3..ee29b244b5 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -351,7 +351,6 @@ export is_less_real export is_less_root_order export is_lower_triangular export is_negative -export is_nilpotent export is_nonnegative export is_nonpositive export is_nonzero diff --git a/src/HeckeMoreStuff.jl b/src/HeckeMoreStuff.jl index 7abe92c401..262ab8148c 100644 --- a/src/HeckeMoreStuff.jl +++ b/src/HeckeMoreStuff.jl @@ -346,38 +346,6 @@ function gcdx(a::ResElem{T}, b::ResElem{T}) where {T<:IntegerUnion} return R(G), R(U) * R(u), R(U) * R(v) end -@doc raw""" - is_unit(f::Union{ZZModPolyRingElem,zzModPolyRingElem}) -> Bool - -Tests if $f$ is a unit in the polynomial ring, i.e. if -$f = u + n$ where $u$ is a unit in the coeff. ring -and $n$ is nilpotent. -""" -function is_unit(f::T) where {T<:Union{ZZModPolyRingElem,zzModPolyRingElem}} - if !is_unit(constant_coefficient(f)) - return false - end - for i = 1:degree(f) - if !is_nilpotent(coeff(f, i)) - return false - end - end - return true -end - -@doc raw""" - is_nilpotent(a::ResElem{ZZRingElem}) -> Bool - is_nilpotent(a::ResElem{Integer}) -> Bool - -Tests if $a$ is nilpotent. -""" -function is_nilpotent(a::ResElem{T}) where {T<:IntegerUnion} - #a is nilpontent if it is divisible by all primes divising the modulus - # the largest exponent a prime can divide is nbits(m) - l = nbits(modulus(a)) - return iszero(a^l) -end - function inv(f::T) where {T<:Union{ZZModPolyRingElem,zzModPolyRingElem}} if !is_unit(f) error("impossible inverse") diff --git a/src/antic/nf_elem.jl b/src/antic/nf_elem.jl index 312f88efff..71be6296f1 100644 --- a/src/antic/nf_elem.jl +++ b/src/antic/nf_elem.jl @@ -130,14 +130,6 @@ function iszero(a::AbsSimpleNumFieldElem) return @ccall libflint.nf_elem_is_zero(a::Ref{AbsSimpleNumFieldElem}, a.parent::Ref{AbsSimpleNumField})::Bool end -@doc raw""" - is_unit(a::AbsSimpleNumFieldElem) - -Return `true` if the given number field element is invertible, i.e. nonzero, -otherwise return `false`. Note, this does not take the maximal order into account. -""" -is_unit(a::AbsSimpleNumFieldElem) = !iszero(a) - @doc raw""" isinteger(a::AbsSimpleNumFieldElem) diff --git a/src/arb/Complex.jl b/src/arb/Complex.jl index 0e36d14904..e32895f99c 100644 --- a/src/arb/Complex.jl +++ b/src/arb/Complex.jl @@ -447,10 +447,6 @@ end # ################################################################################ -function is_unit(x::ComplexFieldElem) - !iszero(x) -end - @doc raw""" iszero(x::ComplexFieldElem) diff --git a/src/arb/acb.jl b/src/arb/acb.jl index bf7031d7a3..95b3fbc313 100644 --- a/src/arb/acb.jl +++ b/src/arb/acb.jl @@ -458,10 +458,6 @@ end # ################################################################################ -function is_unit(x::AcbFieldElem) - !iszero(x) -end - @doc raw""" iszero(x::AcbFieldElem) diff --git a/src/arb/arb.jl b/src/arb/arb.jl index f7abff284b..4a5a0c5c58 100644 --- a/src/arb/arb.jl +++ b/src/arb/arb.jl @@ -450,10 +450,6 @@ end # ################################################################################ -function is_unit(x::ArbFieldElem) - !iszero(x) -end - @doc raw""" iszero(x::ArbFieldElem) diff --git a/src/flint/fmpq.jl b/src/flint/fmpq.jl index 39bca1ca01..ae22e4d284 100644 --- a/src/flint/fmpq.jl +++ b/src/flint/fmpq.jl @@ -113,8 +113,6 @@ is_one(a::QQFieldElemOrPtr) = isinteger(a) && is_one(_num_ptr(a)) is_zero(a::QQFieldElemOrPtr) = is_zero(_num_ptr(a)) -is_unit(a::QQFieldElem) = !iszero(a) - isinteger(a::QQFieldElemOrPtr) = is_one(_den_ptr(a)) isfinite(::QQFieldElem) = true diff --git a/src/flint/fmpq_mpoly.jl b/src/flint/fmpq_mpoly.jl index f4e9398ce9..cab8b11af7 100644 --- a/src/flint/fmpq_mpoly.jl +++ b/src/flint/fmpq_mpoly.jl @@ -104,10 +104,6 @@ function is_term(a::QQMPolyRingElem) return length(a) == 1 end -function is_unit(a::QQMPolyRingElem) - return length(a) == 1 && total_degree(a) == 0 && is_unit(coeff(a, 1)) -end - function is_constant(a::QQMPolyRingElem) b = @ccall libflint.fmpq_mpoly_is_fmpq(a::Ref{QQMPolyRingElem}, parent(a)::Ref{QQMPolyRing})::Cint return Bool(b) diff --git a/src/flint/fmpz_mod_mpoly.jl b/src/flint/fmpz_mod_mpoly.jl index 2254152c3d..e7d44cd2e7 100644 --- a/src/flint/fmpz_mod_mpoly.jl +++ b/src/flint/fmpz_mod_mpoly.jl @@ -106,10 +106,6 @@ for (etype, rtype, ftype, ctype) in ( return length(a) == 1 end - function is_unit(a::($etype)) - return length(a) == 1 && total_degree(a) == 0 && is_unit(coeff(a, 1)) - end - function is_constant(a::($etype)) return Bool(@ccall libflint.fmpz_mod_mpoly_is_fmpz(a::Ref{($etype)}, parent(a)::Ref{($rtype)})::Cint) end diff --git a/src/flint/fmpz_mpoly.jl b/src/flint/fmpz_mpoly.jl index f83fb2be72..73bb15c4d1 100644 --- a/src/flint/fmpz_mpoly.jl +++ b/src/flint/fmpz_mpoly.jl @@ -95,10 +95,6 @@ function is_term(a::ZZMPolyRingElem) return length(a) == 1 end -function is_unit(a::ZZMPolyRingElem) - return length(a) == 1 && total_degree(a) == 0 && is_unit(coeff(a, 1)) -end - function is_constant(a::ZZMPolyRingElem) b = @ccall libflint.fmpz_mpoly_is_fmpz(a::Ref{ZZMPolyRingElem}, parent(a)::Ref{ZZMPolyRing})::Cint return Bool(b) diff --git a/src/flint/fq.jl b/src/flint/fq.jl index ab363b9b96..ae4d2093ef 100644 --- a/src/flint/fq.jl +++ b/src/flint/fq.jl @@ -81,8 +81,6 @@ finite field, otherwise return `false`. """ is_gen(a::FqPolyRepFieldElem) = a == gen(parent(a)) -is_unit(a::FqPolyRepFieldElem) = !is_zero(a) - function characteristic(a::FqPolyRepField) d = ZZRingElem() @ccall libflint.__fq_ctx_prime(d::Ref{ZZRingElem}, a::Ref{FqPolyRepField})::Nothing diff --git a/src/flint/fq_default.jl b/src/flint/fq_default.jl index 15fa7165f2..0cf3b78bcb 100644 --- a/src/flint/fq_default.jl +++ b/src/flint/fq_default.jl @@ -60,8 +60,6 @@ isone(a::FqFieldElem) = @ccall libflint.fq_default_is_one(a::Ref{FqFieldElem}, a _is_gen(a::FqFieldElem) = a == _gen(parent(a)) -is_unit(a::FqFieldElem) = !iszero(a) - function characteristic(a::FqField) d = ZZRingElem() @ccall libflint.fq_default_ctx_prime(d::Ref{ZZRingElem}, a::Ref{FqField})::Nothing diff --git a/src/flint/fq_nmod.jl b/src/flint/fq_nmod.jl index f10daf4a0a..1b53fbcd74 100644 --- a/src/flint/fq_nmod.jl +++ b/src/flint/fq_nmod.jl @@ -81,8 +81,6 @@ isone(a::fqPolyRepFieldElem) = @ccall libflint.fq_nmod_is_one(a::Ref{fqPolyRepFi is_gen(a::fqPolyRepFieldElem) = a == gen(parent(a)) # there is no is_gen in flint -is_unit(a::fqPolyRepFieldElem) = @ccall libflint.fq_nmod_is_invertible(a::Ref{fqPolyRepFieldElem}, a.parent::Ref{fqPolyRepField})::Bool - function characteristic(a::fqPolyRepField) return ZZ(a.n) end diff --git a/src/flint/fq_nmod_mpoly.jl b/src/flint/fq_nmod_mpoly.jl index 6557697a2f..d29346995a 100644 --- a/src/flint/fq_nmod_mpoly.jl +++ b/src/flint/fq_nmod_mpoly.jl @@ -91,10 +91,6 @@ function is_term(a::fqPolyRepMPolyRingElem) return length(a) == 1 end -function is_unit(a::fqPolyRepMPolyRingElem) - return is_constant(a) -end - function is_constant(a::fqPolyRepMPolyRingElem) b = @ccall libflint.fq_nmod_mpoly_is_fq_nmod(a::Ref{fqPolyRepMPolyRingElem}, parent(a)::Ref{fqPolyRepMPolyRing})::Cint return Bool(b) diff --git a/src/flint/gfp_elem.jl b/src/flint/gfp_elem.jl index 8a44ab0103..1dab8ecbaa 100644 --- a/src/flint/gfp_elem.jl +++ b/src/flint/gfp_elem.jl @@ -57,8 +57,6 @@ iszero(a::fpFieldElem) = a.data == 0 isone(a::fpFieldElem) = a.data == 1 -is_unit(a::fpFieldElem) = a.data != 0 - modulus(R::fpField) = R.n function deepcopy_internal(a::fpFieldElem, dict::IdDict) diff --git a/src/flint/gfp_fmpz_elem.jl b/src/flint/gfp_fmpz_elem.jl index 7a89b1117f..dfc955d479 100644 --- a/src/flint/gfp_fmpz_elem.jl +++ b/src/flint/gfp_fmpz_elem.jl @@ -60,8 +60,6 @@ function one(R::FpField) end end -is_unit(a::FpFieldElem) = a.data != 0 - modulus(R::FpField) = R.n characteristic(F::FpField) = modulus(F) diff --git a/src/flint/nmod.jl b/src/flint/nmod.jl index b04266f62e..f8c7442fa2 100644 --- a/src/flint/nmod.jl +++ b/src/flint/nmod.jl @@ -50,9 +50,7 @@ end iszero(a::zzModRingElem) = a.data == 0 -isone(a::zzModRingElem) = a.parent.n == 1 ? a.data == 0 : a.data == 1 - -is_unit(a::zzModRingElem) = a.parent.n == 1 ? a.data == 0 : gcd(a.data, a.parent.n) == 1 +isone(a::zzModRingElem) = (a.parent.n == 1) || (a.data == 1) modulus(R::zzModRing) = R.n diff --git a/src/flint/nmod_mpoly.jl b/src/flint/nmod_mpoly.jl index b434177acd..ceed984e65 100644 --- a/src/flint/nmod_mpoly.jl +++ b/src/flint/nmod_mpoly.jl @@ -100,10 +100,6 @@ for (etype, rtype, ftype, ctype, utype) in ( return length(a) == 1 end - function is_unit(a::($etype)) - return length(a) == 1 && total_degree(a) == 0 && is_unit(coeff(a, 1)) - end - function is_constant(a::($etype)) return Bool(@ccall libflint.nmod_mpoly_is_ui(a::Ref{($etype)}, parent(a)::Ref{($rtype)})::Cint) end diff --git a/src/flint/padic.jl b/src/flint/padic.jl index 0b64f029f9..681d2d2f71 100644 --- a/src/flint/padic.jl +++ b/src/flint/padic.jl @@ -185,8 +185,6 @@ iszero(a::PadicFieldElem) = Bool(@ccall libflint.padic_is_zero(a::Ref{PadicField isone(a::PadicFieldElem) = Bool(@ccall libflint.padic_is_one(a::Ref{PadicFieldElem})::Cint) -is_unit(a::PadicFieldElem) = !iszero(a) - characteristic(R::PadicField) = 0 ############################################################################### diff --git a/src/flint/qadic.jl b/src/flint/qadic.jl index 3d29e60f02..acf11e4002 100644 --- a/src/flint/qadic.jl +++ b/src/flint/qadic.jl @@ -189,8 +189,6 @@ iszero(a::QadicFieldElem) = Bool(@ccall libflint.qadic_is_zero(a::Ref{QadicField isone(a::QadicFieldElem) = Bool(@ccall libflint.qadic_is_one(a::Ref{QadicFieldElem})::Cint) -is_unit(a::QadicFieldElem) = !iszero(a) - characteristic(R::QadicField) = 0 function shift_right(a::QadicFieldElem, n::Int) diff --git a/src/gaussiannumbers/QQi.jl b/src/gaussiannumbers/QQi.jl index 46e3b6543a..07ca8c1fb1 100644 --- a/src/gaussiannumbers/QQi.jl +++ b/src/gaussiannumbers/QQi.jl @@ -384,10 +384,6 @@ end # ############################################################################### -function is_unit(a::QQiFieldElem) - return !iszero(a) -end - function inv!(z::QQiFieldElem, a::QQiFieldElem) d = abs2(a.num) mul!(z.num.x, a.num.x, a.den) diff --git a/test/flint/fmpz_mod-test.jl b/test/flint/fmpz_mod-test.jl index ff4bea8359..e1c81c8df3 100644 --- a/test/flint/fmpz_mod-test.jl +++ b/test/flint/fmpz_mod-test.jl @@ -89,6 +89,8 @@ end @test !is_unit(R()) @test is_unit(R(3)) + @test is_nilpotent(R()) + @test !is_nilpotent(R(3)) @test deepcopy(R(3)) == R(3) @@ -103,6 +105,7 @@ end @test modulus(S) == UInt(1) @test is_unit(S()) + @test is_nilpotent(S()) @test characteristic(R) == 13 @@ -128,6 +131,10 @@ end @test_throws Exception R6(R22(1)) @test_throws Exception R2(R3(1)) @test_throws Exception R3(R2(1)) + + ZZmodZZ720,_ = residue_ring(ZZ,ZZ(720)) + @test is_nilpotent(ZZmodZZ720(30)) + @test count(is_nilpotent, ZZmodZZ720) == 24 # 720/(2*3*5) end @testset "ZZModRingElem.unary_ops" begin diff --git a/test/flint/nmod-test.jl b/test/flint/nmod-test.jl index c92702ba10..1759a5d266 100644 --- a/test/flint/nmod-test.jl +++ b/test/flint/nmod-test.jl @@ -129,6 +129,16 @@ end @test_throws Exception R6(R2(1)) @test_throws Exception R2(R3(1)) @test_throws Exception R3(R2(1)) + + ZZmod720,_ = residue_ring(ZZ, 720) + @test is_nilpotent(ZZmod720(30)) + @test count(is_nilpotent, ZZmod720) == 24 # 720/(2*3*5) + + # 64-bit overflow test: **ASSUMES** Int is 64 bits + rr = 4*3^20 + mm = 3*rr + R_overflow,_ = residue_ring(ZZ, mm) + @test is_nilpotent(R_overflow(rr)) end @testset "zzModRingElem.unary_ops" begin