/// <summary>
        /// Gets the least common multiple of two elements in a <see cref="IEuclideanDomain{T, TFirst, TSecond}"/> via Euclid's algorithm. The LCDM is defined as:
        /// <code>
        ///     r.Mult(r.Gcd(x,y), r.Lcm(x,y)) == r.Mult(x,y)
        /// </code>
        /// </summary>
        /// <typeparam name="T">The type of the carrier set.</typeparam>
        /// <typeparam name="TFirst">The type of the first grouplike operation.</typeparam>
        /// <typeparam name="TSecond">The type of the second groupike operation.</typeparam>
        /// <param name="r">The ringlike structure.</param>
        /// <param name="x">The first element.</param>
        /// <param name="y">The second element.</param>
        /// <exception cref="DivideByZeroException">If <paramref name="x"/> or <paramref name="y"/> is zero.</exception>
        public static T Lcm <T, TFirst, TSecond>(this IEuclideanDomain <T, TFirst, TSecond> r, T x, T y)
            where TFirst : ICommutativeGroup <T>
            where TSecond : IMonoid <T>, ICommutative <T>
        {
            if (r.IsZero(x) || r.IsZero(y))
            {
                throw new DivideByZeroException();
            }

            var gcd       = r.Gcd(x, y);
            var numerator = r.Mult(x, y);
            var ret       = r.EuclideanDivide(numerator, gcd).quotient;

            return(ret);
        }
        /// <summary>
        /// Gets the greatest common divisor of two elements in a <see cref="IEuclideanDomain{T, TFirst, TSecond}"/> via Euclid's algorithm. The GCD of two elements <c>X</c> and <c>Y</c> is the unique minimal principal ideal.
        /// </summary>
        /// <typeparam name="T">The type of the carrier set.</typeparam>
        /// <typeparam name="TFirst">The type of the first grouplike operation.</typeparam>
        /// <typeparam name="TSecond">The type of the second groupike operation.</typeparam>
        /// <param name="r">The ringlike structure.</param>
        /// <param name="x">The first element.</param>
        /// <param name="y">The second element.</param>
        public static T Gcd <T, TFirst, TSecond>(this IEuclideanDomain <T, TFirst, TSecond> r, T x, T y)
            where TFirst : ICommutativeGroup <T>
            where TSecond : IMonoid <T>, ICommutative <T>
        {
            if (r.IsZero(x) || r.IsZero(y))
            {
                return(r.Zero <T, TFirst>());
            }

            while (!r.IsZero(y))
            {
                var t = y;
                y = r.EuclideanDivide(x, y).remainder;
                x = t;
            }

            return(x);
        }
 /// <summary>
 /// Performs the modulus-operation on two elements, returning the remainder of <see cref="IEuclideanDomain{T, TFirst, TSecond}.EuclideanDivide(T, T)"/>.
 /// </summary>
 /// <typeparam name="T">The type of the carrier set.</typeparam>
 /// <typeparam name="TFirst">The type of the first grouplike operation.</typeparam>
 /// <typeparam name="TSecond">The type of the second groupike operation.</typeparam>
 /// <param name="r">The ringlike structure.</param>
 /// <param name="x">The first element.</param>
 /// <param name="y">The second element.</param>
 public static T Mod <T, TFirst, TSecond>(this IEuclideanDomain <T, TFirst, TSecond> r, T x, T y)
     where TFirst : ICommutativeGroup <T>
     where TSecond : IMonoid <T>, ICommutative <T>
 => r.EuclideanDivide(x, y).remainder;