monoid_concept.h

Back to Algebra

pastel/sys/algebra/

// Description: Monoid concept
// Documentation: algebra.txt

#ifndef PASTELSYS_MONOID_CONCEPT_H
#define PASTELSYS_MONOID_CONCEPT_H

#include "pastel/sys/algebra/semigroup_concept.h"

#include "pastel/sys/algebra/native_monoid.h"
#include "pastel/sys/ensure.h"

namespace Pastel
{

    //! An additive monoid.
    /*!
   A monoid (X, +, 0), where 0 in X, is a semi-group (X, +), 
   such that there exist 0 in X such that 
       
           x + 0 = x = 0 + x, for all x in X.
   */
    struct Additive_Monoid_Concept
    : Refines<Additive_SemiGroup_Concept>
    {
        template <typename Type>
        auto requires_(Type&& t) -> decltype
        (
            conceptCheck(
                // Returns whether t == 0.
                Concept::convertsTo<bool>(zero(t))
            )
        );
    };

    //! A multiplicative monoid.
    /*!
   A monoid (X, *, 1), where 1 in X, is a semi-group (X, *), 
   such that there exist 1 in X such that 
       
           x * 1 = x = 1 * x, for all x in X.
   */
    struct Multiplicative_Monoid_Concept
    : Refines<Multiplicative_SemiGroup_Concept>
    {
        template <typename Type>
        auto requires_(Type&& t) -> decltype
        (
            conceptCheck(
                // Returns whether t == 1.
                Concept::convertsTo<bool>(one(t)),
                //! Returns the power t^p, for p in NN^{>= 0}.
                Concept::convertsTo<Type>(pow(t, (integer)0))
            )
        );
    };

}

namespace Pastel
{

    //! Computes x^p, for p in NN^{>= 0}.
    /*!
   The notation x^p means to multiply x with itself p times.
   */
    template <typename Multiplicative_Monoid>
    Multiplicative_Monoid monoidPower(
        Multiplicative_Monoid x,
        integer p)
    {
        ENSURE_OP(p, >=, 0);

        if (p == 0)
        {
            return 1;
        }

        return semiGroupPower(std::move(x), p);
    }

}

#endif