diff --git a/src/Fields.jl b/src/Fields.jl index 4df6c4043..e9762442d 100644 --- a/src/Fields.jl +++ b/src/Fields.jl @@ -6,6 +6,8 @@ is_domain_type(::Type{T}) where {T <: FieldElem} = true +is_euclidean_type(::Type{T}) where {T <: FieldElem} = true + is_zero_divisor(a::T) where T <: FieldElem = is_zero(a) is_unit(a::FieldElem) = !iszero(a) diff --git a/src/Poly.jl b/src/Poly.jl index a612c17f7..f519f0058 100644 --- a/src/Poly.jl +++ b/src/Poly.jl @@ -16,13 +16,12 @@ coefficient_ring(R::PolyRing) = base_ring(R) dense_poly_type(::Type{T}) where T<:RingElement = Generic.Poly{T} -function is_domain_type(::Type{T}) where {S <: RingElement, T <: PolyRingElem{S}} - return is_domain_type(S) -end +is_exact_type(::Type{<:PolyRingElem{T}}) where {T <: RingElement} = is_exact_type(T) -function is_exact_type(a::Type{T}) where {S <: RingElement, T <: PolyRingElem{S}} - return is_exact_type(S) -end +is_domain_type(::Type{<:PolyRingElem{T}}) where {T <: RingElement} = is_domain_type(T) + +is_euclidean_type(::Type{<:PolyRingElem{T}}) where {T <: RingElem} = T <: FieldElem +# TODO: what about polynomials over `Rational{BigInt}`? @doc raw""" var(a::PolyRing) diff --git a/src/Rings.jl b/src/Rings.jl index 34992587d..cdf3c5059 100644 --- a/src/Rings.jl +++ b/src/Rings.jl @@ -95,12 +95,41 @@ end # Type can only represent elements of an exact ring # true unless explicitly specified +# +# implementors should only implement this trait for RingElem subtypes, but for +# convenience we support calling this also on Ring subtypes as well as Ring +# and RingElem instances is_exact_type(R::Type{T}) where T <: RingElem = true -# Type can only represent elements of domains +is_exact_type(x) = is_exact_type(typeof(x)) +is_exact_type(x::Type{<:Ring}) = is_exact_type(elem_type(x)) +is_exact_type(T::DataType) = throw(MethodError(is_exact_type, (T,))) + +# Type can only represent elements of domains, i.e. without zero divisors # false unless explicitly specified +# +# implementors should only implement this trait for RingElem subtypes, but for +# convenience we support calling this also on Ring subtypes as well as Ring +# and RingElem instances is_domain_type(R::Type{T}) where T <: RingElem = false +is_domain_type(x) = is_domain_type(typeof(x)) +is_domain_type(x::Type{<:Ring}) = is_domain_type(elem_type(x)) +is_domain_type(T::DataType) = throw(MethodError(is_domain_type, (T,))) + +# Type can only represent elements of euclidean rings (which do not need to be domains) +# false unless explicitly specified +# +# implementors should only implement this trait for RingElem subtypes, but for +# convenience we support calling this also on Ring subtypes as well as Ring +# and RingElem instances +is_euclidean_type(R::Type{T}) where T <: RingElem = false + +is_euclidean_type(x) = is_euclidean_type(typeof(x)) +is_euclidean_type(x::Type{<:Ring}) = is_euclidean_type(elem_type(x)) +is_euclidean_type(T::DataType) = throw(MethodError(is_euclidean_type, (T,))) + + ############################################################################### # # Exponential function for generic rings