@@ -439,3 +439,45 @@ function _number_of_direct_product_factors end
439439Return the homomorphism from the domain `D` into the codomain `C` defined by the data.
440440"""
441441function hom end
442+
443+ # ##############################################################################
444+ #
445+ #
446+ #
447+ # ##############################################################################
448+
449+ # Calling `_implements(T, f)` checks whether a "sensible" method for the unary
450+ # function `f` is implemented for inputs of type `T`. The argument order is
451+ # meant to be similar to e.g. `isa`, and thus indicates `T implements f`.
452+ #
453+ # For example, `_implements(MyRingElem, is_unit)` should return true if
454+ # invoking `is_unit` on elements of type `MyRingElem` is supported.
455+ #
456+ # The generic fallback uses `hasmethod`. However, this may return `true` in
457+ # cases where it shouldn't, as we often provide generic methods for that rely
458+ # on other methods being implemented -- either for the same type, or for types
459+ # derived from it. For example the `is_nilpotent(::PolyElem{T})` method needs
460+ # `is_nilpotent(::T)` in order to work.
461+ #
462+ # To reflect this, additional `_implements` methods need to be provided.
463+ # We currently do this for at least the following functions:
464+ # - factor
465+ # - is_irreducible
466+ # - is_nilpotent
467+ # - is_squarefree
468+ # - is_unit
469+ # - is_zero_divisor
470+ #
471+ _implements (:: Type{T} , f:: Any ) where {T} = hasmethod (f, Tuple{T})
472+
473+ # helper for `_implements` which checks if `f` has a method explicitly for
474+ # a concrete type `T` (i.e. not a generic method that can be specialized to `T`
475+ # but really one that is implement for `T` and `T` only).
476+ function _implements_directly (:: Type{T} , f:: Any ) where {T}
477+ isconcretetype (T) || return false # TODO : drop this?
478+ meth = methods (f, Tuple{T})
479+ # TODO : deal with type parameters: if `T` is `FreeAssociativeAlgebraElem{ZZRingElem}`
480+ # and `f` has a method for `FreeAssociativeAlgebraElem` then we should still consider
481+ # this a match.
482+ return any (m -> m. sig == Tuple{typeof (f), T}, meth)
483+ end
0 commit comments