Overloading isunit from Nemo ring/field

Hi everybody !
My first attempt was quite successful !
I wanted to check experimentally that Z/nZ is a field if and only if n is a prime number. This is easy to prove but it was just an opportunity to use the Nemo residue fields.
So I wrote :

using Nemo

#vérification que Z/pZ corps ssi p premier
function test(n)
    R = ResidueRing( ZZ , n)
    K=[R(i) for i in 0:n-1]
    return all((isunit(x)||iszero(x) for x in K))
end

println([n for n in 2:20 if test(n)])

which gives the desired result…
But the story doesn’t end here. I’m using now Nemo residue rings to study products of such rings.
Everything works more or less and I decided to redefine isunit for a couple given that a couple has inverse if and only if every coordinate has one according multiplication law in product rings. So I wrote a lot of things working correctly :

#http://nemocas.github.io/Nemo.jl/v0.6/types/#the-abstract-type-hierarchy-in-nemo
using Nemo
R5 = ResidueRing( ZZ , 5)
R7= ResidueRing( ZZ , 7)
struct Z_sur_5ZxZ_sur_7Z <:RingElem
   c::Tuple{nmod, nmod}
end
const Z57=Z_sur_5ZxZ_sur_7Z #alias
Base.show(io::IO, C::Z57) = print(io,C.c)
couple(x::Int64,y::Int64)=Z57((R5(x),R7(y)))
println(couple(12,13))
zero(Z57)=couple(0,0) #neutre de l'addition
println(zero(Z57))
println(couple(5,7))
one(Z57)=couple(1,1)
println(one(Z57))
Base.:(==)(C1::Z57,C2::Z57)=C1.c==C2.c
iszero(C::Z57)=C==zero(Z57)
println(iszero(couple(5,7)))
Base.:+(C1::Z57,C2::Z57)=Z57((C1.c[1]+C2.c[1],C1.c[2]+C2.c[2]))
println(zero(Z57)+one(Z57))
Base.:*(C1::Z57,C2::Z57)=Z57((C1.c[1]*C2.c[1],C1.c[2]*C2.c[2]))
println(zero(Z57)*one(Z57))
Base.:*(n::Int64,C::Z57)=Z57((n*C.c[1],n*C.c[2]))
println(5one(Z57))
Base.:^(C::Z57,n::Int64) = Z57((C.c[1]^n,C.c[2]^n))
println(one(Z57)^3)

But now if I want to define isunit for my couples :
it is logical to write

isunit(C::Z57)=isunit(C.c[1])&&isunit(C.c[2])

which is accepted by the compiler without any error.
Now if you want to test with the line :

println(isunit(one(Z57)))

At execution time you receive the error :

ERROR: LoadError: MethodError: no method matching isunit(::nmod)

This error is more or less clear but contradicts the correct execution of first program assuming method matching isunit(::nmod)
I would be glad if somebody can explain to me what happens and why.
Thank you !
Gilles

you want to extend it instead:

Nemo.isunit(...

also I think this is what you wanted? you defined:

but what you wanted is one(::Type{Z57})?

Thank you, what you propose works quite well but I still don’t understand the error message because in the right part of the assignation isunit can only refer to the Nemo definition given the type of the argument (nmod) ???

Yes actually I want to define the multiplying neutral of couples (elements whose type is Z57). It’s not what I did ? I got what I wanted, my ‘one’ works as it should, but I have the feeling that I don’t use the derivation ```
<:RingElem

in my struct definition...

I thought a little more and I understand now. I redefine isunit so the Nemo.isunit is forgotten even for elements of nmod types. In the first case it was called by default.
Subtle but logical.
No need to explain. But I would appreciate if you can develop the zero is it the same mistake ?

Thank you again jiling for your help.
I thought and searched a lot by myself after your remark.
Everything is clear now. No need to answer any of my previous questions.
This topic is closed

1 Like